targate
v0.10.0
Published
targate is install-time supply-chain security for npm — open source, AI-optional, and run from your terminal. It vets every dependency (tarball, lifecycle scripts, lockfile, reputation, known-malicious records) before its code can run, and only installs i
Maintainers
Readme
targate — install-time supply-chain security for npm, in your terminal
targate is install-time supply-chain security for npm — open source, AI-optional, and run from your terminal. It vets every dependency before its code can run: it fetches the published tarball into an isolated quarantine (lifecycle scripts never execute), reads the install-time scripts, analyzes the resolved lockfile before anything is downloaded for real, checks reputation and known-malicious records, and returns an allow / warn / approve / block decision — then runs the real install only if the package passes.
Four things define it:
- Install-time. The gate sits at the exact moment
npm installwould otherwise run a package's lifecycle scripts on your machine — before code executes, not after. - Supply-chain, not application security. It reasons about what a third-party dependency does when you install it, not about bugs in the code you write. See supply chain vs. application security.
- AI-optional. A deterministic rules engine decides on its own; an AI reviewer, when configured, can only make a verdict stricter and can run on a local model. With no provider, nothing leaves your machine.
- Terminal-native & open source. One CLI in the workflow and CI you already have — no dashboard, no account, no SaaS. New to the problem it solves? Start with Why targate.
Quick start
Install the CLI, then gate any package before it lands in your project:
npm install -g targate # or run ad-hoc: npx targate add <package>
targate add lodashtargate analyzes the package first and only runs the real install if it passes:
Pre-install review — [email protected]
────────────────────────────────────────────────────────────
Lodash modular utilities.
license: MIT · published: 1977 days ago · deps: 0 · repo: git+https://github.com/lodash/lodash.git
Analysis
✓ no lifecycle scripts
✓ no known malicious-package records (OSV/OpenSSF)
✓ no typosquatting suspicion
✓ repository metadata present
✓ OSV/OpenSSF lookup completed
✓ no native code
static findings:
- lodash.min.js: appears minified/obfuscated
Decision: ALLOW (risk: low, source: rules)Preview a package without installing anything with --dry-run, or record a committable approval without installing via targate approve <package>. A full positive-and-negative walkthrough — including a package that gets blocked — is in docs/examples/full-review.md.
Tip — vet the whole tree. By default
targate add <pkg>analyzes only the package you named; a malicious dependency usually hides deeper in the tree. Strongly recommended: add--deep(or usetargate install) before pulling a dependency into a real project or in CI — it runs the same analysis over every transitive dependency. It is opt-in rather than default because a deep run resolves and analyzes the entire tree (more network/AI cost); the quick per-package check stays fast by default. See transitive dependencies & full-tree install.
Install
targate ships three ways — all install the same CLI.
npm — every platform, needs Node ≥ 22.13:
npm install -g targate # or ad-hoc: npx targate add <package>Install script — macOS & Linux; detects your OS/arch, downloads the binary, and verifies a minisign signature over the checksums and then the SHA-256 before installing. It fails closed: no minisign, a missing signature, or a bad signature aborts the install (needs minisign on PATH):
curl -fsSL https://raw.githubusercontent.com/marcoabate-ck/targate/main/install.sh | shDirect download — grab a standalone binary from the latest release and verify it against the release SHA256SUMS:
| Platform | Asset |
| ----------- | ------------------------- |
| macOS arm64 | targate-darwin-arm64 |
| macOS x64 | targate-darwin-x64 |
| Linux arm64 | targate-linux-arm64 |
| Linux x64 | targate-linux-x64 |
| Windows x64 | targate-windows-x64.exe |
# verify then install (example: macOS arm64)
grep targate-darwin-arm64 SHA256SUMS | shasum -a 256 -c -
install -m 0755 targate-darwin-arm64 /usr/local/bin/targateThe standalone binaries bundle the JS runtime, but targate still calls your git and package manager at runtime — keep those installed.
How it works
developer intent → package inspection → AI risk reasoning → safe install decisionflowchart TD
A["targate add <pkg>"] --> B[Resolve npm metadata]
B --> C[Download tarball to quarantine]
C --> D["Static analysis (scripts, contents, native surface)"]
D --> E["OSV/OpenSSF malicious + vulnerability lookup"]
E --> F["Rules engine — deterministic security floor"]
F --> G["AI reviewer — can only make the verdict stricter"]
G --> H{Decision}
H -->|allow / warn| I[Gated install]
H -->|require approval| J[Install with scripts disabled, or approve]
H -->|block| K[Never installed]targate resolves the package from npm, extracts the tarball into quarantine (scripts never run), statically inspects lifecycle scripts and contents, checks OSV/OpenSSF for malicious records, maps the React Native native surface, then reasons over every signal — with an AI provider if one is configured, or a deterministic rules engine otherwise. Every deterministic verdict is a floor the AI can never downgrade. Full walkthrough: how it works · architecture.
Commands at a glance
| Command | What it does |
|---|---|
| targate add <package>[@version] | Analyze one package, then gate its installation. |
| targate approve <package>[@version] | Record a committable human approval without installing. |
| targate audit <package>[@version] | AI-read a package's source for security issues, without installing. |
| targate install | Vet the complete dependency tree, then gate a full install. |
| targate sandbox <package>[@version] | Trial-install a package in a disposable Docker container. |
| targate ci [init] | Gate dependency changes against a Git ref or scaffold CI. |
| targate policy init | Scaffold a declarative team policy from a preset. |
| targate proxy <start\|stop\|status\|ensure\|setup\|teardown\|exec\|cert\|approvals\|approve\|deny> | Run a registry proxy that vets every package before install. |
| targate doctor | Diagnose the local security and provider environment. |
| targate diff <pkg>@<v1> [<pkg>[@<v2>]] | Compare package versions and rate the upgrade risk. |
| targate monitor | Re-check trusted packages and report increased risk. |
| targate graph [<package>[@version]] | Render a dependency risk graph or explain why a package is present. |
| targate recommend "<need>" | Recommend analyzed packages for a need, safest first. |
| targate history [<package>[@version]] | Show recorded trust decisions and optionally verify signatures. |
| targate explain <package>[@version] \| --last | Explain a fresh or previously recorded decision without installing. |
| targate cache <info\|clear> | Inspect or clear the AI assessment cache. |
| targate agents init | Scaffold instructions that make coding agents use targate. |
Package installation is intentionally explicit: use targate add <package>. Bare package names and unknown commands fail without starting an analysis. Run targate <command> --help for the options accepted by that command.
Exit codes: 0 ok · 1 error · 2 blocked (or suspicious sandbox / failed CI check). Full flags and options: docs/cli-reference.md.
Key guarantees
- Deterministic security floor. The rules engine decides first; the AI can only make a verdict stricter. A jailbroken or prompt-injected model cannot turn
allow_with_warnings,require_approval, orblockinto a weaker result. See docs/decisions.md. - Hard vs soft blocks. Artifact-identity mismatches, known-malicious records, and remote-code-execution blocks can never be overridden; heuristic ("soft") blocks can be deliberately cleared by a committed approval or allow-list entry.
- Auditable, verifiable trust. Every approval records its circumstances (who, when, verdict, tool version, AI model, policy hash) —
targate historyshows it;targate approve --signadds an SSH signature thatrequireSignedApprovalsenforces in CI, so a hand-edited approvals file cannot green a poisoned dependency. - Nothing untrusted executes during analysis. Tarballs are SHA-512 identified and checked against every available registry, lockfile, public-mirror, and historical digest before being read in a resource-bounded quarantine — lifecycle scripts never run. A compromised npm mirror that rewrites tarball and metadata is hard-blocked by the independent public comparison when a public mirror is configured (
registries[].mirrorOfor a global.npmrcoverride) and reachable; against the defaultregistry.npmjs.org, or when the public comparison is unavailable, the divergence is surfaced for review (require_approval/allow_with_warnings) rather than hard-blocked. Repository configuration is declarative only (.yaml/.yml/.json) — it is parsed, never executed, so a hostile repo cannot run code through a config file. See docs/security.md. - Bounded inputs fail visibly. Network bodies, tarballs, extracted trees, individual files, and scan time have configurable limits. A timeout or exceeded limit is reported as
UNKNOWNand deterministically requires approval; it is never presented as clean. - Local-AI capable — your code never leaves your machine. targate does reach the network for package metadata, tarballs and vulnerability data, but the AI reasoning can run entirely on a local model; with no AI provider configured it runs on the deterministic rules engine alone and sends nothing to any model. See AI providers.
- Fail-closed option.
--fail-on-osv-errorescalates when the malicious-package lookup can't complete, so a package is never silently trusted while the strongest check was skipped.
What's shipped today vs. the vision
Install-time supply-chain security is what targate is today. Under the hood it is a dependency intelligence and decision layer, and that engine can grow beyond the install gate. To keep messaging honest, here is the line between what ships today and where the product is going.
Available today — everything in this README is implemented and tested:
- Security score and structured, machine-readable signals (
--json). - Reputation and maintainer intelligence.
- Explain, diff, and monitor workflows.
- Team policy, version-specific approvals, and signed trust history.
- Pre-install gating, CI integration, coding-agent integration, and sandboxed observation.
Future vision — directional, not commitments (tracked in what's next):
- Developer intent and project context as first-class inputs.
- Grounded dependency recommendations and safer-alternative discovery.
- Deeper trust history across an organization.
The distinction that matters: today targate inspects and decides; the vision is that it also recommends with intent. An unchecked roadmap item is a plan, not a promise.
Documentation
The full docs are online at targate.dev/docs. The same specifications live in docs/:
| Topic | Page |
| ------------------------------------------------- | ----------------------------------------------------------- |
| Why gate dependencies | why.md |
| Full end-to-end example (allow + block) | examples/full-review.md |
| Architecture · deterministic vs AI | architecture.md |
| The analysis pipeline | how-it-works.md |
| Every command, flag, exit code | cli-reference.md |
| Decision policy · hard vs soft blocks | decisions.md |
| Policy reference (full schema) | policy-reference.md |
| AI providers · reasoning support | ai-providers.md |
| AI response cache | ai-cache.md |
| --deep & targate install | transitive-and-install.md |
| Approvals · pnpm builds · team policy | team-workflow.md |
| Private registries · .npmrc · internal scopes | private-registries.md |
| Dependency risk graph · workspaces · CI artifacts | dependency-graph.md |
| React Native hardening | react-native.md |
| Sandboxed trial install | sandbox.md |
| CI integration | ci.md |
| AI coding agents | agents.md |
| Threat model (what it catches / can't) | threat-model.md |
| Security model, scope & limitations | security.md |
| Roadmap · what's next | whats-next.md |
Development
pnpm install
pnpm build
pnpm dev add <pkg> # run from source (tsx), e.g. pnpm dev add react-native-mmkv --dry-run
pnpm test # vitest suite, including end-to-end CI and full-install fixture checks
pnpm typecheck
pnpm format:check # zero-dependency whitespace/formatting gate across the tree
pnpm docs:check # generated CLI docs, examples, and local links
pnpm pack:check # offline: the published tarball ships only dist/**+README+LICENSE+package.json, and the bin runs
pnpm audit # runtime dependency advisory audit (--prod, high and above)
pnpm benchmark # repeatable cold/warm 10–1000 package performance targetsOr use the built CLI locally: run it in place with node dist/cli.js add <package>, or register it as targate on your PATH — pnpm setup once (creates pnpm's global bin dir), then pnpm add -g . from the repo root (pnpm ≥ 11; on pnpm ≤ 10 use pnpm link --global, which pnpm 11 removed).
Continuous integration
.github/workflows/ci.yml runs every push and pull request:
- quality —
install --frozen-lockfile, build, typecheck,format:check,docs:check, the full test suite, andpack:check(the published-artifact gate), on Node 22 and 24 across Linux and Windows (the Windows leg is the cross-platform path coverage). - dependency gate + audit — gates the project's own dependency tree through
targate install --dry-run(targate eats its own dog food) and audits runtime dependencies for advisories. - performance benchmarks — the repeatable 10–1000 package targets, which fail the job on regression.
The project deliberately uses no external linter or formatter: type safety is enforced by tsc in strict mode and formatting by the zero-dependency format:check, so no toolchain dependency bypasses the targate gate.
Contributing & security
- Contributions are welcome — read CONTRIBUTING.md for the workflow, gates, and expectations, and CODE_OF_CONDUCT.md for community standards.
- Found a security issue? Do not open a public issue. Follow the private disclosure process in SECURITY.md.
Stability & compatibility
targate follows Semantic Versioning. From 1.0.0 on,
the following are the stable surface — a breaking change to any of them ships
only in a new major version, with an entry in CHANGELOG.md:
- CLI — command names, their flags, and exit codes. In particular
0= allowed / clean,1= usage or operational error,2= blocked (and, forciandinstall, an unresolved approval). Note the2-on-unresolved-approval contract applies to the non-interactiveci/installpaths; interactivetargate addreturns0when arequire_approvalpackage is skipped or declined. New commands and new (additive) flags are minor releases. The stable command set isadd,approve,install,ci,audit,doctor,explain,diff,history,policy,agents, andcache;graph,recommend, andmonitorship as experimental and may change flags or output in a minor release. --jsonoutput — the machine-readable schema, carried explicitly asschemaVersion(currently1). Within a major, changes are additive only (consumers must ignore unknown keys); any removal, rename, or type change bumpsschemaVersionand the major.- Committed config formats —
.targate/approvals.json,.targate/denials.json, and thetargate.policy.*schema (including thedependencyPolicy,aiCache,registries, andresourceLimitsfields). Existing keys keep their meaning within a major; unknown keys are ignored with a warning.
Not part of the stable surface (may change in a minor release): human-readable
terminal formatting, heuristic tuning and thresholds, AI prompts/models, the
security score number, and internal module APIs (targate is consumed as a
CLI, not imported as a library).
Releases are cut by pushing a v* tag; the release pipeline
(.github/workflows/release.yml) runs the full
gate set (typecheck, tests, build, docs, format, and the pack:check artifact
gate, plus the runtime dependency audit), sets the published version from the
tag, and publishes with npm provenance. The version in package.json is not
bumped by hand.
