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

# Authorization

> Reference for the mcpAuthorization and authorization policies — CEL-based access control rules for MCP and HTTP traffic.

Agentgateway supports two authorization policy types:

* **`mcpAuthorization`** — evaluates access to MCP tool calls, resources, and prompts using CEL expressions with MCP-aware context variables.
* **`authorization`** — evaluates access to HTTP routes using CEL expressions with HTTP-aware context variables.

Both policies define a list of rules. A request is allowed if **at least one rule evaluates to `true`**. If no rule matches, the request is denied.

## Configuration location

Both policies are set under `binds[].listeners[].routes[].policies`:

```yaml theme={null}
binds:
- port: 3000
  listeners:
  - routes:
    - policies:
        mcpAuthorization:
          rules:
          - 'mcp.tool.name == "echo"'
          - 'jwt.sub == "admin" && mcp.tool.name == "add"'
```

## mcpAuthorization

<ParamField body="mcpAuthorization" type="object">
  Authorization policy for MCP access. Controls which MCP tool calls, resource reads, and prompt invocations are allowed.

  <Expandable title="mcpAuthorization fields">
    <ParamField body="mcpAuthorization.rules" type="string[]" required>
      A list of CEL expressions. Each expression must evaluate to a boolean. A request is **allowed** when any rule evaluates to `true`. If no rules match, the request is denied with a 403 response.

      ```yaml theme={null}
      mcpAuthorization:
        rules:
        - 'mcp.tool.name == "echo"'
        - 'jwt.sub == "test-user" && mcp.tool.name == "add"'
      ```
    </ParamField>
  </Expandable>
</ParamField>

### CEL context variables for mcpAuthorization

The following variables are available inside CEL expressions for `mcpAuthorization`:

| Variable              | Type     | Description                                                                                                      |
| --------------------- | -------- | ---------------------------------------------------------------------------------------------------------------- |
| `mcp.tool.name`       | `string` | Name of the MCP tool being called                                                                                |
| `mcp.tool.target`     | `string` | Target server name for the tool                                                                                  |
| `mcp.resource.name`   | `string` | Name of the MCP resource being accessed                                                                          |
| `mcp.resource.target` | `string` | Target server name for the resource                                                                              |
| `mcp.prompt.name`     | `string` | Name of the MCP prompt being invoked                                                                             |
| `mcp.prompt.target`   | `string` | Target server name for the prompt                                                                                |
| `jwt`                 | `map`    | Decoded JWT claims from the authenticated token. Access any claim with dot notation, e.g. `jwt.sub`, `jwt.email` |
| `jwt.sub`             | `string` | JWT subject claim                                                                                                |

<Note>
  Nested JWT claims are accessible using dot notation. For example, a claim `{"nested": {"key": "value"}}` can be referenced as `jwt.nested.key`.
</Note>

## authorization

<ParamField body="authorization" type="object">
  Authorization policy for HTTP access. Controls which HTTP requests are allowed based on request attributes.

  <Expandable title="authorization fields">
    <ParamField body="authorization.rules" type="string[]" required>
      A list of CEL expressions. Each expression must evaluate to a boolean. A request is **allowed** when any rule evaluates to `true`.

      ```yaml theme={null}
      authorization:
        rules:
        - 'request.headers["x-user-role"] == "admin"'
      ```
    </ParamField>
  </Expandable>
</ParamField>

## Rule evaluation

<Steps>
  <Step title="Evaluate each rule in order">
    Agentgateway evaluates each CEL expression in the `rules` list sequentially.
  </Step>

  <Step title="Allow on first match">
    If any rule returns `true`, the request is allowed immediately and evaluation stops.
  </Step>

  <Step title="Deny if no rules match">
    If no rules return `true`, the request is denied with an HTTP 403 response.
  </Step>
</Steps>

## Examples

<AccordionGroup>
  <Accordion title="Allow specific tools">
    Allow anyone to call `echo`, but restrict `add` to a specific user:

    ```yaml theme={null}
    mcpAuthorization:
      rules:
      # Allow anyone to call 'echo'
      - 'mcp.tool.name == "echo"'
      # Only test-user can call 'add'
      - 'jwt.sub == "test-user" && mcp.tool.name == "add"'
    ```
  </Accordion>

  <Accordion title="Require a specific JWT claim">
    Allow access to `printEnv` only for users who have a specific nested claim value:

    ```yaml theme={null}
    mcpAuthorization:
      rules:
      - 'mcp.tool.name == "printEnv" && jwt.nested.key == "value"'
    ```
  </Accordion>

  <Accordion title="Combined authentication and authorization">
    A full example using JWT authentication with authorization rules:

    ```yaml theme={null}
    policies:
      jwtAuth:
        issuer: agentgateway.dev
        audiences: [test.agentgateway.dev]
        jwks:
          file: ./manifests/jwt/pub-key
      mcpAuthorization:
        rules:
        - 'mcp.tool.name == "echo"'
        - 'jwt.sub == "test-user" && mcp.tool.name == "add"'
        - 'mcp.tool.name == "printEnv" && jwt.nested.key == "value"'
    ```
  </Accordion>
</AccordionGroup>

<Warning>
  Authorization rules are evaluated **after** authentication. If `jwtAuth` or `mcpAuthentication` is configured alongside an authorization policy, the JWT must be valid before any rules are checked. A missing or invalid token results in a 401, not a 403.
</Warning>

<Tip>
  To allow all authenticated users unconditional access, add a catch-all rule that always returns true: `'true'`. Use this sparingly — it effectively disables authorization checking for matched requests.
</Tip>
