{"id":50450671,"url":"https://github.com/barestripehq/primer","last_synced_at":"2026-06-01T00:01:34.766Z","repository":{"id":359429764,"uuid":"973235199","full_name":"barestripehq/primer","owner":"barestripehq","description":"Pre-install security interceptor for package managers.","archived":false,"fork":false,"pushed_at":"2026-05-28T20:54:38.000Z","size":717,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-28T22:22:25.651Z","etag":null,"topics":["cve","mcp","osv","package-manager","sbom","scanner","security","vulnerability"],"latest_commit_sha":null,"homepage":"https://primer.barestripe.com/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/barestripehq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-26T14:58:47.000Z","updated_at":"2026-05-28T20:54:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/barestripehq/primer","commit_stats":null,"previous_names":["callezenwaka/primer","barestripehq/primer"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/barestripehq/primer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barestripehq%2Fprimer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barestripehq%2Fprimer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barestripehq%2Fprimer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barestripehq%2Fprimer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/barestripehq","download_url":"https://codeload.github.com/barestripehq/primer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barestripehq%2Fprimer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33753925,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cve","mcp","osv","package-manager","sbom","scanner","security","vulnerability"],"created_at":"2026-06-01T00:01:25.496Z","updated_at":"2026-06-01T00:01:34.760Z","avatar_url":"https://github.com/barestripehq.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# primer\n\nPre-install security interceptor for package managers. Scans packages against the [OSV vulnerability database](https://osv.dev/) before they hit your system — with an optional local AI summary, git hook integration, and CI mode.\n\n## How it works\n\nprimer places lightweight shims ahead of your package managers in `$PATH`. When you run `pip install requests`, the shim intercepts the command, queries OSV, and either passes through silently (clean result) or prompts you before executing.\n\n```\npip install pillow\n  → primer shim intercepts\n  → queries OSV\n  → found 3 vulnerabilities (1 CRITICAL, 2 HIGH)\n    pillow 9.0.0 — GHSA-56pw-mpj4-fxjw [CRITICAL]\n      Summary: Heap buffer overflow in TIFF image parser\n      Fixed in: 9.0.1\n  → [prompt] View full details? (y/N)\n  → [prompt] Continue install anyway? (y/N)\n  → exits 1 on \"N\"\n```\n\n✓ requests: found 0 vulnerabilities — passes through silently (after the first cached query).\n\n## Supported ecosystems\n\n| Ecosystem | Intercepted commands | Manifest / Lockfile |\n|-----------|---------------------|---------------------|\n| Python    | `pip`, `uv`, `poetry` | `requirements.txt`, `pyproject.toml`, `uv.lock`, `poetry.lock` |\n| Node.js   | `npm`, `yarn`, `pnpm` | `package.json`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml` |\n| Go        | `go get`, `go mod` | `go.mod`, `go.sum` |\n| Rust      | `cargo add`, `cargo build`, `cargo fetch`, `cargo check` | `Cargo.toml`, `Cargo.lock` |\n\n## Installation\n\n**macOS / Linux**\n\n```sh\ncurl --proto '=https' --tlsv1.2 -fsSL https://github.com/barestripehq/primer/releases/latest/download/primer-installer.sh | sh\nprimer init\n```\n\n`primer init` creates shims in `~/.primer/bin` and prepends it to your shell config (`.zshenv` for zsh, `.bashrc` for bash, fish function for fish). Restart your shell or `source` the config file.\n\n**Windows**\n\nDownload the MSI installer from the [latest release](https://github.com/barestripehq/primer/releases/latest), then run in a new terminal:\n\n```powershell\nprimer init\n```\n\n`primer init` creates `.cmd` wrappers in `%USERPROFILE%\\.primer\\bin`, updates user PATH via `SETX`, and injects into your PowerShell 7 profile. Open a new terminal for changes to take effect.\n\n**From source:**\n\n```sh\ncargo install --git https://github.com/barestripehq/primer\nprimer init\n```\n\n## Commands\n\n### Scanning\n\n```sh\n# Scan any package manually\nprimer scan requests --ecosystem pypi\nprimer scan express --ecosystem npm\nprimer scan github.com/gin-gonic/gin --ecosystem go\nprimer scan serde --ecosystem cargo\n\n# Pin a version\nprimer scan pillow --ecosystem pypi --version 9.0.0\n\n# Skip prompts (proceed regardless)\nprimer scan pillow --ecosystem pypi --force\n\n# Show cache hit/miss\nprimer scan requests --ecosystem pypi --verbose\n\n# Include AI-generated summary (requires primer model add)\nprimer scan pillow --ecosystem pypi --ai\n\n# Scan all packages declared in a manifest file (no install)\nprimer scan --file requirements.txt\nprimer scan --file package.json\nprimer scan --file go.mod\nprimer scan --file Cargo.toml\n\n# Scan a lockfile directly — resolves exact pinned versions for every transitive dep\nprimer scan --file package-lock.json\nprimer scan --file yarn.lock\nprimer scan --file Cargo.lock\n\n# Skip transitive dependencies (direct packages only)\nprimer scan --file package.json --direct-only\n\n# Output SARIF 2.1.0 for GitHub Security tab upload\nprimer scan --file requirements.txt --format sarif\nprimer scan --file package-lock.json --format sarif --output results.sarif\n```\n\nEach finding shows the patched version when OSV provides one:\n\n```\npillow 9.0.0 — GHSA-56pw-mpj4-fxjw [CRITICAL]\n  Summary: Heap buffer overflow in TIFF image parser\n  Fixed in: 9.0.1\n```\n\n### Transitive dependency scanning\n\nBy default, primer scans the full dependency tree — not just the package you name, but everything it pulls in.\n\n**Explicit installs** (`npm install express`, `cargo add serde`): primer scans the named package first (pre-install), then after the PM runs it diffs the lockfile and scans any newly added transitive packages. Post-install findings include a remove hint since the package is already on disk.\n\n**Bare restores** (`npm install`, `go mod download`): when `intercept-restore` is enabled and a lockfile exists alongside the manifest, primer loads it to resolve exact versions for both direct and transitive packages before the PM runs. The header shows the split:\n\n```\n  primer: scanning package.json — 3 direct + 47 transitive packages\n```\n\n**Opt out** — skip transitive scanning when you want low-noise results:\n\n```sh\n# Per command\nprimer scan --file package.json --direct-only\n\n# Globally (writes to ~/.primer/config.toml)\nprimer config set direct-only true\n```\n\nThe transitive scan always closes with a status line:\n\n```\n  primer: scanning 4 new transitive packages …\n  ✓ transitive scan complete — found 0 vulnerabilities.\n```\n\n### Auditing existing vulnerabilities\n\nThe shim gates new installs. To surface vulnerabilities already in your project, scan the manifest or lockfile directly:\n\n```sh\nprimer scan --file package-lock.json   # full resolved tree (recommended)\nprimer scan --file package.json        # declared dependencies only\nprimer scan --file requirements.txt\nprimer scan --file Cargo.toml\n```\n\nFor each vulnerable package, primer shows the CVE details and a ready-to-run fix command:\n\n```\n⚠ lodash 4.17.15 (npm) — 6 vulnerabilities\n\n  [HIGH]   GHSA-35jh-r3h4-6jhm — Command Injection\n           Fixed in: 4.17.21\n           Fix:      npm install lodash@4.17.21\n  …\n```\n\nPrimer prints the fix command but does not modify your manifests — you run it, and the shim gates the new version on the way in.\n\n### Directory watcher\n\nAuto-scan manifest files whenever they change — useful for long-running dev sessions:\n\n```sh\nprimer watch                        # watch current directory\nprimer watch --directory /project   # watch a specific path\nprimer watch --scan                 # also scan immediately on startup\n```\n\nWatches: `requirements.txt`, `pyproject.toml`, `package.json`, `go.mod`, `Cargo.toml`. Debounced at 500 ms. Exit with `Ctrl+C`.\n\n### Policy file\n\n`.primer/policy.toml` is committed to the repo and enforced automatically on every developer machine and in CI — no flags required. It is separate from `~/.primer/config.toml` (machine-wide settings).\n\n\u003e **Legacy:** If you have a `.primer-policy.toml` in the project root, primer falls back to it with a deprecation warning. Run `primer migrate` to move it to `.primer/policy.toml`.\n\n```toml\n# .primer/policy.toml\n[policy]\nthreshold = \"high\"          # optional global override for this repo\n\n[[deny]]\npackage = \"event-stream\"    # hard block by name regardless of CVE status\nreason  = \"supply chain compromise\"\n\n[[ignore]]\ncve     = \"CVE-2023-1234\"\npackage = \"pillow\"          # optional: scope to one package\nexpires = \"2026-12-31\"      # YYYY-MM-DD; finding re-activates after this date\nreason  = \"Mitigated by WAF\"\n\n[[override]]\npackage   = \"requests\"\nthreshold = \"critical\"      # per-package threshold\n```\n\nEvaluation order: `[[deny]]` → `[[ignore]]` (expiry checked) → `[[override]]` → `[policy].threshold`.\n\n```sh\nprimer policy list    # show all rules and expiry status\nprimer policy check   # validate syntax without scanning\n```\n\n### Severity threshold\n\nControl which severity level triggers a prompt or CI block:\n\n```sh\nprimer config set prompt-threshold medium   # block MEDIUM, HIGH, CRITICAL\nprimer config set prompt-threshold critical # block CRITICAL only\nprimer config set prompt-threshold high     # default\n```\n\n### SBOM generation\n\nEmit a Software Bill of Materials for any manifest or lockfile:\n\n```sh\nprimer sbom --file requirements.txt              # CycloneDX JSON to stdout\nprimer sbom --file package-lock.json             # from lockfile (exact versions)\nprimer sbom --file Cargo.toml --output sbom.json # write to file\nprimer sbom --file package.json --format spdx    # SPDX 2.3 JSON\nprimer sbom --file go.mod --no-scan              # inventory only, no OSV queries\n```\n\n### AI agent integration (MCP)\n\n`primer mcp` starts a [Model Context Protocol](https://modelcontextprotocol.io) server over stdio, exposing a `scan_package` tool that any MCP-capable agent (Claude Code, Cursor, Cline, …) can call before deciding to install a package.\n\nAdd a `.mcp.json` in your project root (or `~/.claude/mcp.json` for Claude Code):\n\n```json\n{\n  \"mcpServers\": {\n    \"primer\": {\n      \"command\": \"primer\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\nThe agent can then call:\n\n```\nscan_package(\"pillow\", \"PyPI\", \"9.0.0\")\n→ ⚠ pillow 9.0.0 (PyPI) — found 2 vulnerabilities:\n    [HIGH] GHSA-xxxx-yyyy-zzzz — Buffer overflow in TIFF decoder (Fixed in: 9.1.0)\n    [MEDIUM] GHSA-aaaa-bbbb-cccc — …\n```\n\nThe tool returns structured JSON (`vulnerabilities[]`, `summary.blocking`) so the agent can decide whether to proceed. OSV cache applies — repeated lookups are instant.\n\n### Setup and teardown\n\n```sh\nprimer init           # create shims, update PATH\nprimer uninit         # remove shims, strip PATH entry\nprimer uninit --purge # also delete cache and model files\nprimer doctor         # check PATH order, shim health, cache state, model state\nprimer migrate        # move .primer-ignore / .primer-policy.toml into .primer/\n```\n\n### Allow-list\n\nAdd a package to `.primer/ignore` (or `.primer-ignore` for legacy repos) to skip the scan without `--force`:\n\n```sh\nprimer allow add pillow\nprimer allow add pillow --ecosystem pypi   # scope to one ecosystem\n```\n\n### Cache\n\n```sh\nprimer cache clear    # remove all cached OSV results\n```\n\nResults are cached in `~/.primer/cache/` with a 24-hour TTL. On network failure the most recent cached result is used (stale-on-error fallback).\n\n### AI model\n\n```sh\n# Download the default model (~80 MB, no account required)\nprimer model add\n\n# Import a local GGUF file\nprimer model add --from /path/to/model.gguf --tokenizer /path/to/tokenizer.json\n\n# Download a specific model from HuggingFace Hub\nprimer model add --repo \u003chf-repo\u003e --file \u003cfilename\u003e\n\n# List registered models (* = active)\nprimer model list\n\n# Set the active inference target\nprimer model set ~/.primer/models/smollm2.gguf   # local candle inference\nprimer model set ollama:llama3.2                 # route to local Ollama instance\n\n# Remove models\nprimer model remove                              # interactive select\nprimer model remove smollm2.gguf ollama:llama3.2 # remove by name (no prompt)\nprimer model remove --all                        # remove all, clear config\n```\n\nOnce a model is present, pass `--ai` to any `scan` command to get a plain-English CVE summary before the decision prompt.\n\nSet `PRIMER_AI=0` to disable AI entirely (useful in CI pipelines).\n\n### Git hook\n\nBlock commits that add vulnerable packages to manifests:\n\n```sh\n# Install the pre-commit hook in the current repo\nprimer hook install\n\n# Run the check manually without committing\nprimer hook check\n```\n\nMonitored manifests: `requirements.txt`, `pyproject.toml`, `package.json`, `go.mod`, `Cargo.toml`.\n\n### Intercept bare restore commands\n\nBy default, bare restore commands (`npm install` with no packages, `go mod download`, etc.) pass straight through. Enable interception to scan the manifest before dependencies are installed:\n\n```sh\nprimer config set intercept-restore true\n```\n\nWhen enabled, primer scans the relevant manifest for each PM's \"install all\" form before passing through. If a lockfile is present, primer loads it to include transitive packages at exact pinned versions:\n\n| Command | Manifest scanned | Lockfile (if present) |\n|---------|-----------------|----------------------|\n| `npm install` / `pnpm install` / `yarn` | `package.json` | `package-lock.json`, `yarn.lock`, or `pnpm-lock.yaml` |\n| `pip install` (no packages) / `uv sync` | `requirements.txt` → `pyproject.toml` | `uv.lock`, `poetry.lock` |\n| `poetry install` | `pyproject.toml` | `poetry.lock`, `uv.lock` |\n| `go mod download` | `go.mod` | `go.sum` |\n| `cargo build` / `cargo fetch` / `cargo check` | `Cargo.toml` | `Cargo.lock` |\n\nDisabled by default — large projects can have many deps. Cache makes repeat scans instant. Use `--direct-only` (or `primer config set direct-only true`) to skip transitive packages.\n\n## CI / non-interactive mode\n\nWhen `CI=true` is set (standard on GitHub Actions, CircleCI, etc.) or stdin is not a TTY, primer switches to non-interactive mode automatically:\n\n- No prompts — consolidated findings table printed to stderr\n- Blocks on Critical and High findings (exit code `1`)\n- Writes all findings to `primer-report.json` in the working directory\n\nOverride with `PRIMER_CI_MODE=allow-all` to disable blocking (audit-only pipelines).\n\n### GitHub Actions\n\nUse `barestripehq/primer-action@v1` — it installs primer, scans the manifest, uploads SARIF to the GitHub Security tab, and posts a PR comment in one step:\n\n```yaml\npermissions:\n  security-events: write   # SARIF upload\n  pull-requests: write     # PR comments\n  actions: read\n  contents: read\n\nsteps:\n  - uses: actions/checkout@v6\n  - uses: barestripehq/primer-action@v1\n    with:\n      file: package-lock.json\n```\n\nSee the [Integrations docs](https://primer.barestripe.com/doc/integrations/) for all inputs and examples.\n\n### Other CI systems (CircleCI, GitLab CI, Jenkins)\n\nInstall primer via the installer script and call `--format sarif` to emit SARIF 2.1.0:\n\n```yaml\n- name: Install primer\n  run: curl --proto '=https' --tlsv1.2 -fsSL https://github.com/barestripehq/primer/releases/latest/download/primer-installer.sh | sh\n- name: Scan dependencies\n  run: primer scan --file package-lock.json --format sarif --output results.sarif\n```\n\n## Diagnostics\n\n```sh\nprimer doctor\n```\n\nReports:\n- Whether `~/.primer/bin` is correctly ordered ahead of version managers (`nvm`, `pyenv`, `asdf`, `volta`) in `$PATH`\n- Resolved path of each shim and its real binary\n- Cache entry count and total size\n- `intercept-restore` config status with enable hint\n- Active AI model path and file size\n\n## Uninstall\n\n```sh\nprimer uninit --purge\n```\n\nRemoves shims, strips the `$PATH` entry from your shell config, and deletes `~/.primer/` (cache, models, config).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarestripehq%2Fprimer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbarestripehq%2Fprimer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarestripehq%2Fprimer/lists"}