AGENTEGRITY_TOKEN and AGENTEGRITY_EXPORTER_URL.
What it does
The plugin registerspython3 -m agentegrity hook --host claude-code on nine Claude Code hook events: PreToolUse, PostToolUse, PostToolUseFailure, UserPromptSubmit, Stop, SubagentStart, SubagentStop, PreCompact and SessionEnd. Claude Code starts a new process for every hook, so the first hook of a session starts a small daemon that holds the session’s state. Every later hook forwards its payload to that daemon, and the layers see the whole conversation in order instead of one call at a time.
A PreToolUse verdict maps to Claude Code’s permission decision: block becomes deny, escalate becomes ask (an approval prompt), and everything else stays silent so Claude Code’s normal permission flow decides. What the runtime checks:
- Argument classification. Shell commands are tokenized the way the shell reads them. A downloaded or decoded payload piped into an interpreter, or deleting logs and shell history, is denied. Commands computed at runtime (
$IFSsplicing, computed executables) ask. - Sensitive-data egress (GOV-005). An external send after a secret was read anywhere in the session, or in the same command, asks. Reading a secret alone is allowed and recorded.
- Output scanning. Injection found in anything a tool returns lowers the score until the context is compacted.
- Written content. Text written into files by
Write,Editand multi-editeditsis scanned for instructions, since a file is how an injection persists across sessions. A strong finding asks; a finding that blocks denies. - Governance. Sensitive tool names are gated and the match is MCP-aware: an entry for
file_deletealso gatesmcp__filesystem__file_delete. - Behavioral drift. Each session that ends without a
blockorescalateteaches a per-agent baseline in<hook dir>/claude-code/baselines/. Later sessions whose tool mix departs from it lower the score and alert. Drift never blocks here. - Token usage. Read from the session transcript and each subagent’s transcript at every
Stopand at session end, normalized and totalled per model, and sent onstopevents and in the session summary. Only usage counts and model names are kept from the transcript. - Decision chain. Every evaluation and a
hook_verdictdecision for every non-allow verdict are appended to<hook dir>/claude-code/<session>.chain.json, written atomically with mode 0600 and resumed if the daemon restarts.
<hook dir>/keys/hook.key (mode 0600), and writes the public key beside it as hook.pub, which is what --trusted-key takes. Set AGENTEGRITY_SIGNING_KEY_FILE to use your own key. Signing needs the [crypto] extra; without it, or with a key file others can read, chains stay unsigned and the hook keeps working. The key sits on the same machine and under the same user as the agent, so a signature shows the chain was not changed afterward by someone without the key; it does not stop a process running as you from signing a forged one. See Attestation.
Install
Install the library so that thepython3 on your PATH can import it:
/agentegrity-status to check the wiring. It reports whether the library is importable, the mode, whether console streaming is on, the chain directory, and record and decision counts for up to five chain files in that directory. It also warns about legacy AGENTEGRITY_CC_* variables, which are ignored.
The plugin version (0.13.0) matches the library release it needs. If the hook command fails because the library is missing or older than 0.11.0, the plugin prints a system message saying the action was not checked, and the action goes through.
Wiring the hook without the plugin
The plugin’shooks/hooks.json uses the standard hook format, so you can register the same command in a Claude Code settings file (for example ~/.claude/settings.json) instead. Register it on all nine events; a partial set loses failures, subagent boundaries or the session end. Two of the entries:
"matcher": "*" on PreToolUse, PostToolUse and PostToolUseFailure, no matcher on the other events, a 20 second timeout everywhere except SessionEnd (5 seconds), and appends || echo '{"systemMessage": ...}' to each command so a missing library produces a warning. Copy those details from the plugin’s file.
Configuration
All variables are optional and shared with the Codex plugin. The runtime reads them from the hook’s environment, which is the environment Claude Code runs in.
An agent id that is not safe as a file name keeps its drift baseline in memory for that session only.
Stream sessions to a console
Set the token and URL in the environment Claude Code starts from. The daemon inherits that environment and attaches the built-inHTTPExporter, which sends the session start, every event, and the session summary when the session ends (SessionEnd, or the idle timeout):
agentegrity pro does the same for one command after checking the token against the console:
exporters. Only the daemon streams: when the runtime falls back to in-process evaluation (below), nothing is sent. See Agentegrity Pro and Data flows.
Failure semantics
The hook never breaks a session. When it cannot reach a verdict it prints nothing, which leaves the decision to Claude Code’s permission flow.Migrating from 0.1
The per-callhooks/pretooluse.py is replaced by the shared runtime.
- Environment variables were renamed:
AGENTEGRITY_CC_MODEis nowAGENTEGRITY_HOOK_MODE,AGENTEGRITY_CC_DISABLEDisAGENTEGRITY_HOOK_DISABLED,AGENTEGRITY_CC_RISK_TIERisAGENTEGRITY_RISK_TIER, andAGENTEGRITY_CC_CHAIN_DIRis replaced byAGENTEGRITY_HOOK_DIR(chains now live under<dir>/claude-code).
- Commands are no longer text-scanned. A bare
cat ~/.aws/credentialsused to be denied; it is now allowed and recorded, and sending the data out afterwards asks. - Existing chain files are resumed, not replaced.

