> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blobhub.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Policies & approvals

> How far a coding agent may go on its own, and how a call that needs a person reaches one.

export const Scope = ({type, href}) => {
  const scopes = {
    workflow: ['the ', 'Workflow', ' blob type', '/blob-types/introduction#workflow'],
    scheduler: ['the ', 'Scheduler', ' blob type', '/blob-types/scheduler/overview'],
    onnx: ['the ', 'ONNX Model', ' blob type', '/blob-types/introduction#onnx'],
    worker: ['', 'blobhub-worker', ', which runs on your machines', '/worker/introduction']
  };
  const scope = scopes[type];
  if (!scope) {
    return <p>Unknown scope: {type}</p>;
  }
  return <p className="text-sm text-gray-600 dark:text-gray-400">
      Provided by {scope[0]}<strong>{scope[1]}</strong>{scope[2]}. · <a href={href || scope[3]}>Reference</a>
    </p>;
};

export const Shot = ({src, alt, caption}) => <Frame caption={caption}>
    <img className="block dark:hidden" src={src} alt={alt} />
    <img className="hidden dark:block" src={src.replace(/\.(png|svg)$/, '.dark.$1')} alt={alt} />
  </Frame>;

<Scope type="worker" href="/worker/session-agent-harness/thread-object#policy-and-guarded-permissions" />

[blobhub-worker](/general/agents-and-workers) decides how far each coding agent it runs may go on its own. A thread
runs under one of three postures: no gate at all, a policy that settles most calls by rule, or a person asked about
every gated call. A call the gate holds becomes a question in the thread the agent works in, and the agent waits
there until a person answers.

Policies and approvals belong to the worker and govern the coding agents it runs: Claude Code, Codex and
Antigravity.

## Three postures

A thread's `agent.permissions` picks its posture, resolved like the agent's other settings: the thread's own value,
then the worker's configuration, then the built-in default.

* **`autonomous`** installs no gate. The agent runs unattended, with everything the operating-system user running
  the worker can reach.
* **`guarded`** answers each call that reaches the gate from a policy. A rule's `allow` or `deny` settles the call at
  once, and its `ask` hands the call to a person.
* **`approval`**, the default, asks a person about every call that reaches the gate.

Whoever runs the machine can forbid `autonomous` on their worker altogether; a thread that asks for it there fails to
start. Which calls reach the gate depends on the agent, as [What policies are not](#what-policies-are-not) explains.

## Policies

A policy is a list of rules and a default. Each rule matches a call by its effect, one of `write`, `exec`, `read` and
`network`, optionally narrowed to a path outside the thread's work folder or, for `exec`, to a command pattern, and
answers `allow`, `deny` or `ask`. Effects are portable: the worker translates each agent's own tool names into the
four, so one policy holds whichever agent the thread runs. A tool with no single honest effect, such as a call into
an MCP tool server, maps to none and falls to the default.

Rules come from two places. The worker's own `policy.rules`, set by whoever runs the machine in its
[configuration](/worker/configuration#policy), are checked first, then the thread's own `policy` block; the first rule
that matches decides, and the thread's `default` answers anything no rule matched. A machine owner's `deny` therefore
cannot be relaxed by anything a thread sends, while a thread can still be stricter. A `guarded` thread with no policy
fails to start with `POLICY_MISSING` rather than run ungated.

A guarded run leaves its own record in the thread. It posts a `policy_applied` item before each turn, naming the rules
in force, and a `policy_denied` item for every call a rule refused, naming the rule and the call. After a restart the
worker reads and checks a guarded thread's policy again before resuming it, as
[Recovery](/worker/session-agent-harness/recovery) describes.
[Thread object](/worker/session-agent-harness/thread-object#policy-and-guarded-permissions) has the policy's fields
and what each agent's calls map to.

<Shot src="/general/images/policies-and-approvals/denied.png" alt="A policy_denied item in a coding agent's transcript" caption="A refused call is recorded with the rule that refused it." />

## How a gated call reaches a person

A call the gate holds, under `approval` or on a rule's `ask`, is posted to the thread as exactly one question with
two options, Approve and Deny. On Claude Code the agent can also ask a question of its own, with options or for free
text, and it reaches the thread the same way. Either way, by default, the agent waits in place: its process stays up
and the call is held, the wait gives up its agent slot and does not count against the turn's time, and the answer
releases the call where it stopped, whether it comes in a minute or a week.

Mission Control, the board of the [Missions](/general/apps) app, shows a waiting question with its options to pick
from. In any thread, a reply posted while the question waits answers it, and for an approval, a reply that is not a
clear yes counts as Deny.

If the worker restarts or the machine goes down meanwhile, the question survives in the thread. The turn is parked
instead of held, and when the answer arrives, the agent's session resumes with it: an approved call is tried again
under a one-shot grant, so the person is never asked twice.
[Interactive prompts](/worker/session-agent-harness/interactive-prompts) covers how an answer is matched to its
question.

<Shot src="/general/images/policies-and-approvals/question.png" alt="An agent's question waiting for a person in Mission Control" caption="A gated call or a question waits in the thread until a person answers it." />

## What policies are not

A policy is a guardrail against mistakes, not a sandbox. A command rule is a text pattern over a command line, which
a shell variable, `eval` or a script file gets past as easily as it gets past a person skimming the command, and what
the gate sees depends on the agent:

* **Codex** runs inside an operating-system sandbox on macOS and Linux under `approval` and `guarded`, rooted at the
  work folder, and only the calls that escalate past the sandbox reach the gate. It is the only one of the three with
  a sandbox.
* **Claude Code** has no sandbox, and its own permission engine approves whatever it judges read-only before the
  gate is asked, read-only shell commands included. A rule on reads has no effect there, and under `approval` a person
  sees only the calls Claude Code was unsure about.
* **Antigravity** has no sandbox either, and every call reaches the gate, reads included, so under `approval` a
  person is asked about each one.

On Claude Code and Antigravity the gate is the whole boundary, and the work folder is only where the agent starts:
the agent can reach whatever the operating-system user running the worker can. On Codex under `approval` and
`guarded`, the sandbox rooted at the work folder is what holds its writes in; under `autonomous` nothing does. If you
need isolation, run the worker on a machine or in a container that holds only what its work needs.

Cloud workflow runs have no policy. Nothing on this page applies to a workflow's own components; when a workflow
hands a step to a coding agent through a thread, as Missions does, that agent's calls are gated by the worker that
runs it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.