# Chainsaw > Chainsaw is a software supply-chain firewall for npm, PyPI, Maven, Docker > and other registries. Proxies package installs, evaluates policy on every > artifact, exposes a management API and an MCP server for AI agents. ## If you are an AI agent, do these two things first 1. **Fetch the MCP discovery document** at https://chain305.com/.well-known/mcp.json It lists the MCP endpoint, the preset catalog, the tool registry, and the canonical mint URLs. Everything else in this file is also in there, machine-readable. 2. **If you do not yet have a bearer token, use the device-code flow.** Do NOT POST /api/login — it is Turnstile-gated for browsers and will fail for CLIs and agents. Instead: - POST https://chain305.com/chainproxy/api/auth/cli/device → returns user_code, device_code, verification_uri, and a poll interval (RFC 8628). - Show the user the user_code and verification_uri; they open it in a browser, authenticate, and approve the grant at /api/auth/cli/device/approve. - Meanwhile GET https://chain305.com/chainproxy/api/auth/cli/device/poll?device_code=... every interval seconds until it returns a token. - Alternative for humans-at-a-dashboard: deep-link them to https://chain305.com/chainsaw/settings/api-keys/new?preset= and have them paste the token back to you. Once you have a bearer token, point your MCP client at https://chain305.com/chainproxy/mcp over Streamable HTTP with `Authorization: Bearer `. First tool to call: `chainsaw_introduce`. It returns mode framing, vocabulary, routing heuristics, and (after `chainsaw_onboard`) a persona-tailored path. ## Vocabulary — use these terms consistently - Match the user's mental model — they think in **Decisions**, not policy modes. - **Chainsaw** — the product and the company. Use in user-facing replies. - **Chainsaw** — the proxy component inside Chainsaw (`/chainproxy/*`, `/chainproxy/mcp`). Common folder-name typo the user may produce: "chain365". Don't correct the user; just say "Chainsaw" in your replies. - **Decision** — Chainsaw's user-facing answer for any package install: **Blocked** (prevented automatically), **Monitored** (detected but allowed through), or **Allowed** (no rule triggered, or an explicit allow rule matched). Use these three words verbatim in user-facing replies. Distinct from policy *mode* (block/quarantine/monitor/allow, the wire-level enum the policy author writes) and lifecycle *status* (new/acknowledged/snoozed/resolved/suppressed, what the human is doing about a finding). - **Posture** — the dashboard's one-state summary of the org's firewall health: **Protected** / **At risk** / **Monitoring only** / **Needs setup**. When a user asks "are we protected?" answer with one of these four states. - **client_credential** — username/password-style secret that goes into `.npmrc` / `pip.conf` / `~/.docker/config.json` / `~/.m2/settings.xml`. Held by the human. Agents NEVER hold these — you help the human paste one into config files. - **API key** (bearer) — the agent's own credential for MCP and the management API. Minted via the dashboard or the device-code flow. Scoped to a preset. - **Billy** — internal name for the approval workflow (policy proposals route through it). Translate to "human approval" in user-facing replies; users don't need the internal name. ## Mental models — what does the user think they're doing? Chainsaw serves five personas, each with a different mental model. Match the user's utterance to a persona BEFORE picking a mode: - **End-user developer** (most common cold walk-in). Head: "I want `pip install` / `npm install` to go through Chainsaw." Utterances: "set up chainsaw for python," "do it for me," "install chainsaw in this repo." → Mode A, `client-setup` preset. Call `chainsaw_onboard` with `skip=true` so the persona nudge doesn't block them. - **AppSec**. Head: "I author the rules that block bad packages." Utterances: "draft a CVSS policy," "why was this CVE allowed?" → Mode B, `manage-propose` preset. - **DevSecOps / Platform engineer**. Head: "I plumb the proxy into fleets and CI runners." Utterances: "mint a CI service token," "add proxy to GitHub Actions." → Mode A, `client-setup` preset (org-scale flavour of end-user dev). - **Enterprise IT / Governance**. Head: "Show me evidence — I report, I don't author." Utterances: "export SBOM," "pull yesterday's audit log." → Mode B, `manage-readonly` preset. - **Agent-as-persona** (that's you). Head: "I'm headless — no browser, no cookies, no Turnstile widget I can solve." Canonical first five actions: (1) GET /.well-known/mcp.json, (2) if no bearer, POST /api/auth/cli/device, (3) show user the user_code + verification URL, (4) poll /device/poll, (5) connect MCP and call `chainsaw_introduce`. Never POST /api/login. ## First-message routing heuristics Match the user's first utterance; act accordingly. Authoritative copy is returned by `chainsaw_introduce` as `routing_heuristics` — treat this table as a stale mirror and the MCP response as source of truth. | User says… | Do | |---|---| | "set up for {python/node/go/java/docker}" | Mode A; `list_my_repositories` → `get_install_snippet(ecosystem=X)` | | "do it for me" / "just set it up" | Mode A; `chainsaw_onboard(skip=true)`; device-code flow; then snippet | | "block {CVE / package / license}" | Mode B `manage-propose`; `list_policies` → `propose_policy` | | "audit" / "SBOM" / "who installed X" | Mode B `manage-readonly`; `get_audit_log` | | "why is this blocked" / "policy error" | Mode B `manage-readonly`; `get_package_info` + `list_policies` | | "install chainsaw" / "chain365" (typo) | Normalize — Chainsaw = proxy, Chainsaw = product; usually Mode A | ## Pick the mode before you pick the key There are two distinct workflows. Pick wrong and you'll waste your user's time. **Mode A — Configure my project to install through Chainsaw.** The user wants `npm install` / `pip install` / `docker pull` to flow through the proxy so policy enforces on every install. End state: a `client_credential` in their `.npmrc` / `pip.conf` / `~/.docker/config.json` / `~/.m2/settings.xml`. Default sub-flow: human mints credential in the dashboard, agent only edits config files. Agent's API key needs scope `repos:read` (preset: `client-setup`). → Mint a key: https://chain305.com/chainsaw/settings/api-keys/new?preset=client-setup **Mode B — Manage Chainsaw (policies, audit, SBOMs).** The user wants to inspect or change Chainsaw itself. Agent calls the management API via MCP. Pick `manage-readonly` for view-only or `manage-propose` for the ability to draft policy changes (which route through human approval by default). → Mint a read-only key: https://chain305.com/chainsaw/settings/api-keys/new?preset=manage-readonly → Mint a propose key: https://chain305.com/chainsaw/settings/api-keys/new?preset=manage-propose **If you don't know which mode the user needs, ASK THEM. Do not guess.** ## Personas recorded by chainsaw_onboard When the agent calls `chainsaw_onboard` with one of: - `appsec` — application security; suggests Mode B + manage-propose - `devsecops` — platform / build engineering; suggests Mode A + client-setup - `enterprise_it` — governance / audit; suggests Mode B + manage-readonly Or pass `skip=true` to silence the onboarding nudge (recommended for the "end-user developer" mental model — they just want pip to work). ## API key presets - `client-setup` — Mode A. Scope: `repos:read`. Lets the agent list the user's repos and generate install snippets. Cannot change any Chainsaw state. - `manage-readonly` — Mode B. Read-only scopes (`policies:read`, `audit:read`, `packages:read`). For inspecting policies, vulnerabilities, audit logs. - `manage-propose` — Mode B. Adds `policies:manage` so the agent can draft policy changes; mutations are routed through the human-approval flow by default. - `custom` — pick specific scopes in the dashboard. ## MCP tools Bootstrap tools (callable by any authenticated key): - `chainsaw_introduce` — first call; returns mode framing, vocabulary, routing heuristics, preset catalog, persona nudge - `chainsaw_onboard` — record persona (appsec / devsecops / enterprise_it) or pass skip=true - `chainsaw_onboarding_state` — returns the caller-org's setup checklist with narration strings (client_created, policy_applied, …). Read-only. Call this before guiding a user through setup so you don't re-route them through a step they've already completed. Mode A tools (preset: client-setup): - `list_my_repositories` — list the user's repos - `get_install_snippet` — generate `.npmrc` / `pip.conf` / Maven / Docker snippet - `setup_doctor` — diagnose user-supplied proxy config Operator CLI (run locally, not via MCP): - `chainsaw doctor verify-hook` — detects client-side install-hook bypasses (a dev who edited `.npmrc` or set an env override to skip the proxy will surface here, not silently slip past policy). - `chainsaw doctor logs` — surfaces operator-actionable WARN lines from the server so on-call doesn't grep raw stdout. Pair with `verify-hook` when a user says "but I did install it through Chainsaw." Mode B tools (preset: manage-readonly or manage-propose): - `list_policies` — list policies on the org - `propose_policy` — draft a policy change (routes through approval) - `simulate_policy` — dry-run a policy against recent traffic - `get_package_info` — metadata for a package@version - `check_vulnerabilities` — CVE/CVSS/EPSS for a package@version - `get_audit_log` — query the audit log ## Supply-chain attack coverage Beyond CVE/license rules, Chainsaw carries 12 first-class attack signals — 4 always-on (CVE/CVSS/EPSS, license, reserved namespaces, trust score) plus up to 8 more where each registry supports them: install-script exfiltration (PhantomRaven), maintainer-account takeover (Axios pattern), version-number anomalies and backdated publishes, hidden Unicode (GlassWorm, Trojan Source), publish-velocity worm bursts (Shai-Hulud), Docker malware feed, bundled Hugging Face malware feed, per-layer container image scanning, APT/Yum/DNF hash-chain provenance, Linux distro CVE detection (Alpine / Debian / Red Hat / Oracle Linux), typosquat matching across 14 ecosystems including Go, CocoaPods, and GitHub Actions, repo-liveness plus ownership-match trust factor, and checksum fail-closed enforcement. Each is a condition on a policy object. Per-ecosystem coverage grid at POLICY_PROXY_MATRIX.md. ## Documentation - [Quickstart: set up Chainsaw as your proxy](https://docs.chain305.com/tutorials/01-set-up-chainsaw-as-package-proxy/) - [Configure your package manager](https://docs.chain305.com/tutorials/02-configure-package-manager-for-chainsaw/) - [Create and manage client credentials](https://docs.chain305.com/tutorials/03-create-manage-client-credentials/) - [Block vulnerable packages by CVSS/EPSS](https://docs.chain305.com/tutorials/04-block-vulnerable-packages-cvss-epss/) - [Detect and prevent typosquatting](https://docs.chain305.com/tutorials/05-detect-prevent-typosquatting/) - [Enforce license compliance](https://docs.chain305.com/tutorials/06-enforce-license-compliance/) - [Verify package provenance (SLSA)](https://docs.chain305.com/tutorials/07-verify-package-provenance-slsa/) - [Detect install-script exfiltration](https://docs.chain305.com/tutorials/35-detect-install-script-exfiltration/) - [Detect compromised packages (maintainer takeover)](https://docs.chain305.com/tutorials/36-detect-compromised-packages/) - [Detect hidden Unicode payloads](https://docs.chain305.com/tutorials/37-detect-hidden-unicode/) - [Detect publish-velocity anomalies](https://docs.chain305.com/tutorials/38-detect-publish-velocity-anomaly/) - [Apply reserved-namespace packs](https://docs.chain305.com/tutorials/39-apply-reserved-namespace-packs/) - [Enable checksum fail-closed](https://docs.chain305.com/tutorials/40-enable-checksum-fail-closed/) - [OS-package hash-chain provenance](https://docs.chain305.com/tutorials/41-os-package-hash-chain-provenance/) - [Scan container image layers](https://docs.chain305.com/tutorials/42-scan-container-image-layers/) - [Monitor violations and respond to blocks](https://docs.chain305.com/tutorials/09-monitor-violations-respond-blocked/) - [Export SBOMs (CycloneDX)](https://docs.chain305.com/tutorials/10-export-sbom-cyclonedx/) - [Integrate with CI/CD pipelines](https://docs.chain305.com/tutorials/21-integrate-chainsaw-with-cicd-pipelines/) - [Browse all docs](https://docs.chain305.com/) - [Machine-readable tutorial index](https://docs.chain305.com/llms.txt) ## API reference OpenAPI 3.1 spec (YAML) at https://chain305.com/chainproxy/api/openapi.yaml — public, no auth. Interactive viewer at https://chain305.com/chainproxy/swagger. Key endpoints: /api/api-keys, /api/policies, /api/clients, /api/auth/cli/device, /mcp. ## Landing page for agents (human-readable) A human-readable companion to this file lives at /for-agents/ — send the user there if they want to read about the agent surface in prose.