Coding agent security
Govern Claude Code, Cursor, Codex, and Copilot CLI with a local hook that blocks dangerous tool calls and mints a signed, offline-verifiable Coding Session Seal.
@axiorank/coding-guard governs AI coding agents the way AxioRank governs production
agents. It installs as a hook into Claude Code, Cursor, OpenAI Codex CLI, and
GitHub Copilot CLI. On every tool-call lifecycle event the agent hands the action to the
guard, which scores it with the same AxioRank detection engine the hosted gateway runs and
answers allow, deny, or ask in the agent's own response format.
It blocks the actions you do not want an autonomous agent taking on your machine:
- destructive commands (
rm -rf,git push --force,DROP TABLE,curl ... | sh) - secret exfiltration (a command or file write that ships an API key, token, or
.env) - prompt-injected tool results (a poisoned MCP reply or fetched page steering the agent)
Local blocking runs fully offline with no API key and no signup. Add a key and the guard also reports the session centrally and mints a signed Coding Session Seal.
Install
Run this in your repo. It merges a hook entry into each agent's config, idempotently:
- Claude Code:
.claude/settings.json - Codex:
.codex/hooks.json - Cursor:
.cursor/hooks.json - GitHub Copilot CLI:
.github/hooks/copilot-cli-policy.json
npx -y @axiorank/coding-guard initEach command carries an explicit --agent flag. Codex uses the same hooks.json event
schema as Claude Code (PascalCase events, hookSpecificOutput responses), so the flag is
what keeps a Codex session labeled as Codex rather than Claude Code. Copilot's payload does
not name the event, so its commands also pass --event. Prefer to paste the config yourself?
npx -y @axiorank/coding-guard printHow it decides
The guard normalizes each agent's tool event (a shell command, a file edit, a file read,
an MCP call) onto AxioRank's tool-call vocabulary, then runs scoreToolCall from
@axiorank/detectors. It applies the default posture: deny on a live secret, deny on a
destructive operation, deny at risk 75 or above, and ask for review in the 50 to 74 band.
- A
denyblocks the call and returns the reason to the agent. - An
askprompts you in the editor. - Everything else proceeds, and the guard stays silent so your own permission rules still apply.
The guard is fail-open: a crash, a malformed event, or an unreachable gateway never
blocks your editor. Security tightening comes from explicit deny verdicts, not from the
guard failing closed.
Central reporting and the Coding Session Seal
Set an API key and the guard reports each governed call to your workspace:
export AXIORANK_API_KEY="axr_live_..."Now sessions appear under Coding Sessions in the dashboard, raise alerts on high-risk activity, and apply your workspace policy. The central decision can only tighten the local one (your org policy adds rules the local default does not know about); it never loosens a local block.
When the agent finishes, the guard mints a Coding Session Seal: an Ed25519-signed,
offline-verifiable attestation of how many tool calls were governed, how many were blocked,
which detector categories fired, and a Merkle root over the session's audit log. It is
written to <repo>/.axiorank/session-<id>.seal.json.
Session seals require the Team plan or higher. Local blocking is always free.
Verify a seal offline
Anyone can verify a seal against AxioRank's published key, with no trust in AxioRank and no network beyond fetching the key once:
npx -y @axiorank/audit-verify coding-seal .axiorank/session-*.seal.jsonPass --jwks with a key you pinned out of band for the fully independent path. This is the
provenance record for AI-written code: a portable proof that the session was governed, which
you can keep in CI artifacts or attach to a pull request.
Configuration
| Env var | Default | Purpose |
|---|---|---|
AXIORANK_API_KEY | unset | Report sessions centrally and mint seals. Unset means local-only. |
AXIORANK_BASE_URL | https://app.axiorank.com | Your AxioRank deployment. |
AXIORANK_CODING_GUARD_TIMEOUT_MS | 2500 | Timeout for the central call (fails open on timeout). |
AXIORANK_CODING_GUARD_DISABLE_REMOTE | unset | Force local-only mode even with a key set. |
What never leaves your machine
The detectors redact secrets in place, so only the redacted payload is ever reported, exactly like the SDK. Seal leaves are one-way row hashes, not payloads. Local-only mode (no key) sends nothing at all.