__ __ __
___/ /___ ___ / /________ _______/ /_
/ _ / __ \/ _ \/ __/ ___/ / / / ___/ __/
/ __/ /_/ / __/ /_/ / / /_/ (__ ) /_
\__,_/\____/ .___/\__/_/ \__,_/____/\__/
/_/
deptrust is a CLI that checks package versions for known vulnerabilities across npm, PyPI, crates.io, Go modules, RubyGems, NuGet, Maven, Packagist, pub.dev, CocoaPods, Hex.pm, Hackage, GitHub Actions, and more.
It runs locally as a CLI and as an MCP server. It calls public package registry and OSV APIs directly; there is no hosted deptrust service to trust or configure.
This tool was born out of the frustration that is AI agents constantly using old versions.
Supported ecosystems:
- npm, including scoped packages like
@clidey/ux - PyPI
- Cargo / crates.io
- Go modules
- RubyGems
- NuGet
- Maven, using
groupId:artifactIdpackage names - Packagist / Composer, using
vendor/packagepackage names - pub.dev
- CocoaPods
- Hex.pm
- Hackage
- GitHub Actions, using
owner/repopackage names and tags, branch refs, or commit SHAs as versions
deptrust currently reports known vulnerabilities and gives a simple recommendation:
| Highest known severity | Recommendation |
|---|---|
| critical | block |
| high | block |
| medium / unknown | review |
| low | allow |
| none found | allow |
allow means no blocking known vulnerability was found in the public data sources. It does not prove that a package is safe.
deptrust also emits risk signals that are not CVEs. For example, a version published in the last 72 hours is marked for review so an agent does not blindly install a brand-new release.
Advisory providers are queried in parallel:
- OSV
- GitHub Advisory Database, including reviewed advisories and malware advisories
Provider coverage varies by ecosystem. If deptrust can resolve registry metadata but no configured vulnerability provider supports that ecosystem, it returns unknown instead of treating the package as safe.
Provider coverage:
| Ecosystem | Registry metadata | OSV | GitHub Advisory DB |
|---|---|---|---|
| npm | yes | yes | yes |
| PyPI | yes | yes | yes |
| Cargo / crates.io | yes | yes | yes |
| Go modules | yes | yes | yes |
| RubyGems | yes | yes | yes |
| NuGet | yes | yes | yes |
| Maven | yes | yes | yes |
| Packagist / Composer | yes | yes | yes |
| pub.dev | yes | yes | yes |
| CocoaPods | yes | no | yes |
| Hex.pm | yes | yes | yes |
| Hackage | yes | yes | no |
| GitHub Actions | yes | yes | yes |
The JSON output includes advisory coverage fields:
checked_providers: vulnerability providers deptrust actually queriedskipped_providers: configured providers skipped because the ecosystem is unsupportedadvisory_coverage:full,partial,none, orerroradvisory_coverage_reason: short explanation for the coverage valueregistry_verification:verifiedwhen registry metadata confirmed the version, orunverifiedwhen an exact-version check continued after a transient registry failureregistry_verification_reason: the registry error when verification was unavailable
An exact-version check still queries advisory providers when registry verification is temporarily unavailable. That result is always non-installable and never receives an allow recommendation. Checks for latest, unknown packages, and definitively nonexistent versions still require successful registry resolution.
HTTP requests retry 429, 502, 503, and 504 responses up to three total attempts. Retries use short exponential delays and honor Retry-After values up to two seconds; longer server-requested waits fail fast so the CLI does not hang. Exhausted advisory retries make the result incomplete and prevent an allow recommendation.
GitHub Advisory Database and GitHub Actions API requests can use a short-lived, least-privilege GitHub App token. In CI, pass it through DEPTRUST_GITHUB_TOKEN:
DEPTRUST_GITHUB_TOKEN="$GITHUB_APP_TOKEN" deptrust check npm lodash 4.17.20The credential precedence is DEPTRUST_GITHUB_TOKEN, GITHUB_TOKEN, then GH_TOKEN. For local use, the optional GitHub CLI fallback is enabled explicitly with DEPTRUST_GITHUB_AUTH=gh deptrust check ...; it runs gh auth token without prompting. If no credential is available, DepTrust continues unauthenticated. A GitHub API rate-limit or permission failure produces unknown with diagnostics and is never treated as an OSV-only success.
DepTrust never stores, bundles, caches, logs, telemeters, or emits GitHub tokens. Authentication headers are sent only to https://api.github.com.
Check an exact version:
deptrust check npm lodash 4.17.20Example normal response:
npm lodash@4.17.20: 2 known vulnerabilities found
recommendation: block
risk_score: 80
Check the latest version:
deptrust check pypi requests latestReturn JSON:
deptrust check --json cargo serde latestCheck a Go module:
deptrust check go golang.org/x/crypto latestCheck RubyGems, NuGet, or Maven:
deptrust check rubygems rails latest
deptrust check nuget Newtonsoft.Json latest
deptrust check maven org.apache.logging.log4j:log4j-core latestCheck Packagist, pub.dev, CocoaPods, Hex.pm, Hackage, or GitHub Actions:
deptrust check packagist monolog/monolog latest
deptrust check pub http latest
deptrust check cocoapods AFNetworking latest
deptrust check hex plug latest
deptrust check hackage aeson latest
deptrust check github-actions actions/checkout v7.0.0
deptrust check github-actions actions/checkout mainFor GitHub Actions, full commit SHAs are treated as pinned. Full semver tags such as v4.2.2 are accepted without an extra pinning signal. Major-only tags such as v4 and branch refs such as main are valid refs, but deptrust adds a review signal because they can move.
Example JSON response:
{
"ecosystem": "npm",
"package": "lodash",
"version": "4.17.20",
"latest_version": "4.17.21",
"known_vulnerabilities_found": true,
"safe_to_use": false,
"should_install": false,
"risk_score": 80,
"recommendation": "block",
"classification": "vulnerable",
"reason": "Found 2 known vulnerability records.",
"next_action": "do_not_install; use suggest_safe_version or compare_versions to choose a safer version",
"summary": "lodash 4.17.20 has 2 known vulnerabilities, including high severity. Block this exact version and prefer a fixed release.",
"signals": [],
"checked_providers": [
"OSV",
"GitHub Advisory DB"
],
"skipped_providers": [],
"advisory_coverage": "full",
"advisory_coverage_reason": "all configured vulnerability providers were checked",
"registry_verification": "verified",
"vulnerabilities": [
{
"id": "GHSA-35jh-r3h4-6jhm",
"aliases": [
"CVE-2021-23337"
],
"cve_ids": [
"CVE-2021-23337"
],
"ghsa_ids": [
"GHSA-35jh-r3h4-6jhm"
],
"summary": "Command Injection in lodash",
"severity": "high",
"source": "OSV",
"advisory_url": "https://github.com/advisories/GHSA-35jh-r3h4-6jhm",
"affected_ranges": [
"SEMVER: introduced 0, fixed 4.17.21"
],
"fixed_versions": [
"4.17.21"
],
"references": [
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-35jh-r3h4-6jhm"
}
]
}
],
"provider_errors": []
}Suggest the latest version only when no known vulnerabilities are found:
deptrust suggest npm lodashIf the latest version is not allowed, suggest checks older known versions and returns the newest version with an allow recommendation.
When advisories include fixed versions, suggest checks those provider-reported fixed versions first before walking back through the registry version list.
Compare two versions:
deptrust compare npm lodash 4.17.20 4.17.21Example compare response:
lodash 4.17.20 -> 4.17.21 improves risk: score 80 to 0.
recommendation: allow
next_action: upgrade_to_target
Show the installed version:
deptrust versionThe easiest install path is npx or pnpx:
npx @clidey/deptrust install
pnpx @clidey/deptrust@latest installThe default installer is guided. It installs the binary, asks which agent integrations to configure, prints the user-level destinations before changing anything, and asks for confirmation. The guided installer defaults to enabling MCP, the skill fallback, and dependency safety hooks for Codex and Claude Code. Add --yes to install without prompts or enabling new integrations, or pass explicit integration flags. Existing registrations are refreshed during installation.
Rerunning the installer is safe. It silently leaves unchanged MCP, skill, and hook configuration alone. If an integration points at an old deptrust binary or its managed configuration has changed, the installer updates it automatically; users do not need to manually remove and re-add MCP servers. Customized skills are backed up before replacement.
To upgrade the binary and refresh your existing agent setup, run one command:
npx @clidey/deptrust@latest upgradeNo setup questions or integration flags are needed. Existing local MCP and hook
registrations are updated in place, installed skills are refreshed with backups,
and integrations you haven't enabled stay disabled. The installer verifies the
downloaded binary's version before replacing the old executable at the same
location. If you originally chose a custom --bin-dir, pass that same directory
when upgrading. Updating the npm wrapper alone does not update the Go binary;
the command above handles both. Restart active agent sessions to reload any
already-running MCP server.
The npm installer and scripts/install.sh automatically refresh integrations
you already enabled. They do not ask again or enable new integrations. If an
automatic refresh fails, the binary installation still succeeds and prints
the exact setup --refresh repair command; existing configuration errors are
reported instead of silently discarded.
To remove the user-level binary, skill, and MCP entries:
npx @clidey/deptrust uninstall
pnpx @clidey/deptrust@latest uninstallHomebrew users can install from the Clidey tap:
brew install clidey/tap/deptrustOr tap first, then install and upgrade as usual:
brew tap clidey/tap
brew install deptrust
brew upgrade deptrustHomebrew prints a reminder after installation. To run the guided Codex and Claude Code setup using the Homebrew binary itself (MCP registrations and dependency safety hooks):
deptrust setupThe guided setup asks before enabling MCP and dependency safety hooks. It leaves registrations that already use the current binary alone, and reconciles existing DepTrust registrations that point to an older npm, Homebrew, or source-install path.
Homebrew setup uses the stable opt/deptrust/bin/deptrust path when available,
so subsequent brew upgrade deptrust runs do not need another guided setup. Existing
registrations that still contain a versioned Cellar path can be migrated once
with deptrust setup --refresh. This non-interactive command only refreshes
existing local user registrations; remote MCP servers and custom wrappers are
left alone. It preserves MCP environment settings, hook options, and unrelated
configuration.
After upgrading through Homebrew, Go, Nix, a manual download, or another package
manager, deptrust setup --refresh also updates any existing package-check skill
from the binary itself. It needs neither npm nor a source checkout. Changed
skills are backed up in full before replacement; unchanged skills are left
alone. It never enables an absent skill. For a first-time skill installation,
run deptrust setup --skill explicitly.
Homebrew's isolated post-install environment cannot reliably access user agent
settings, so the formula prints the refresh command instead of attempting it
inside post-install. Direct go install, Nix profile updates, and manual binary
replacement also require running deptrust setup --refresh explicitly when you
want to refresh installed skill files or migrate registrations. No background
updater or automatic agent restart is installed.
Go users can install directly:
go install github.com/clidey/deptrust/cmd/deptrust@latestThe project provides optional Nix flake outputs for users who already use Nix. The flake wraps the prebuilt release binary.
# Run without installing
nix run github:clidey/deptrust
# Install into your profile
nix profile install github:clidey/deptrustThe normal release workflow generates the Nix
hashes from the same archives it publishes, evaluates the flake before
publishing, then builds and runs it against the published assets before updating
the default branch. github:clidey/deptrust may briefly lag while that workflow
is running. Release tags point to the source commit from before the generated
flake update and may still reference the previous binary; pin a commit whose
flake.nix contains the version you need when reproducibility matters.
For reproducible development environments, use Devbox:
# Install Devbox first (if not already installed)
curl -fsSL https://get.jetify.dev/devbox | bash
# Initialize the environment
devbox shell
# Build the project
devbox run builddevbox.json constrains the toolchain version and the committed devbox.lock
pins the exact package versions and nixpkgs revisions. Run devbox update when
you intentionally want to refresh those pins.
Or install Devbox via Homebrew:
brew install jetify-com/devbox/devboxTo install deptrust and register everything the installer can configure without the guided prompts:
npx @clidey/deptrust install --all
pnpx @clidey/deptrust@latest install --all--all installs the binary, registers Codex MCP when the codex CLI is available, installs the Codex skill fallback, registers Claude Code MCP when the claude CLI is available, and installs the Codex and Claude Code dependency safety hooks.
The hooks are PreToolUse hooks. They check package install commands before they run, and they also check GitHub Actions added to workflow files through agent file-edit tools. A hook blocks the tool call when deptrust returns review, block, or unknown. The installer writes user-level hook config only: ~/.codex/hooks.json for Codex and ~/.claude/settings.json for Claude Code.
Install inspection accepts a deliberately simple format: one standalone command
with literal package names and versions, such as pnpm add @scope/pkg@1.2.3,
pip install requests==2.32.3, or
dotnet add package Example --version 1.0.0. Multiple literal packages are
supported where the package manager allows them. An omitted version means
latest. The hook does not attempt to interpret shell programs.
If an install-like command contains redirects (including 2>&1), command
chaining, quotes, variables, substitutions, ranges, local paths, wrappers, or
unsupported options, the hook denies that attempt before package lookups and asks
the agent to retry with simpler input. It never checks a partial package list and
treats that as complete. Directory changes should be separate tool calls. Only
the version options shown above (--version, or -v for Ruby tools) and Maven's
dependency:get -Dartifact=group:artifact:version form are accepted as options;
other necessary options and source settings require an explicit source-aware
check, not silently removing their meaning from the install.
This is inspection of recognized explicit package installs, not a shell security boundary or a complete detector of arbitrary scripts. Install commands without explicit package names do not audit the manifest or lockfile. Unknown tools, aliases and dynamically constructed command names are outside this hook's coverage; use explicit checks for their dependencies.
When the gh CLI is available, guided setup also offers to use its existing local login for hook checks. This writes only DEPTRUST_GITHUB_AUTH=gh, never a GitHub token, so hook subprocesses can avoid unauthenticated GitHub API rate limits.
Use narrower installs when preferred:
npx @clidey/deptrust install --codex-mcp
npx @clidey/deptrust install --claude-code-mcp
npx @clidey/deptrust skills install
pnpx @clidey/deptrust@latest install --codex-mcp
pnpx @clidey/deptrust@latest install --claude-code-mcp
pnpx @clidey/deptrust@latest skills installAfter MCP setup, agents will automatically check packages before recommending updates or changes. The MCP server sends instructions to vet all dependency versions — including answering questions like "what can I update" or "which dependencies are safe to upgrade" — before providing recommendations.
If using deptrust in a non-MCP context, remind your agent:
Before listing, comparing, or recommending specific package versions, check them with deptrust. This includes answering "what can I update" — do not provide version recommendations until after checking for known vulnerabilities.
For CI, configure a short-lived least-privilege GitHub App token as DEPTRUST_GITHUB_TOKEN for the process running DepTrust. For local GitHub CLI authentication, use DEPTRUST_GITHUB_AUTH=gh deptrust check .... DepTrust never stores tokens.
If your client supports stdio MCP servers, configure it to run:
/absolute/path/to/deptrust mcpMany clients use this JSON shape:
{
"mcpServers": {
"deptrust": {
"command": "/absolute/path/to/deptrust",
"args": ["mcp"]
}
}
}For Codex, you can also add it with:
codex mcp add deptrust -- /absolute/path/to/deptrust mcpFor Claude Code:
claude mcp add --transport stdio deptrust -- /absolute/path/to/deptrust mcpOn initialize, the server returns MCP instructions telling the agent when to reach for these tools (before adding, bumping, or recommending a dependency, or when asked whether a version is safe to update). Clients that surface server instructions will apply this automatically, so the manual reminder above is optional rather than required.
Checks a package version and returns known vulnerabilities plus a recommendation.
{
"ecosystem": "npm",
"package": "lodash",
"version": "4.17.20"
}version may be omitted or set to latest. If an exact version does not exist, deptrust returns an error and suggests the latest explicit version.
MCP output is intentionally compact so agents can decide whether to install a dependency without pulling full advisory bodies into context. If the user asks to see full details, the agent can run the full_response_command.
Example compact MCP structured output:
{
"ecosystem": "npm",
"package": "vite",
"version": "7.0.0",
"latest_version": "8.0.16",
"known_vulnerabilities_found": true,
"safe_to_use": false,
"should_install": false,
"risk_score": 80,
"classification": "vulnerable",
"recommendation": "block",
"reason": "Found 7 known vulnerability records.",
"next_action": "do_not_install; use suggest_safe_version or compare_versions to choose a safer version",
"summary": "vite 7.0.0 has 7 known vulnerabilities, including high severity. Block this exact version and prefer a fixed release.",
"vulnerability_count": 7,
"vulnerability_counts": {
"critical": 0,
"high": 2,
"medium": 3,
"low": 2,
"unknown": 0
},
"highest_severity": "high",
"checked_providers": [
"OSV",
"GitHub Advisory DB"
],
"skipped_providers": [],
"advisory_coverage": "full",
"advisory_coverage_reason": "all configured vulnerability providers were checked",
"registry_verification": "verified",
"full_response_command": "deptrust check --json npm vite 7.0.0"
}The compact MCP response omits the vulnerability array, advisory details, and repeated references. Agents should use the counts, highest severity, provider coverage, recommendation, and next action by default. If the user asks for full advisory details, run the full_response_command.
When GitHub advisory access is rate-limited or unavailable, MCP returns unknown. The agent should proactively offer to configure a token and retry, skip or defer the version, or proceed only after the user explicitly accepts the unresolved GitHub coverage risk for that exact version. That exception must remain clearly labeled as user-accepted uncertainty; it must not be reported as allow or as proof that the version is safe.
Checks the latest version first. If latest is not allowed, checks provider-reported fixed versions first, then older known versions, and suggests the newest version with an allow recommendation.
{
"ecosystem": "npm",
"package": "lodash"
}Compares a current version and target version, including resolved and added vulnerabilities.
{
"ecosystem": "npm",
"package": "lodash",
"from_version": "4.17.20",
"to_version": "4.17.21"
}If you do not want MCP, install the bundled Codex skill:
npx @clidey/deptrust skills installThe skill tells Codex to call the deptrust CLI before installing, updating, or recommending npm, PyPI, Cargo, Go module, RubyGems, NuGet, Maven, Packagist, pub.dev, CocoaPods, Hex.pm, Hackage, and GitHub Actions packages.
If deptrust is not found:
export PATH="$HOME/.local/bin:$PATH"If an MCP client cannot start the server, find the full path:
which deptrustThen put that absolute path in the MCP config.
If a package check returns unknown, do not treat the package as safe. It means deptrust could not get a complete answer from an advisory provider or could not verify the exact version with its registry.
Configure GOPRIVATE through the environment or go env -w to identify private
Go module paths:
export GOPRIVATE='github.com/your-org/*,git.corp.example.com'
deptrust check go github.com/your-org/internal-lib v1.2.3DepTrust uses Go's comma-separated module-prefix glob semantics. Matching Go
modules skip all public registry and advisory requests and return unknown,
with registry verification unverified and advisory coverage none. Suggestions
and comparisons also skip these requests and cannot recommend a version.
This does not verify the module's existence, authenticate to its repository, or
scan its dependencies. Other ecosystems and nonmatching Go modules retain their
normal behavior.
A nonempty exported GOPRIVATE takes precedence. Otherwise DepTrust runs
go env GOPRIVATE to read the effective saved configuration, including GOENV
overrides and GOENV=off. This requires Go on PATH unless a nonempty GOPRIVATE
is exported. Failure to read the configuration stops before public requests.
Toolchain downloads and Go telemetry are disabled for this configuration read.
For MCP, configure the environment of the server process. GONOPROXY and GONOSUMDB do not override this privacy
policy. Configure patterns before checking private names: unmarked paths use
public services.
See the official Go private-module documentation for the underlying Go configuration and pattern semantics.
Select configuration explicitly before checking packages that might come from
custom feeds. These options apply to check, suggest, and compare:
deptrust check --json --project-dir /absolute/path/to/project npm @company/library 1.2.3
deptrust check --json --nuget-config /absolute/path/to/nuget.config nuget Company.Library 1.2.3For MCP, pass project_dir (npm) or nuget_config (NuGet) on each tool call.
Follow-up commands retain the selected configuration. No project directory is
implicitly taken from the MCP server's working directory. Without these options,
checks continue to use the public registries.
- npm: requires npm on PATH and reads its effective configuration in the
selected directory using
npm config get. Scope-specific registry mappings take precedence over the default registry. npm handles its normal project, user, global, and environment configuration. This does not infer privacy from a scope name orpackage.jsonpublishing restrictions. Private packages hosted on registry.npmjs.org cannot be distinguished by registry selection alone. - NuGet: reads the selected config file alone, like NuGet's explicit
--configfilemode; machine, user, and parent-directory settings are not merged in this explicit-file mode. Use a consolidated config containing package sources and mappings. Exact package IDs take precedence over prefixes, longer prefixes over shorter ones, and*is the default. Matching is case-insensitive. Disabled sources are excluded. Orderedadd,remove, andclearoperations are applied to source/disabled collections; source mappings support collection clears. Duplicate sections and unsupported mapping directives are rejected before network access.
Only an exclusive selection of the supported public source (npmjs.org or the
NuGet v3 public index) proceeds to public checks. Custom, mixed, or unmapped
sources return unknown with registry verification unverified and advisory
coverage none. They are not labeled private: a custom feed may also be public
or mirror public packages. Configuration errors stop the operation before public
requests. DepTrust does not fetch from custom feeds or expose their URLs or
credentials in results. This is source selection support, not authenticated
private-package assessment or a dependency-graph scan.
Official references: npm scope registry mappings, npm configuration, NuGet source mapping and precedence, NuGet configuration selection.
The same explicit --project-dir option (MCP: project_dir) supports Cargo and
Poetry projects:
deptrust check --json --project-dir /absolute/path/to/rust-project cargo internal-crate 1.2.3
deptrust check --json --project-dir /absolute/path/to/python-project pypi internal-package 1.2.3- Cargo: requires Cargo on PATH. Reads workspace dependency declarations with
cargo metadata --format-version 1 --no-deps --offline. Alternate registries, Git/path dependencies, workspace packages, aliases queried instead of actual crate names, and names not declared as workspace dependencies returnunknown. Use the actual crate name for renamed dependencies. Before permitting a public check, resolved sources are confirmed with offline, locked metadata so that local/Git patches cannot be mistaken for crates.io artifacts. This requires a current lockfile and cached metadata for the resolved graph; failures stop before public requests. This does not build code or fetch missing dependencies. It does not scan arbitrary transitive dependencies or authenticate to registries. - Poetry: uses a native Go TOML parser; Python is not required. Reads
pyproject.tomlwithout executing project code or invoking installation. Supports explicitsourceconstraints, dependency groups, optional dependencies, legacy dev-dependencies, and Poetry enrichment of PEP 621 dependencies. PyPI-bound dependencies can proceed; custom source constraints and direct Git/path/URL dependencies returnunknown. Unconstrained packages also returnunknownif custom primary/supplemental sources could supply them. Unused explicit sources do not affect other dependencies. Source constraints are not inherited by dependencies. Undeclared packages returnunknown; this does not scan a lockfile or resolve transitive dependencies. Deprecated Poetrydefault/secondarypriority settings are rejected rather than guessed.
Both options work for checks, suggestions, and comparisons, retain project selection in MCP follow-up commands, and skip public registry/advisory requests when source identity is unsupported or uncertain. Parser/tool errors stop before public requests. Calls without project targeting retain public-registry behavior.
Official references: Go environment configuration, Cargo metadata, Poetry package source constraints, Go TOML parser.
Select a resolved Bundler lockfile explicitly:
deptrust check --json --bundler-lock /absolute/path/to/Gemfile.lock rubygems internal_gem 1.2.3Use bundler_lock in MCP calls. The option works for checks, suggestions, and
comparisons; follow-up commands preserve it. It cannot be combined with
project_dir or nuget_config.
DepTrust uses the installed Ruby/Bundler LockfileParser to read resolved gem
sources. This follows the source recorded after Bundler resolves per-gem source:
options and source blocks. Only gems exclusively associated with the HTTPS
RubyGems.org source proceed to public checks. Custom sources, mixed remotes,
missing gems, and source uncertainty return unknown without public requests.
Git, path, and plugin source objects are not constructed. Their locked gem names
remain unsupported, while unrelated RubyGems.org gems can still be assessed.
The same gem name appearing in both public and unsupported sources returns unknown. Credential URLs never appear in results.
This inspects the selected artifact only. It does not evaluate Gemfile, verify
that the lockfile matches current Gemfile declarations, apply local source
configuration overrides, install gems, run plugins, or update the lockfile.
Keep the selected lockfile current before relying on its source assignments.
A newer version suggested from a public source is not proof of compatibility with
Gemfile constraints. Calls without this option retain public-registry behavior.
Ruby and Bundler must be installed on PATH; unavailable tooling or an unreadable
lockfile stops the operation before public requests. RUBYOPT startup options
are disabled for the parser subprocess.
Official references: Bundler per-gem sources and source blocks, resolved lockfile sources.
Hook source checks use an absolute hook cwd for npm configuration. Install
commands with explicit registry/index/configuration/directory overrides stop
before public requests because the hook cannot reliably reconstruct those
sources. Use the explicit source-aware CLI/MCP interface for those assessments.
Use --source-file /absolute/path/to/composer.json (MCP: source_file) to assess
repository declarations in the selected root artifact. Custom repositories that
can supply the package return unknown, including noncanonical repositories;
only and exclude wildcard filters are respected. Disabling Packagist also
returns unknown. A VCS/dist URL in composer.lock is not treated as proof that a
package came from Packagist. No Composer scripts or plugins run.
This is a selected-file assessment: it does not merge Composer's global config, environment overrides, or plugins. Use a configuration artifact representing the intended sources. It does not prove the freshness or provenance of installed packages. Source context options are mutually exclusive.
Official references: Composer repositories, repository priority and filters.
--source-file /absolute/path/to/pubspec.yaml or pubspec.lock (MCP:
source_file) reads declared or locked Dart sources natively. Hosted pub.dev
identities can proceed; custom hosted URLs, Git/path/SDK dependencies, workspace
inheritance, missing packages, and unsupported identities return unknown.
dependency_overrides in the selected pubspec take precedence. A custom
PUB_HOSTED_URL always prevents public checks, even without a selected file.
The selected artifact is not merged with pubspec_overrides.yaml or workspace
configuration; supply the intended artifact and do not treat this as freshness
verification. No Dart commands, downloads, or project code are executed.
Official references: Dart dependency sources, pub environment.
For Python, --source-file additionally accepts uv.lock, uv pyproject.toml,
Pipfile, Pipfile.lock, pip.conf, or pip.ini. uv index constraints and locked
registry identities, Pipenv index assignments, and selected pip global/install
index settings are read natively. Custom, direct, ambiguous, or undeclared
identities return unknown. Explicit uv indexes unused by a dependency do not
restrict that dependency. Marker alternatives are considered together.
Custom index/find-links/no-index environment settings for pip and uv prevent
public requests, even without a selected artifact. PIP_CONFIG_FILE is checked
when set. A selected pip file is not a reconstruction of pip's complete global,
user, virtualenv, and command-line configuration hierarchy. Selected lockfiles
are snapshots; project configuration overrides and freshness are not inferred.
No Python tools or build backends run. Unsupported configuration stops the check.
References: uv indexes, Pipenv indexes, pip configuration.
For npm ecosystem checks, --source-file accepts Yarn Classic .yarnrc, Yarn
Berry .yarnrc.yml, and pnpm pnpm-workspace.yaml/config.yaml. Registry and
scope mappings in the selected file determine whether public assessment applies.
Unknown/custom registry identities return unknown. Named pnpm registry routing
and URL-keyed registry declaration objects are unsupported and return unknown. Registry URL interpolation is not guessed.
This is a selected-file assessment, not a merge of all inherited package-manager
configuration, plugins, package overrides, aliases, or command-line options.
A selected .npmrc is parsed by npm itself as user configuration in its directory;
normal npm project/environment precedence still applies. Yarn Classic registry
lines support the documented simple quoted/unquoted form; other source overrides
need explicit context. A public npm scope is not evidence of privacy, and private
npmjs.org packages cannot be identified reliably from a scope name alone.
References: Yarn settings, pnpm settings, npm config.
Use --project-dir /absolute/path/to/project maven group:artifact 1.2.3 (MCP:
project_dir, ecosystem maven). The installed Maven/Gradle tool processes its
own effective configuration. A directory containing both POM and Gradle build
files is rejected instead of guessing which manager applies.
- Maven: requires Maven and a compatible JDK (
javac/jar). A temporary extension uses Maven's publicafterProjectsReadlifecycle callback after model inheritance, settings, and active profiles have been applied. Resolver's public mirror selector supplies the effective endpoint. The inspector aborts before build goals run. System-path and reactor-local identities remainunknown. - Gradle: requires installed Gradle. An init script uses public repository and
resolution APIs and runs a generated inspection task in the selected project's
task context. Metadata is resolved offline to detect local/project or module
substitutions. Requested/default project tasks are not scheduled by DepTrust.
Missing cached metadata, unresolved identities, and composite builds remain
unknown.
These are trusted-project integrations, not static parsers or sandboxes.
Maven model extensions and Gradle configuration/buildSrc/plugin code may execute;
build tools may write local caches. Both are invoked offline, using installed
executables rather than wrappers that might download a distribution. Prepare
required parent POMs, extensions, plugins, and metadata in advance. Select the
actual project/subproject directory whose declared direct dependency is being
checked. Arbitrary transitive queries and undeclared modules remain unknown.
Only exclusively Maven Central endpoints permit a public assessment. Custom,
mixed, Ivy/local, or uncertain source sets return unknown, including mixed
Gradle repositories where a content filter might exclude the private source for
this particular module. The implementation does not use internal filter APIs or
pretend it can prove that narrower routing. The context is the installed tool and
current environment (including MAVEN_ARGS/Gradle properties); flags supplied only
to a separate future invocation are not inferred. Hooks stop on explicit profile,
property, or settings overrides rather than losing that context.
A standalone Maven effective XML supplied via source_file still returns
unknown: one artifact alone cannot establish the full effective source set.
No private registry credentials are fetched or changed.
Runtime tests use isolated projects and local repository tripwires, including
settings profiles, parent inheritance, mirrors, system/reactor dependencies,
Gradle exclusive content, project substitution, and missing offline metadata.
Run with DEPTRUST_TEST_JVM=1 go test ./internal/app -run 'TestEffectiveMaven|TestEffectiveGradle|TestMavenLocal'.
The public Gradle fixture primes an isolated cache with the vetted public
commons-lang3 test module before testing the product's offline inspection.
References: Maven lifecycle callback, Maven repository order, Gradle public repository API, Gradle resolution results, Gradle safe resolution lifecycle.
For Hackage, source_file accepts Cabal's dist-newstyle/cache/plan.json.
Only matching repo-tar packages whose recorded repository URI is HTTPS
hackage.haskell.org proceed to public checks. Local, source-repository, tarball,
custom-repository, missing-source, and unlisted packages return unknown.
The parser follows Cabal's official plan writer; fixtures cover those shapes.
The selected plan is not freshness/provenance proof; DepTrust does not generate
or update it.
References: Cabal external plan artifact, official plan writer.
For CocoaPods, source_file accepts Podfile.lock. SPEC REPOS associates root
pod names with trunk/the public Specs repository or custom repositories.
EXTERNAL SOURCES takes precedence and returns unknown; mixed or missing
source assignments do too. Query root pod names, not subspec names. The selected
lockfile does not verify Podfile freshness, local repository configuration, or
installed artifact provenance. No Podfile or Ruby project code is evaluated.
Reference: official CocoaPods lockfile implementation.
For Hex, source_file accepts a selected official package API response JSON.
The package name, repository: hexpm, and hex.pm package URL must agree before
public assessment proceeds. Organization/custom repository metadata, mismatched
identities, and missing fields return unknown. Repository-qualified names also
skip public requests without a selected file. Metadata is a caller-selected
snapshot, not live authentication or provenance verification. DepTrust does not
fetch private metadata on your behalf or evaluate Mix files. mix.lock parsing is supported as described below; effective Mix runtime repository
overrides and authenticated private fetching remain separate.
References: Hex private organizations, Hex repository usage, official repository-qualified naming.
For GitHub Actions, local paths and docker:// actions return unknown before
public requests. For repository actions, source_file accepts the official
GitHub repository API response JSON. Matching full_name, private: false,
visibility: public, and github.com repository URL are required before public
checks. Private/internal, mismatched, or incomplete metadata returns unknown.
This snapshot is not live visibility verification and may become stale. Without
it, ordinary owner/repo checks retain public behavior; privacy cannot be inferred
from an owner/name. Fetching authenticated metadata and enterprise-host support
remain separate integrations. No repository visibility or permission is changed.
Reference: GitHub repository REST metadata.
Hooks also accept optional source_context containing the same project_dir,
nuget_config, bundler_lock, or source_file selector used by CLI/MCP. The
wrapper supplying hook JSON must provide it explicitly; identity/version fields
cannot override parsed install requests. With an absolute cwd, hooks use npm or
Cargo project context; NuGet uses its effective .NET hierarchy, and Go uses
effective GOPRIVATE independently. Other project
installs require explicit context rather than guessing inherited repositories
from a nearby artifact. New dependencies not yet represented by selected
artifacts may return unknown. This does not turn command parsing into a complete shell
interpreter; unrecognized commands and source overrides remain documented limits.
A consolidated source support matrix lists the implemented paths, verification boundaries, and deferred integrations.
Use --project-dir /absolute/path/to/solution-directory nuget Package.Name 1.2.3
(MCP: project_dir) to apply inherited NuGet configuration. DepTrust invokes the
official dotnet nuget config paths command, reads its ordered machine/user/parent
file list, and applies collection clears/removals, source-key overrides, disabled
sources, mapping precedence, and %ENVIRONMENT_VARIABLE% source URLs. The selected
directory is the restore context; choose the solution or project directory used
by your actual restore. The installed .NET SDK must support that command.
No restore or project evaluation runs during source discovery. Tests compare
merge decisions against the NuGet.Configuration assemblies shipped with the SDK,
including replacement of a source's pattern list by a child config. Discovery
errors stop public requests. --nuget-config retains NuGet's standalone-file mode.
Hooks can use their absolute cwd for effective NuGet context.
Reference: official NuGet configuration hierarchy.
Hex source_file also accepts mix.lock. DepTrust invokes Elixir's official
Code.string_to_quoted! parser and inspects the returned AST without evaluating
the lockfile or loading mix.exs. Public :hex tuples must identify the queried
package and the hexpm repository (including Hex's legacy default repository).
Organization/custom repositories, Git entries, aliases queried as package names,
unlisted packages, and executable expressions return unknown. Syntax/tool
errors stop before public requests. Elixir must be on PATH.
Tests run the same parser in a cached official Elixir container with networking
disabled, read-only fixtures, and an executable-lockfile marker that must never
be created. Set DEPTRUST_TEST_ELIXIR_IMAGE to a cached digest to run that optional
oracle when Elixir is not installed; normal product code does not invoke Docker.
References: Elixir AST parsing, Hex lock tuple semantics.