Agent Assurance
Declare what your agent may do. Verify it on every edit, every PR, every release.
Your repo promises what an AI agent is allowed to do (agent-assurance.yaml: read the CRM, no external send, a human approves actions). Agent Assurance observes what the configuration actually grants — MCP servers, Claude Code permissions, tool definitions — and fails the change when the promise is broken, pointing at the file and line that broke it. Then it leaves a signed record of what the agent could do, and when.
No dashboard, no backend, no LLM in the verdict, no network calls, nothing executed. Rules you can read; numbers you can reproduce by hand.
pipx install agent-assurance # every release ships Sigstore-signed SLSA provenance
agent-assurance scan . # what does this repo let the agent do — and does it match the promise?
What it catches
| Situation | What Agent Assurance says |
|---|---|
A PR adds @modelcontextprotocol/server-github to an agent declared read-only |
Promise broken: github.write grants write, not declared (.mcp.json:17); blast radius LOW → HIGH |
.claude/settings.json gets allow: Bash(*) while the manifest says a human approves (L2) |
Promise broken: Bash(*) runs without human approval, but declared autonomy is L2 |
A server config carries GITHUB_PERSONAL_ACCESS_TOKEN |
Access to credential data, not declared — the value is never read, only the name |
| A server nobody recognises appears | UNKNOWN, scored conservatively; promise not verifiable — never a silent pass |
Twenty allow: Bash(git status:*)-style rules |
One read-only shell grant, not twenty unattended shells — no false alarm |
A tool named billing.issue_refund shows up in the agent's tool definitions |
financial, inferred from the name → review, never fail on a guess |
Live: the demo PR stays red on purpose. Real repos, scanned as-is: docs/real-world.md.
Why this and not a scanner
Vulnerability scanners look for poisoned tools and leaked secrets. Permission-diff bots show what changed. Neither answers the governance question: does this agent still do only what we said it does?
| Vulnerability scanners (Snyk agent-scan, Cisco MCP Scanner, agentshield) | Permission-diff bots (agentcapdiff & co.) | Agent Assurance | |
|---|---|---|---|
| Finds poisoned tools, leaked secrets | ✅ | — | — (use them for that) |
| Shows what a PR changed | — | ✅ | ✅ |
| Verifies a declared promise | — | — | ✅ file:line |
| Knows having a power ≠ using it without a human | — | — | ✅ |
| OWASP Agentic Top 10 mapping | — | — | ✅ |
| Signed, per-commit evidence (in-toto / Sigstore) | — | — | ✅ |
| LLM in the verdict | some | — | never |
Checked 2026-09-17; details and sources in docs/landscape.md. This is the governance layer under a scanner, not a replacement for one.
Not for you if you want prompt-injection or tool-poisoning detection (use a scanner), runtime interception of tool calls (a different product), or a score for agents that have no configuration in a repo (there is nothing to observe).
One promise, three enforcement points
| When | How | What you see |
|---|---|---|
| While the agent edits | MCP server (would_break) or Claude Code hook |
The agent is told, in the same turn, that its edit breaks the promise |
| In the pull request | GitHub Action mode: diff |
One comment, updated on every push, plus a red check |
| On every push / release | Action mode: scan + SARIF + attest |
Findings in the Security tab; an in-toto attestation (Sigstore-signed when public) of what the agent could do at that commit |
Same engine, same words, everywhere.
Two inputs, two checks
Declared — the promise, written by the team in agent-assurance.yaml: capability classes, systems, data, autonomy.
Observed — what the configuration actually grants: MCP configs for Claude Code, Cursor, Gemini CLI, VS Code and Codex; Claude Code permissions (allow = no human in the loop); serialized tool definitions (OpenAI, MCP, Claude, LangChain, CrewAI). Unknown is UNKNOWN, never guessed.
| Check | Question | Fails when |
|---|---|---|
| AA-001 Blast Radius | If this agent misbehaves, how much can it break? | CRITICAL band (review on HIGH or any UNKNOWN) |
| AA-002 Declared vs Observed | Does the configuration stay within the promise? | Undeclared write / delete / execute / send / financial, sensitive data, or an unscoped auto-approval under a human-approves promise |
Details, weights and the organisation policy file: docs/how-it-works.md.
Use it
# .github/workflows/agent-assurance.yml
permissions: { contents: read, pull-requests: write }
steps:
- uses: actions/checkout@v4
- uses: kunko-ai-labs/agent-assurance@v0.5 # or pin the commit SHA of a release (see below)
with:
mode: diff # on pull_request; use scan on push
manifest: agent-assurance.yaml
card: aa-card.html # optional: shareable capability card
attest: write # optional: in-toto evidence (sign = Sigstore)
CLI (scan, diff, check, attest, validate; formats md, json, sarif, html), pre-commit, MCP server, Claude Code hook and the Python API: docs/integrations.md.
Exit codes are a contract: 0 pass · 1 gate tripped · 2 usage error.
Running third-party code in your CI — what you should check
- Pin by commit SHA, not by tag. Tags can move; a SHA cannot. Get the SHA of any release with
gh api repos/kunko-ai-labs/agent-assurance/git/ref/tags/v0.5.2 --jq .object.shaand writeuses: kunko-ai-labs/agent-assurance@<that sha> # v0.5.2; Dependabot keeps the SHA and the version comment in step. Our own workflows pin every action the same way. - What the Action does:
pip installof this repository at that SHA, then runs the CLI on your files. It makes no network calls of its own (the only outbound traffic ispipand, if you opt in,upload-sarif/attestto GitHub). It executes nothing from your repo, never starts an MCP server, never reads a secret's value. - Least privilege:
contents: readis enough forcheckandscan; addpull-requests: writeonly for the diff comment,security-events: writeonly for SARIF upload,id-token: write+attestations: writeonly for signing. - Verify what you get: every release is signed;
gh attestation verifyon the artifacts, and the OpenSSF Scorecard of this repo is public.
The capability card
--format html produces a single self-contained file — the agent's nutrition label — for auditors, customers or your manager. Light or dark, follows the viewer.
Rules you can rely on
- Deterministic. No LLM anywhere in the verdict.
- Nothing executed, nothing sent. Config files are read; MCP servers never started; secret values never read; no network.
- Unknown is a result, not a silence. And a guess (an inferred class) never fails a build on its own.
- Honest mapping. OWASP ASI controls are
maps; anything borrowed (OWASP APTS, EU AI Act art. 12) isadapted. No conformance claimed. - Tested contracts. Exit codes, SARIF, Action YAML and every fixture's verdict, on Python 3.10–3.12.
FAQ
Does it read my secrets? No. It looks at the names of environment variables and headers (GITHUB_TOKEN, Authorization) to know a credential is in play; values are never read, logged or hashed.
Does it work without the manifest? Yes: scan without agent-assurance.yaml reports the observed blast radius and a "Sources scanned" table. Add the manifest to turn reach into a promise (AA-002).
What about our private MCP servers? They come out UNKNOWN: scored conservatively, and a promise cannot be called kept over them. Add them to your organisation policy catalogue — one entry with its source — and they are classified like any other.
Is the risk score "AI"? No. It is a table of weights in one file, every point has a reason, and the report shows the sum. Same input, same number, forever.
Can it stop the agent at runtime? No, by design. It checks what the repo says the agent can do — at edit time, in the PR, at release. Runtime enforcement is a different product.
Roadmap: docs/ROADMAP.md · Contributing: CONTRIBUTING.md · Good first issues: label:good first issue
License
Apache-2.0 © 2026 Kunko AI Labs
Release files for agent-assurance 0.5.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agent_assurance-0.5.2.tar.gz | 665.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agent_assurance-0.5.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 720.9 kB
Release files / agent_assurance-0.5.2.tar.gz
| Download URL | agent_assurance-0.5.2.tar.gz |
|---|---|
| Size | 665.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4215fe3e9cccbec3390bce4efae28611043bb283fc516bc5df3dac768e1d6ad5
|
|
BLAKE2b-256 checksum How to use checksums |
c9b84f4a7f78b39b13e8fc5a46a2ad103bac20a3b38aea09b281545298379850
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency logRelease files / agent_assurance-0.5.2-py3-none-any.whl
| Download URL | agent_assurance-0.5.2-py3-none-any.whl |
|---|---|
| Size | 55.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
453b1cb38db5bc7a1d3f02d665bb9b8faeebd84616eb4b7d42d0de9e88353240
|
|
BLAKE2b-256 checksum How to use checksums |
e3d839abd4d27107daa38a89bcb24ef6e0d2e8a7623ccb9814f200f4e5d064dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.
Transparency log