> ## 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.

# Write Policies

> Author CEL-based policy rules that control what your agents can do.

Policies are CEL expressions that the gateway evaluates on every tool call. Write them in the console's policy editor.

## Create a policy

<Steps>
  <Step title="Navigate to Policies">
    Open your project and click **Policies** in the sidebar.
  </Step>

  <Step title="Click Create Policy">
    Click the **Create Policy** button.
  </Step>

  <Step title="Set the name">
    Give the policy a descriptive name — e.g., `allow-support-reads`, `block-admin-tools`, `scope-to-customer`.
  </Step>

  <Step title="Choose the effect">
    | Effect    | Behavior                                            |
    | --------- | --------------------------------------------------- |
    | **Allow** | If expression is `false`, the request is **denied** |
    | **Deny**  | If expression is `true`, the request is **denied**  |

    Deny rules are evaluated first and take priority.
  </Step>

  <Step title="Write the CEL expression">
    Write the CEL expression directly in the editor. The expression is evaluated on every tool call against the request context:

    ```cel theme={null}
    // Example: only allow support tools for support team
    identity.labels.team == "support"
      && request.tool.name in ["get_issue", "add_comment"]
    ```

    Available variables:

    * `identity.name`, `identity.labels`
    * `task.name`, `task.labels`, `task.context`
    * `request.tool.name`, `request.tool.args`

    See the [CEL reference](/policies/cel-expressions) for full syntax.
  </Step>
</Steps>

## Policy editor

The console includes a code editor with:

* Syntax highlighting for CEL expressions
* Access to the variable reference while editing

## Organizing policies

A project can have multiple policy rules. They're evaluated in order:

1. All **deny** rules first — if any match (`true`), the request is blocked
2. All **allow** rules next — if any don't match (`false`), the request is blocked
3. If all rules pass, the request is allowed

**Recommended pattern:**

```
1. [Deny]  block-dangerous-ops     → block destructive tools for everyone
2. [Deny]  block-production-access  → block production for non-prod agents
3. [Allow] allow-support-tools      → support team can use support tools
4. [Allow] allow-engineering-tools  → engineering team can use dev tools
```

<Note>
  Policies are drafts until published. Changes to draft policies don't affect the gateway until you publish a new release.
</Note>

## Testing policies

Before publishing, test your policies mentally by checking:

1. Does an agent with label `team: support` calling `get_issue` pass? (Should it?)
2. Does an agent with label `team: engineering` calling `deploy_service` pass? (Should it?)
3. Does an agent without a task session get blocked? (If your allow rule references `task.context`, yes — and that might be intentional.)

<Warning>
  If a CEL expression references `task.context` but the request has no active task session, the expression will error — and errors are treated as **deny**. Use `has()` to check for optional fields.
</Warning>

## Next steps

<CardGroup cols={2}>
  <Card title="Publish policies" icon="rocket" href="/console/publish-policies">
    Publish a release to start enforcing your policies.
  </Card>

  <Card title="CEL reference" icon="code" href="/policies/cel-expressions">
    Full syntax reference for policy expressions.
  </Card>
</CardGroup>
