How it works
- A policy rule matches an agent tool call and returns
require_approval. - The Guard hook keeps the tool call waiting and sends an approval request to Guard Cloud from the enrolled device.
- An administrator approves or denies it in the Console.
- The hook consumes the approval once and lets that one action run.
The hook waits at most 10 seconds in total. Anything other than a valid, live, one-time approval of the exact action denies it: a timeout, a network error, a denial, an expired request, a changed input or a repeated use.
The request carries only digests of the harness session and the exact action (tool name, working directory and tool input). Raw tool input, prompts, commands, paths and secrets are never sent.
Policy decisions
Response rules use a versioned decision object:
{"version": 2, "verb": "require_approval"}
| Verb | Effect |
|---|---|
notify |
Warns through the harness. Denies where no reliable notification channel exists (Copilot, generic Cursor pre-tool hooks). |
deny |
Always blocks. |
require_approval |
Waits for an exact, one-time approval. |
modify |
Redacts detected secrets from Claude Code Write content. Denies everywhere else. |
quarantine |
Denies the current call and every later call in that exact session, across restarts, until released locally. |
The older warn, ask and block strings still work unchanged. An older Guard build rejects version 2 objects rather than treating them as warnings.
Harness support
| Harness | Approval | modify |
Quarantine |
|---|---|---|---|
| Claude Code | Yes | Write content only |
Exact session |
| Codex | Yes | Deny | Exact session |
| Cursor | Yes | Deny | Exact conversation |
| Gemini CLI | Yes | Deny | Exact session |
| Windsurf | Yes | Deny | Exact trajectory |
| Cline | Yes | Deny | Exact task |
| Copilot | Deny | Deny | Deny |
Copilot hooks have no stable session identity, so approval and quarantine deny.
Warning: These hook paths are tested with real Guard processes, not yet in live sessions of every vendor release. Check what your installed version supports with
guard approval capabilities HARNESS.
Deciding in the Console
The approval queue lists requests newest first. Filter by state, device, harness and time.
| State | Meaning |
|---|---|
pending |
Undecided and still live |
decided |
Approved, denied or consumed |
expired |
Not decided in time |
Any Console role can view the queue. Only an administrator can decide. A decision needs:
- approve or deny;
- the reviewed action digest;
- a reason of 1 to 200 bytes;
- optionally, a shorter approval window of 1 to 300 seconds.
Rules for decisions:
- Each approval covers one exact action, used once. A changed input needs a new request.
- Decisions can't be changed. An identical retry returns the recorded decision.
- With SSO and a device bound to a directory identity, that person can't approve their own device's requests. Another administrator must.
- There is no two-person rule for action approvals.
- Each decision is written to the audit log as
approval.approveorapproval.deny.
Automation can decide with an organization machine-administrator key through POST /v1/admin/approvals/decide. Never put that key on an endpoint.
Audit on the device
Guard records every response decision before it allows or modifies an action. If it can't record it, it denies the action. The record holds metadata only and reaches Guard Cloud through the signed device channel. It records the decision, not proof that the vendor ran the tool.
Managed Linux hooks
By default, the device user controls Guard's enrollment, policy and state, so they could point the hook at their own server. On Linux, administrators can pin the authority instead:
guard --managed-endpoint claude-tool-hook
The global flag must come first. The same applies to the Codex, Copilot, Cursor, Gemini, Windsurf and Cline tool-hook commands.
- The root-owned
/etc/runeward/collector.jsonpins the user's enrollment and server. - An optional
managed_catalogentry pins the policy (path,sha256,public_key). - Managed approvals require HTTPS, even on loopback. A self-hosted private CA can be pinned with
approval_ca: {path, sha256}. - Any missing or changed pin denies. Managed mode is Linux only; elsewhere it denies.
Limits
- A harness that kills, skips or removes the hook can ignore its result. Missing hooks and already-running tools are outside enforcement.
- Some harnesses fail open. Gemini CLI and Copilot CLI run the action when a hook times out or returns malformed output. Hook deadlines installed by older versions were five seconds: run
guard hooks repairto update them. - Cline ignores failed or timed-out hooks. Set Cline's hook timeout above Guard's 10-second budget plus start-up time, and test it.
- Where tool output already reached the model, Guard can only block or warn; it can't undo the exposure.
- Quarantine does not kill processes or end the session in the vendor's tool.
- The local
guard approvalapprove and deny commands are user-owned and never authorize a hook. Only a Cloud approval does.
Written from docs/action-approvals.md, docs/cloud-approvals.md at commit fb79778d02f0. Rune Guard is in early access.