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

# Policies

> Governance at the tool-call boundary: per-tool allow / ask / deny, plus connection and primitive scoping.

Every capability an agent has flows through one place — the tool call. Naive Managed Agents enforces governance there, so a policy is checked *before* a tool runs, not audited after. Policies ship in **Phase 1** with the primitives they protect.

## Two layers, one decision

A policy is resolved from two layers, most specific wins:

1. **Organization default** — a baseline every agent in the [organization](https://vetta.sh/docs/platform/organizations.md) inherits.
2. **Agent override** — per-agent, and per-tool within an agent.

The resolved policy is evaluated on every tool call, connect attempt, and primitive use. Nothing reaches an external system without passing it.

## Per-tool permission policy

Each [tool](https://vetta.sh/docs/capabilities/tools.md) resolves to one of three permissions:

| Permission | Behavior |
| - | - |
| `allow` | The tool runs without confirmation. |
| `ask` | The runtime emits a `tool.confirm` event and **pauses the tool** until you approve or reject it. |
| `deny` | The tool is not offered to the model at all — the agent cannot call it. |

Tools are configured with a single **toolset** object: a `default_config` that applies to every tool, and per-tool `configs` that enable a tool and override its permission. There is no separate flat `tools[]` array or top-level default field.

```typescript TypeScript theme={"system"}
const agent = await vetta.agents.create({
  name: "ops",
  model: "z-ai/glm-5.3-flash",
  harness: "pi",
  budget: { capMicroUsd: "50000000", maxTaskMicroUsd: "5000000", period: "month" }, // $50 / $5
  tools: {
    default_config: { permission: "allow" },
    configs: {
      bash:            { enabled: true, permission: "allow" },
      publish_file:    { enabled: true, permission: "allow" },
      "tracker.get_issue": { enabled: true, permission: "ask" },  // a connection/MCP tool, keyed `<connector>.<tool>`
    },
  },
});
```

```bash CLI theme={"system"}
vetta agent update agt_01j8rn6zk3m9xq2vp7c4h5wgte --file ops.json   # tool policy travels in the config file
```

> [!NOTE]
>
> `allow` is convenient but not automatically the right default. For irreversible or externally-visible tools (payouts, deletes, sending mail) set `ask` — or `deny` if the agent should never have the capability — rather than leaning on the permissive baseline.

> [!NOTE]
>
> The [ask-by-default tools](https://vetta.sh/docs/capabilities/tools.md#permission-policies) (publishing, paying, filing, changing the company's settings, a paid data run, a video, training a character) resolve to `ask` when `configs` does not name them — **even under a `deny` default**. A per-tool entry is the only thing that denies one.

### Responding to `ask`

When a tool is set to `ask`, the runtime streams a `tool.confirm` event and holds the turn. The session goes `idle` with `stop_reason: "awaiting_approval"`. You resolve it by sending a decision back into the [session](https://vetta.sh/docs/concepts/sessions.md) — the same mechanism as any other input:

```bash CLI theme={"system"}
vetta session confirm --session $SID --tool-call $CALL_ID          # or
vetta session confirm --session $SID --tool-call $CALL_ID --reason "not this account"
```

The decision **records the approver** — the user or API key id that answered — on the event and audit trail, so a sign-off is attributable after the fact. See the [awaiting-approval loop](https://vetta.sh/docs/concepts/session-operations.md#awaiting-approval-loop) for the driving code.

An unanswered `ask` waits until someone answers it. A held tool consumes no budget while it waits, and — because the loop is [durable](https://vetta.sh/docs/concepts/runtime.md) — an agent can sit on a confirmation for hours at storage cost only. See [Events & streaming](https://vetta.sh/docs/concepts/events-and-streaming.md) for the event shapes.

## Connection & primitive scoping

Beyond individual tools, a policy scopes *which* external systems and primitives an agent may reach. This governs the [identity](https://vetta.sh/docs/identity/overview.md) surface — connections an agent acts through run under the same allow/ask/deny filter as `bash`.

**primitives** `object`

Which built-in primitives are enabled for the agent — e.g. `computer`, `browser`, `files`, `connections`, and (coming soon, as agent tools) `email`, `phone`.

**connections.mode** `string` (default: allowlist)

How third-party connections are gated:
\
• `open` — any connection type is allowed.
\
• `allowlist` — only the listed connection types are allowed. Recommended for anything an agent runs unattended.
\
• `blocklist` — every connection type except the listed ones is allowed.
\
`open` is permissive by design; prefer `allowlist` in production so a new connector type is not reachable until you add it.

**connections.list** `string[]`

The connection types the `allowlist` / `blocklist` applies to.

```jsonc theme={"system"}
{
  "primitives": { "computer": true, "browser": true, "connections": true },
  "connections": { "mode": "allowlist", "list": ["crm", "tracker", "chat"] }
}
```

An agent that tries to connect or call outside its allowlist is refused with a typed `forbidden` error (a `permission` denial) before any external request is made.

## Why the boundary matters

Because enforcement lives at the tool-call boundary rather than inside a prompt, a policy holds regardless of what the model decides to attempt. Combined with the [budget gate](https://vetta.sh/docs/concepts/budgets.md) — which prices every call before it runs — an agent left running unattended can neither exceed its spend nor touch a system it was not granted.

> [card] [Next: the computer](https://vetta.sh/docs/computer/index.md)
>
> The sandbox, filesystem, shell, and browser in depth.


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