All pages
Protect
Block, hold and contain
What happens when a rule fires: a refusal with a reason, a hold for a decision, a session locked down or restricted with Safely, or a machine quarantined.
Golem responds at three sizes. A rule acts on one call: it lets it through with a warning, refuses it, or holds it for a decision. A session can be locked down or restricted, so everything after a bad moment runs with less. A machine can be quarantined, so every session on it does. All of them are reversible by a person, and none of them can be loosened from inside the session they restrict.
A refused call#
A refusal always says which rule refused it, carries a decision id, and says that trying again will not help, so the agent can tell its user what happened instead of retrying into a wall.
In a hook#
The client's own hook refuses the call before it runs. In Claude Code the agent sees:
blocked by Golem policy (rule "no-force-push-to-main", decision gd_3f9a1c07b2e4d815). Trying again won't change this. If it's a false positive, the user can ask the security team for an exception: golem exception gd_3f9a1c07b2e4d815 --reason "why".If the rule has a Message to the agent, it follows the rule's name. The decision id is gd_ and 16 hexadecimal characters. Cursor shows the same text to the user and the agent.
A call refused because it reaches an MCP server, tool or repository the workspace has not approved says so in whole sentences, with where an admin approves it:
Golem blocked this call: pastebin-upload is an MCP server this workspace has not approved. Tell the user; an admin can approve it in the Golem console under Security Inventory → MCP Servers. Decision gd_51e8a3c90f6d2b47. Trying again won't change this; if you need it, ask your security team and quote the decision id.Over MCP#
A call refused on Golem's MCP path never reaches the real server. The client gets a JSON-RPC error with code -32050, so it is not mistaken for a server fault and retried:
{
"jsonrpc": "2.0",
"id": 7,
"error": {
"code": -32050,
"message": "tool call blocked by Golem policy (rule \"no-prod-db-writes\", decision gd_9b04e2d61c7a35f8). Trying again won't change this. …",
"data": {
"effective_action": "block",
"rule_name": "no-prod-db-writes",
"decision_id": "gd_9b04e2d61c7a35f8",
"retryable": false
}
}
}A call a person or Golem's reviewer agent denied comes back the same way, with effective_action set to gate.
A call refused by Safely, a machine restriction or quarantine reads Golem Guarded against <tool>: <reason> instead. It has no decision id, and over MCP it uses code -32603.
Asking for an exception#
If a rule refused something it should not have, the user can ask for an exception from the same machine within 24 hours, quoting the decision id:
golem exception gd_3f9a1c07b2e4d815 --reason "release script needs this" --days 7--days is 1 to 90, 7 by default. --for chooses what it covers: any of machine, agent, repo and command; by default, that command or repository on this machine. The request waits in the console for an owner or admin to decide; a machine or an agent can never approve one. Once approved, the Golem agent lets matching calls through and records which exception did.
A held call#
A rule at Ask holds the call until someone decides. Who decides is part of the rule.
| Who decides | How it reaches them |
|---|---|
| The person at the keyboard | The client's own approval prompt, with held by Golem policy — approve to continue and the rule and decision id. Claude Code asks in every permission mode. |
| Your team | On Golem's MCP path, the call waits under Alerts → Review required → Awaiting approval, and as a Slack message with Approve 5m and Deny if you route alerts to Slack. |
| Golem's reviewer agent | It reads the held call: the tool, the server, the rule and its message, and the arguments as the Golem agent redacted them. It refuses the call, hands it to a person under Held calls, or, only where that rule allows it, lets it through. |
Not every client can wait:
- A client that cannot ask its user refuses the call and says so, rather than letting it run. Cursor asks only in its Allowlist run mode; Codex never does.
- A hook cannot wait for your team, so a team Ask on a hook is refused at once with a message saying who decides it and how to get it approved. It waits for them only on the MCP path.
- A hook waits for the reviewer agent for up to 35 seconds. If it has not decided, the agent is told to wait and retry the same call, and the retry finds the same held call.
On the MCP path a held call waits for the workspace's Default wait for an answer (30 seconds unless changed; a rule can set its own), then If no one answers applies: Block it by default, or Let it through, which counts as loosening and raises an alert. Both are under Protections → Settings → Asks for review.
Golem's reviewer agent#
The reviewer is off until an owner or admin turns on Golem's reviewer agent in the same card. With it on:
- It hands a call to a person when it isn't sure is on by default. Off, it refuses what it is not sure of.
- And after the session read a likely injection is on by default: once a session has read a likely prompt injection, its held calls go to a person without the reviewer.
- It never decides alone on the tools in its high blast radius list,
terraform,kubectlandgh releaseby default. - Whether it may let a call through is set on each rule, never inherited: It may Refuse or hand off (the default) or Also let through, with What it should look for.
It joins your workspace under its own identity, golem-reviewer, and each decision is signed into your record as made by it. Its model calls count against the workspace's model budget.
Lock a session down#
After an agent reads something hostile, the safest thing is often to let it keep working with less. A rule with Taint the session does that: from the match until a fresh session, its shell commands run with no network, no credentials and writes only inside the repository. On a Mac this is enforced by the shell jail, so it holds even for a command the agent was talked into.
The usual trigger is the prompt-injection check. With it on, each web page, search result, MCP result and message from another agent that an agent reads is scored, and the verdict is signed into the session; the text is never stored with it. A rule on that score can lock the session down, and a rule at Block withholds the result itself before the agent reads it (in Claude Code and on Golem's MCP path). Three starter rules lock a session down after a web fetch, a likely injection, or a jail refusal. They ship off; turn them on under Sandbox → Settings → Lock down a session.
Safely#
Type /safely in Claude Code before a task that reads something you do not trust, such as PR comments, an issue or a web page. From then on the session can use only a safe set of tools, refused before they run by its own hook:
| Command | The session may |
|---|---|
/safely | Read, Grep and Glob. No shell, no edits, no network. |
/safely review | The same, plus git status, log, diff, show, branch and remote, and single gh pr, issue, repo, search and api commands, with no chaining. |
Anything that is not a known profile name falls back to the strictest one. It also locks the session's shell down.
Safely is decided from what the person typed, never from what the model says, so content the agent reads cannot turn it on or off. It only tightens. There is no command, tool or console button that loosens it: to get the session's tools back, start a fresh session. Every restriction and every refused call is signed into the record.
To restrict sessions without anyone typing a command, set a Safety mode floor on a profile under Protections → Profiles. Every session on those machines is restricted to that safety mode's allowlist.
Restrict a machine for a while#
On a machine's page in the console, Restrict to Safe · 1 h or 24 h restricts every session on it, including ones already running, to the read-only Safe set. It lifts by itself when the time is up, or sooner with Lift….
Quarantine a machine#
When a machine looks compromised, quarantine it: Quarantine… on the machine's page, or Quarantine this host under Access. A reason is required, because whoever releases it has only that to go on.
- Every session on the machine, new and already running, is restricted to the read-only Safe set, and its shell is locked down.
- The machine keeps reporting to Golem, so evidence keeps arriving while its reach is cut.
- It takes effect within one sync, about 30 seconds. The Golem agent keeps the quarantine across restarts and while offline; only an answer from Golem that the machine is released lifts it.
- Only an owner can release it, with Release.
An agent with the right access can do the same through Golem's MCP with quarantine_host. Quarantine does nothing irreversible: it deletes nothing, stops no process and touches no credentials. See Limits for why.
If Golem is down#
Hooks let calls through rather than stall your engineers, the shell jail keeps a baseline that still denies credential stores and persistence writes, and a held MCP call that nobody can answer is blocked by default. Limits has the full table.
What this does not do#
- A refusal stops the call, not the agent. The session continues, and the agent decides what to do next.
- Blocks and holds act on calls Golem sees. A hook is only as strong as the client that calls it. See Limits.
- Golem does not lift a restriction on its own judgement. Safely needs a fresh session, and a quarantine needs an owner.