Skip to main content

downscope

Least-privilege audit for Claude Code permissions — derived from what your agent actually does, not from what you guessed it needs.

Your ~/.claude/projects directory already records every tool call your agent ever made. downscope reads that history together with your merged permission settings (user / project / local layers) and answers the questions nobody can answer by hand:

  • USED — which allow rules your sessions actually exercised (counts + last-seen dates)
  • UNUSED — which grants are dead weight and can be tightened
  • MISSING — which commands you approve by hand all the time and deserve a rule
  • RISK — ~30 deterministic checks over both your config (wildcard Bash allows, secrets-adjacent grants, bypassPermissions) and your observed history (curl | sh, sudo, force-pushes, exfiltration patterns)
  • MCP — which configured MCP servers are actually used, and which are dead surface

Privacy: reads local files only. Zero network calls. Nothing leaves your machine.

downscope audit demo

(demo generated from a synthetic corpus — regenerate with python docs/make_demo.py)

Commands

downscope audit

The core command. Scans all local transcripts + settings and prints the coverage matrix, suggestions and risk findings.

downscope audit                        # terminal report
downscope audit --json                 # machine-readable, valid JSON on stdout
downscope audit --html report.html     # self-contained HTML report (zero external assets)
downscope audit --emit-policy min.json # proposed minimal policy (reviewable fragment)
downscope audit --save-snapshot a.json # snapshot for later drift diffing
downscope audit --project-root .       # include this repo's .claude/settings*.json + .mcp.json

The emitted policy is deliberately conservative: used grants are kept, unused grants are demoted to ask (never silently denied), frequent-but-safe patterns are promoted, interpreters (python, node, …) and anything already under ask/deny are never auto-promoted, and a small deny pack covers secrets paths and privilege escalation.

downscope check — CI gate

Fails the build when a repo's committed .claude/settings.json is risky or drifts from a team baseline:

downscope check --project-root . --baseline team-baseline.json --fail-on high

Exit codes: 0 clean, 1 violations, 2 usage error. GitHub Actions snippet:

- name: Check agent permissions
  run: |
    pip install downscope
    downscope check --project-root . --baseline .claude/team-baseline.json

downscope diff — drift over time

downscope audit --save-snapshot before.json
# ... a week of sessions later ...
downscope audit --save-snapshot after.json
downscope diff before.json after.json

Shows rules added/removed, usage drift, new and resolved risk findings, and newly frequent uncovered commands.

How it differs from Claude Code's built-in /fewer-permission-prompts

/fewer-permission-prompts downscope
Adds read-only allows from history yes no (by design)
Finds unused grants no yes
Risk-scores config + history no ~30 deterministic rules
Emits minimal policy (shrink) no yes, reviewable
CI gate against a baseline no yes
Drift diffing over time no yes
MCP surface audit no yes

The built-in skill reduces prompt fatigue by adding allows. downscope is the missing other half: the audit layer that shrinks, risk-scores and enforces. Use both.

How matching works (the two hard parts)

  1. Settings-layer semantics. Rules are matched with Claude Code's documented semantics: Bash glob forms (git commit *, :* word-boundary sugar), settings-source path anchoring (/src/** vs //abs/path vs ~/…), WebFetch domain rules (*.example.com vs apex), MCP server globs, and layer provenance (user / project / local).
  2. Chain-aware coverage. A chained command (a && b | c) is only auto-approved when every link is covered, so coverage is decided per segment — with a quote-aware splitter that understands heredocs, comments, redirections and line continuations. Suggestions are generated only from the uncovered links.

Both parts are pinned by a fixture corpus and property-based tests (Hypothesis).

Install (development)

git clone https://github.com/bogdancolceriu/downscope && cd downscope
python -m venv .venv
# Windows: .venv\Scripts\activate    POSIX: source .venv/bin/activate
pip install -e ".[dev]"
pytest -q && downscope audit

Tested on Windows, macOS and Linux via CI. Compatibility: transcript formats are undocumented internals; the parser skips unknown records gracefully and the fixture corpus pins the formats seen in Claude Code 2026 releases.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

downscope-0.1.0.tar.gz (50.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

downscope-0.1.0-py3-none-any.whl (38.5 kB view details)

Uploaded Python 3

File details

Details for the file downscope-0.1.0.tar.gz.

File metadata

  • Download URL: downscope-0.1.0.tar.gz
  • Upload date:
  • Size: 50.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for downscope-0.1.0.tar.gz
Algorithm Hash digest
SHA256 336334697a2cd484af818843cf62c5ef7748cbff3fa46cf13db1ddfb05119d79
MD5 a9061f843308028f33badffbdf77e6ba
BLAKE2b-256 5459156589bec17eb7a921f751c370e5a599d31b4f17bdfb80d64a833d61de1a

See more details on using hashes here.

Provenance

The following attestation bundles were made for downscope-0.1.0.tar.gz:

Publisher: release.yml on bogdancolceriu/Downscope

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file downscope-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: downscope-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 38.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for downscope-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 472ad23c3149bb157e41a15d57d438d04752ca4fe9dab779ae8fd3ef33937718
MD5 9f0afdeb40bedeaa79f1c80155f0f9b4
BLAKE2b-256 8afd6c98ba9eaff822076b9e515b6255b75892cc0688880b6a5f03f47665c672

See more details on using hashes here.

Provenance

The following attestation bundles were made for downscope-0.1.0-py3-none-any.whl:

Publisher: release.yml on bogdancolceriu/Downscope

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page