actrail SDK connects your agent to Actrail: it records each action (metadata only),
registers with Actrail so your managed policies install, and checks actions against
those policies. It works with Claude Code out of the box.
Requirements
- Python 3.11 or 3.12. The system Python on macOS is 3.9 and won’t work — use a
3.11/3.12 environment (e.g.
uv venv --python 3.12). - macOS (Apple Silicon) or Linux (x86_64). On other platforms, install the source distribution (needs a Go toolchain).
Install
PATH — the Claude Code hooks call actrail by
name. The command is a small launcher that runs python3 -m actrail.cli; with an isolated
install (pipx, uv tool, an inactive venv) point it at the right interpreter via
ACTRAIL_PYTHON (see the Quickstart troubleshooting).
Then connect your agent — see the Quickstart:
Upgrade
Upgrading is not justpip install --upgrade. The SDK runs a warm daemon
that keeps the old code loaded until you restart it, and each release can change the Claude
Code hooks and how it registers. Run all four steps, in the same environment you
installed into:
1
Upgrade the package
actrail==1.1.1.2
Re-connect
init re-registers the SDK (refreshing which managed policies are available)
and upgrades Actrail’s Claude Code hooks in place — it never touches your other hooks.3
Restart the daemon
4
Verify
Start a new Claude Code session after upgrading. Claude reads
.claude/settings.json
at session start, so refreshed hooks apply to new sessions.Commands
actrail init
--global→ your user-level~/.claude/settings.json— governs every Claude Code session on the machine. Recommended for a personal setup.- default (no
--global) → the current directory’s./.claude/settings.json— governs that project only. Run it from the repo you want to cover.
A registration hiccup never blocks setup — it defers with a note, and re-running
init
re-projects your policies. If the line reads “not certified for managed policies”, you’re
on an older SDK than Actrail certifies — upgrade and re-run init.actrail status
actrail doctor
hooks: ok (<scope>)— where the live install is:global,project, orproject + global.DISABLEDmeans the hooks are wired but adisableAllHooks/ managed setting stops them from running.managed:— the enterprise-managed layer. A CLI can read managed settings files andmanaged-settings.ddrop-ins, but not MDM/registry/server-pushed policy, so it reports that layer as inspected-or-unverified rather than certifying it.
actrail enforce
--global / -g to toggle the enforce hook in your user-level settings instead of the
current project. enforce off warns if another scope still has the hook, so it never reads
as “off” while a global hook keeps enforcement active.
Whether an action is actually blocked depends on the matching policy’s mode in the
console (shadow vs. enforce).
enforce on just means the agent asks.actrail restart
actrail login
~/.actrail/config.toml (without registering, wiring hooks, or
starting the daemon).
Configuration
Config lives at~/.actrail/config.toml (permissions 0600). actrail init writes it
for you; you can also edit it directly (then actrail restart).
Environment variables
Override the file withACTRAIL_KEY, ACTRAIL_AGENT, and ACTRAIL_ENDPOINT. Precedence,
low to high: defaults → config file → environment → command flags.
How it works with Claude Code
Registration
Registration
On
init the SDK tells Actrail which release it is (integration, version, contract
— no customer data). Actrail certifies the release and installs the managed policies
it can enforce. This is why your console has rules before the first trail — and why an
uncertified SDK sees none until you upgrade.Hooks
Hooks
init writes hooks to ~/.claude/settings.json with --global (every session) or to
the project’s ./.claude/settings.json without it — Claude Code merges both, plus local
and managed settings. Existing hooks you have are preserved.- PostToolUse / PostToolUseFailure → captures each action (success and failure) after it runs.
- PreToolUse → checks an action against policy before it runs (added by
enforce on). - SessionEnd → closes the trail so detection runs promptly.
init — see the Claude Code docs.The daemon
The daemon
A small background process holds a warm client (scanners stay loaded), so per-action
overhead stays low. It starts on
init (or on the first hook) and is managed with
actrail status / restart.Agent identity
Agent identity
Each action is attributed to
claude-code@<host>@<project> by default, so the
console can tell your agents apart. Override it with actrail init --agent <id>.Shadow vs. enforce
- Shadow (default) — actions are captured and evaluated; a matching policy reports what it would block, but nothing is blocked.
- Enforce — a matching
deny/require approvalpolicy actually stops the action.
actrail enforce on|off
controls whether the agent consults policy at all.