Yes, like any dependency. A dotnet tool is a NuGet package that installs an executable, so installing one means running someone else's code with your permissions. Reduce risk by using local tools with a committed manifest, pinning versions, restoring from trusted sources, and avoiding shared install locations.
What a tool is
The dotnet tool install command takes a NuGet package ID and installs it in one of three ways, per Microsoft's documentation.
| Install type | Where it lives | Scope |
|---|---|---|
| Global | Under your user profile, in a dot dotnet tools folder | All your projects |
| Tool path | A directory you choose | Whatever that path exposes |
| Local | NuGet global directory, listed in a manifest | The directory with the manifest and below |
Why local tools are easier to govern
A local tool is recorded in a file at .config/dotnet-tools.json with the exact version. That file is committed with the code, so every developer and the CI agent restore the same tools.
{
"version": 1,
"isRoot": true,
"tools": {
"dotnetsay": {
"version": "2.1.3",
"commands": ["dotnetsay"]
}
}
}
Other developers run one command, dotnet tool restore, to install everything the manifest lists. Updates then happen through pull requests you can review.
Documented cautions
- Make sure a directory used with the tool path option is secure. Tools there can be executed directly, and an untrusted or shared path may introduce risk.
- The CLI walks up the directory tree looking for a manifest. Do not run tool commands from the Downloads folder or any shared location, because it may find a manifest you did not expect. Run from a trusted, project specific folder.
- Starting with the .NET 10 SDK, a manifest is created automatically if none is found, which Microsoft flags as a possible breaking change. You can opt out with the create manifest if needed option set to false.
- When you pass additional sources, feeds are accessed in parallel, and the fastest feed wins if the same package and version exist in several. That is the same ambiguity source mapping tries to remove for libraries.
- By default the latest stable version is installed, so state a version when you install.
A practical policy
- Prefer local tools over global ones for anything a project needs.
- Commit dotnet-tools.json and review changes to it.
- Pin versions. Use the at sign form or the version option when installing.
- Keep tools off the global path on build agents, and start agents clean.
- Add tool package IDs to your source mapping.
- Include tools in your dependency inventory and scanning, because they are packages too.
Try it yourself
Click through it at your own pace, or open it full screen. Tools do not always appear in a project's package list, so check that your inventory includes them.
Safeguard's SBOM and dependency scanning can cover the packages in your repositories, and a free scan lets you see what is detected.
Quick check
Where does a local tool manifest live?
In a file named dotnet-tools.json inside a .config folder at or above the directory where you run the tool.
How do teammates install the same tools?
They run dotnet tool restore, which installs the versions recorded in the committed manifest.
Sources
Last reviewed: 19 October 2026.