Help with managing dependencies

I have a Rust application running as a service and am trying to clean up some unused dependencies. I removed the crate from the Cargo.toml file that referenced it, and now I want to ensure that the crate is fully uninstalled from the system.

For some reason, running cargo install --list does not give me a list of all installed crates and their versions, it just outputs nothing. I'm guessing the reason for this is that as I was building the application, I would add dependencies directly to the Cargo.toml files for binaries/libraries that needed them, and did not directly run cargo install <crate>.

If I go into $HOME/.cargo/registry/src/index.crates.io-.../ I see a directory for the installed crate that I wish to get rid of. Is this something that just needs to be handled manually, or is there some cargo command like clean that can remove specific crates from the registry?

$HOME/.cargo/registry/src is just a cache for crate sources. The compiled crates end up in target/. cargo install --list shows installed executables. There is no global installation for libraries. Only local builds in target/.

Okay, am I safe to just delete the directory in $HOME/.cargo/registry/src for the dependency I removed? I am trying to get rid of a found security vulnerability that says the offending file is the Cargo.lock for the crate within $HOME/.cargo/registry/src because it specifies one of its dependencies as an out of date version with a known vulnerability.

Why do you want to get rid of the directory in $HOME/.cargo/registry/src? Just having it on your computer isn't a liability, and its presence there does not imply that it's used by your code.

I understand that, but our vulnerability scan marks the file as a vulnerability due to the reference of the old version.

Garbage collection of the Cargo cache is currently an unstable feature. If you want to use it, you'll either need to install nightly (even if it's just for this feature; you don't also have to use nightly for your builds), or do your own cache expiry.

Removing crate-level directories from the cargo cache is fine; it won't break anything. It's pointless for most users, since unused code in the cache is completely unused, but if it satisfies your chief compliance officer, vaya con dios.

If you want something easy but inefficient, you could also just delete the cache directory entirely and let everything be downloaded again.

When does the downloading of cache files take place? Is it just on new builds?

I'm hoping that it is just on a new build, as there are a couple dependencies that are being used whose lock files reference other vulnerable crate versions as dev dependencies, but the vulnerability inspector is dumb and marks any vulnerable version referenced in the cache as a vulnerability. So I was going to just remove the cache directories for the crates that are causing issues, but if they are redownloaded at some arbitrary time then that may not be a solution.

What vulnerability scan program? All vulnerability scanners for Rust that I know of don't look at ~/.cargo/registry at all, but rather look at the dependencies of a specific project by for example running cargo metadata on the cargo workspace of your project. ~/.cargo/registry is just a cache and is likely to contain crates that your current project doesn't use as well as miss dependencies of your current project that are only used on other OSes, which cargo metadata doee include.

2 Likes

Whenever cargo needs to build the crate in question.

Amazon Inspector. It doesn't seem to be using cargo metadata because I removed a dependency from the workspace and rebuilt the application, but Inspector was still identifying the removed dependency as a vulnerability (specifically showing the cached Cargo.lock as the offending file). Running cargo metadata on the workspace has no mention of the removed dependency now, so Inspector must be scanning thru the cache files for mentions of vulnerable versions.

I don't believe the Cargo docs make any specific promises about this. A lot of it is vibes and good intentions, around the idea that Cargo is intended to help the end developer make effective use of crates.io and other repositories, as well as of their own disk space and other resources, when building Rust software. The actual advice, in so far as I have any, is that you & your stakeholders should figure out how to either get Cargo's cache exempted from your vulnerability scanning process for being a source of meaningless false positives, or, if that's not feasible, empty the Cargo cache after you're done building software.

However, in practice Cargo will not download a crate until it intends to actually build that crate as part of some project. When you build your-crate, you can expect:

  • The dependencies (and build-dependencies) of your-crate to be downloaded and stored in the cache, and
  • The dependencies (and build-dependencies) of those dependencies, recursively, to likewise be downloaded.

Dependencies available locally might not be copied to the cache. dev-dependencies of your dependencies (and… you get the idea) won't generally be downloaded when building your-crate, because they are not used by your-crate in any way. They are only needed when running tests, examples, and benchmarks of the crate they are declared as dev-dependencies on.

3 Likes