Claude Code
Two commands on the developer's machine. After that every tool call Claude Code makes is decided by your workspace policy before it runs.
Quickstart
Install the collector, sign in to mint this machine's install key, then install the hooks:
curl -fsSL https://get.trefur.com/collector | sh
trefur claude-code login --email you@company.com --workspace "Acme"
trefur claude-code install-hookslogin creates the workspace through your browser (or a device code with --no-browser) and writes the install key to ~/.trefur/install-key-claude_code. Joining a workspace that already exists: trefur claude-code login --api-key <your platform key>. The collector runs on that key alone; no collector key is needed for a developer machine.
trefur claude-code install-hooks writes the hook entries into ~/.claude/settings.json (or the project's .claude/settings.json with --scope project). Operator hooks you already had are preserved; uninstall-hooks removes only the Trefur ones.
The install key's life
- Short-lived, renewed by the collector. The key lasts as long as your workspace's renewal lifetime (seven days by default). The running collector renews it ahead of expiry, for as long as the install remains in good standing under your workspace's policy.
- Refused renewals are visible, not silent. When a renewal is refused, the key keeps working until it expires,
trefur claude-code statusshows why, and a person signs in again withlogin. - Revocation reaches the hook within seconds. The collector keeps a bounded watch open on the key; when the workspace revokes it or engages the install kill switch, the next tool call is denied with the reason. The one-shot hook reads the same record, so this holds even when the daemon is not running.
- Offline. If the key has not been confirmed live for
enforcement.credential_max_age_seconds(an hour by default; 0 disables the check), the fail mode below decides.
What happens on each tool call
- Claude Code runs the pre-tool hook:
trefur claude-code emit-event --decide. - The collector daemon, if running, answers from the live policy. If it is not, the command decides from the policy bundle persisted on the machine, which must carry a valid signature, be addressed to your workspace, and be no older than the configured age.
- Exit code 0 lets the call run; exit code 2 denies it and Claude Code shows the reason. The observation is forwarded either way.
- After the call, the post-tool hook records the result. The transcript tailer adds what the hooks did not see, without duplicating the call.
When a policy requires a person
A policy can mark a tool call as needing a human's approval. The hook cannot wait for a person, so the call is denied at once with the request id, the collector records an approval request bound to that exact call (server, tool, arguments and your install's identity), and the request appears in Trefur on the Fleet page, at the top, with Approve and Deny beside it. Once a person approves it, retrying the same call runs it, once. A changed argument is a different call and records a new request; a denial stands for the request's validity (an hour by default), and an approval that was never used expires with it. The running collector does the recording; with only the one-shot hook the call is denied and the message says to start it.
Fail modes
The hook's fail mode is closed unless you set enforcement.hook_fail_mode: open in the collector config.
- closed (default): no daemon and no valid bundle means the call is denied with the reason policy unavailable. Unsigned, tampered, wrong-workspace or stale bundles are refused the same way.
- open: the same situation allows the call and records that it was allowed without a policy, so the gap is visible in the platform rather than silent.
Managed rollout (fleet)
For a fleet, write the organisation-managed settings file instead of each user's settings. Claude Code reads it ahead of user settings.
sudo trefur claude-code install-hooks --managed --api-host https://api.trefur.com- macOS:
/Library/Application Support/ClaudeCode/ - Linux:
/etc/claude-code/ - Windows:
C:\ProgramData\ClaudeCode\
--managed-out writes the file somewhere else (for your MDM to ship). The file carries the hooks and the telemetry environment for Claude Code's own OpenTelemetry export, pointed at your API host.
What is captured, and what is not
- Captured: the tool name, the arguments the policy needs (paths, commands, URLs), the verdict and its source, the session and the install identity, timings. Web fetches and searches are recorded as network connections.
- Never captured: your hostname or username in the clear (the install identity is a hash), and file contents beyond what the policy inspects.
- Credentials, on a best-effort basis. Before an event leaves the machine the collector masks the value of any argument or environment assignment whose name says it is a secret —
--password,--token,--api-key,Authorization:,*_SECRET=and the like — and removes tokens matching a list of well-known issuer formats. That is pattern matching, not a general secret detector: a credential in a house format, or one passed as a bare positional argument, can reach the platform as content, where your redaction setting decides what happens to it. Trefur applies a wider set of credential formats again on arrival. Treat this as a safety net, not a guarantee, and do not pass secrets on command lines. - Redacted by default: prompts and command lines are content. They are redacted before storage unless your workspace opts a key into full content; see configuration.
Which binary
The trefur command in this guide is the collector binary. It is the one you install from get.trefur.com and the one the hooks call; it is not the same program as the platform's administrative CLI.