TL;DR
- Claude Code ships a hook system (
PreToolUse,PostToolUse,UserPromptSubmit) that lets external code intercept every tool call before it executes. Stratium ships@stratium/claude-hooks, a Node CLI that wires those hooks to a Stratium Agent Gateway. - The result: every Claude Code tool call on every developer machine in the fleet is identified, delegated, authorized, and audited — with zero changes to any project codebase. Policy is set per project in
CLAUDE.mdand centrally via the Stratium PAP. - Default fail-closed: if the Stratium gateway is unreachable, tools don’t execute. Default read-only: new agents are capped at tier-1 (READ_ONLY) until an admin grants higher. Default auditable: every decision lands in
~/.claude/stratium-audit.jsonland on the platform’s audit stream.
Why Claude Code Is the Cleanest Surface for Agent Authorization Today
Most agent runtimes ask you to wrap tool calls in custom code. Claude Code doesn’t. It exposes three hook points that fire around every tool invocation, and the hooks can return a non-zero exit code to block the call. That’s a control point that doesn’t require modifying a single project repo.
UserPromptSubmit
Fires when a developer sends the first prompt of a session. Stratium uses this to authenticate the user against Keycloak, mint a delegation, and load the per-project policy from CLAUDE.md.
PreToolUse
Fires before every single tool call (Read, Write, Edit, Bash, Grep, Glob, etc.). Stratium calls ExecuteAction against the Agent Gateway. If the decision is DENY, the hook exits non-zero and Claude Code surfaces the reason inline to the developer.
PostToolUse
Fires after every successful tool call. Stratium uses this for audit logging only — never blocks. The audit record includes outcome, resource, agent identity, delegation ID.
That’s the entire integration surface. Three scripts in ~/.claude/settings.json. Every Claude Code session on every machine in your fleet now flows through Stratium.
The Reference Architecture
On the developer machine: three scripts wired into Claude Code’s hook system, plus a per-session state file at /tmp/stratium-session-<pid>.json that caches the delegation token. On the corporate side: a standard Stratium deployment with Agent Gateway, Platform Service, PAP, Keycloak, and an audit log.
The Whole Setup, on One Machine
For an individual developer or an evaluation environment, the install is three commands:
Configure writes ~/.claude/stratium.json (machine-level defaults), registers the hook scripts in ~/.claude/settings.json, and is done. Open Claude Code as normal — the next tool call is the first one under Stratium authorization.
Fleet Rollout via MDM
For an engineering org, individual installs don’t scale. Push the configuration via your existing endpoint management. The package supports Jamf, Intune, Workspace ONE, and any other MDM with a custom-script capability.
Pair that with a SSO-backed Keycloak realm and developers never see a separate login — the existing corporate identity is the agent’s delegator. The first prompt of each session prompts the hook to mint a fresh delegation, scoped to whatever the current project’s CLAUDE.md permits.
Per-Project Policy: Just a Block in CLAUDE.md
Projects declare what Claude Code is allowed to do in their own CLAUDE.md. Stratium reads the block on session start and uses it to scope the delegation. No external config file. No IDE plugin. The repo carries its own policy.
For projects that legitimately need more — CI maintenance, infrastructure work, scripted migrations — an admin can grant higher tiers per project, per tool. The tool_tiers map lets you cap most tools at READ_ONLY while permitting one specific tool to INTERNAL_MODIFY:
The decision happens at the gateway. The developer never has to think about it. The policy lives in the repo and travels with it.
What Each max_action_tier Actually Permits
The hook ships a default mapping from Claude Code’s built-in tools to Stratium’s five action tiers. The mapping is overridable per project but well-chosen by default.
REASONING (0)
No tool calls at all. Pure conversation with the model. Useful when a developer wants planning help without any side effects.
READ_ONLY (1)
Read, Grep, Glob, WebFetch, WebSearch. No side effects. The fleet default.
INTERNAL_MODIFY (2)
Write, Edit, Bash (non-network). Local file edits, local builds, local test runs. Tier-2 trust required.
EXTERNAL_COMMS (3)
Bash with curl / wget / ssh / git push / cloud CLIs. Anything that crosses the machine boundary outbound.
DESTRUCTIVE (4)
rm -rf, drop tables, force push to main, infrastructure deletes. Default-deny for everything below tier-3 agent trust. The places you can’t roll back from.
What a Developer Sees When a Call Is Blocked
The hook’s most important UX choice: when a tool is denied, Claude Code surfaces the reason inline as if it were any other tool error. The model continues reasoning with the denial as new context — usually deciding to ask the developer what to do.
The delegation ID gives the admin everything they need to inspect the chain in the PAP UI — what user, what agent, what scope, what hierarchy caps. The developer gets the change-request path. The admin gets the audit trail. No one gets blocked silently.
The Audit Stream
Every tool call — whether it succeeded or was blocked — generates a structured audit event. Two places to read it:
Local: ~/.claude/stratium-audit.jsonl
Every developer machine writes one JSONL line per tool invocation. Useful for incident response when the developer’s laptop has the only memory of what happened.
Central: Stratium Platform Audit Log
Every GetDecision call lands in the platform’s audit log with subject + agent + delegation + action + resource + decision + reason + evaluated policy + timestamp. Ship it to your SIEM via your existing log pipeline.
A representative line from the local log:
The Fail-Closed Default Is Load-Bearing
If the Stratium gateway is unreachable — corporate VPN dropped, network partition, gateway down — the hook fails closed by default and no tools execute. The developer sees an explicit error explaining why, not silent allow-through. That’s a configuration decision that matters; the alternative is exactly the “authentication passed, authorization didn’t” failure mode this whole platform exists to prevent.
fail_open is available for non-production environments. Don’t use it in production. The whole point is that the call doesn’t happen unless authorization succeeded.
Common Pitfalls When You Roll This Out
Setting fail_open “Just for the Pilot”
You will forget to flip it back. The default exists for a reason. Run the pilot with fail_closed from day one — the failure modes you discover are the ones you actually need to fix.
No stratium: Block in CLAUDE.md
Without a project block, the machine-level default applies (usually READ_ONLY, fail-closed). Developers will report “Claude is blocked from everything” on day one. Fix: ship a template CLAUDE.md with a sensible default block for your repos.
Sharing One Agent ID Across the Fleet
The whole compound-decision story requires each developer’s session to register against the same agent type but with the developer’s own delegation. Don’t share delegation tokens. Mint one per session.
Forgetting About PostToolUse
The audit hook is non-blocking, but it’s where the truth of what happened lives. If you skip it during the pilot, you have no incident-response surface when something does go wrong. Ship all three hooks together.
The 30-Day Rollout
One Developer, One Repo, Fail-Closed
Install @stratium/claude-hooks on one machine. Configure against a Stratium instance (Docker Compose is fine for the pilot). Add a stratium: block to one repo’s CLAUDE.md. Run a normal day’s work. Watch the audit log fill in.
Pilot Team Rollout
5–10 developers. Push install + configure via MDM. Standardize the CLAUDE.md block in 3–5 representative repos at different sensitivity levels. Track DENY counts — they tell you which projects need more capacity.
Policy Refinement and SIEM Wiring
Tune the policy library based on real pilot DENY traffic. Wire Stratium’s central audit log into your SIEM. Add Codex hooks (@stratium/codex-hooks) if your fleet uses both.
Fleet-Wide Default
Push to the rest of engineering via MDM. Make the stratium: block in CLAUDE.md a required template field for new repos. Every Claude Code session in the org now flows through Stratium.
See It Running
A 30-minute walkthrough: a real Claude Code session under @stratium/claude-hooks, a real DENY surfaced inline, the matching audit event in the platform stream, and a tour of the PAP UI where policy is administered. We bring the stack; you bring an idea of which agents on your fleet you’d most like to put under authorization first.
Book a Claude Code rollout walkthrough → Explore the Platform
Read Next
- Stratium, “Stratium in 90 Seconds: Compound Decisions for AI Agent Authorization” — the platform this rolls out against.
- Stratium, “Defense in Depth Needs a Floor” — why a hook in the runtime beats per-tool enforcement.
- Stratium, “Agents Are Showing Up in Places You Can’t Roll Back” — the case for default-deny on destructive operations.
- Stratium, “Bearer Tokens Don’t Carry Intent” — the production-deletion failure mode this architecture prevents by construction.