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

# Policies

> Define rules that control what your agents can do. Policies are CEL expressions evaluated on every tool call.

Policies are the rules that govern what your agents can and cannot do. Each policy is a [CEL expression](https://cel.dev/) that's evaluated against the full context of every tool call — the agent's identity, the current task, and the requested tool.

## How policies work

When an agent calls a tool through the gateway, the policy engine:

1. Loads the project's **active policy release** (a versioned snapshot of all policies)
2. Evaluates each policy's CEL expression against the request context
3. Returns **allow** or **deny** based on the results

```cel theme={null}
// Allow only read operations for support agents
identity.labels.role == "support" && request.tool.name.startsWith("get_")
```

## Policy types

There are two types of policy rules:

| Type      | Behavior                                                                                         |
| --------- | ------------------------------------------------------------------------------------------------ |
| **Deny**  | If the expression evaluates to `true`, the request is **blocked**. Deny rules are checked first. |
| **Allow** | If the expression evaluates to `false`, the request is **blocked**. All allow rules must pass.   |

Deny rules take priority. If any deny rule matches, the request is rejected — even if allow rules would have permitted it.

## Policy releases

Policies go through a draft → publish workflow:

1. **Draft** — write and edit policy rules in the console
2. **Publish** — create a versioned snapshot (release) of your current policies

This versioning ensures you can safely update policies without disrupting running agents. You can roll back to a previous release at any time.

<Note>
  If no active release exists for a project, the gateway falls back to the project's **default policy action** — either allow all or deny all.
</Note>

## Evaluation context

Every policy has access to these variables:

```json theme={null}
{
  "identity": {
    "name": "support-agent",
    "labels": { "team": "support", "role": "agent" }
  },
  "task": {
    "name": "resolve-ticket",
    "labels": { "priority": "high" },
    "context": { "ticket_id": "TICKET-123", "customer_id": "cust_456" }
  },
  "request": {
    "tool": {
      "name": "get_issue",
      "args": { "issue_id": "TICKET-123" }
    }
  }
}
```

<Tip>
  Use task context to scope access dynamically. For example, ensure the agent can only access the customer referenced in the current task.
</Tip>

## Example

A policy that allows support agents to read ticket data, but only for the customer in their task context:

```cel theme={null}
identity.labels.team == "support"
  && request.tool.name in ["get_issue", "get_customer", "add_comment"]
  && task.context.customer_id == request.tool.args.customer_id
```

## Next steps

<CardGroup cols={2}>
  <Card title="CEL expressions" icon="code" href="/policies/cel-expressions">
    Full reference for writing CEL policy expressions.
  </Card>

  <Card title="Policy examples" icon="book-open" href="/policies/examples">
    Real-world policy patterns you can copy and adapt.
  </Card>
</CardGroup>
