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

# Set Up Capability RBAC

> Configure fine-grained access control for individual tools, prompts, and resources.

Configure capability RBAC to control access to individual tools, prompts, and resources within an MCP server.

## Prerequisites

<Tabs>
  <Tab title="Control Plane">
    * [Golf Control Plane account](https://app.golf.dev) with Admin role
    * Server RBAC configured ([Set Up Server RBAC](/gateway/guides/security/setup-server-rbac))
    * Groups synced from your identity provider
  </Tab>

  <Tab title="YAML">
    * Golf Gateway deployed in [Distributed mode](/gateway/guides/getting-started/deploy-hybrid-mode)
    * Server RBAC configured in your YAML file
    * Familiarity with the [YAML schema](/gateway/reference/yaml-schema)
  </Tab>
</Tabs>

## How it works

Capability RBAC extends server RBAC to control access to individual:

* **Tools** - Functions the AI can call
* **Prompts** - Prompt templates
* **Resources** - Data sources

### 4-layer policy merge

Capability RBAC uses a 4-layer policy merge to determine access:

| Layer               | Where Configured                    | Purpose                               |
| ------------------- | ----------------------------------- | ------------------------------------- |
| **1. Organization** | Control Plane > Settings > Policies | Base annotation defaults              |
| **2. Gateway**      | Control Plane > Gateway > Policies  | Override org defaults                 |
| **3. Annotation**   | From MCP server tool metadata       | Selects which policy category applies |
| **4. Capability**   | Per-server capability overrides     | Most specific per-tool rules          |

Each layer can only make access **more restrictive**, never less. The final access decision is the intersection of all layers.

### Tool annotations

MCP servers provide annotations that describe each tool's behavior. Golf Gateway uses these to apply the appropriate access policy automatically:

| Annotation              | Meaning                               | Default Policy       |
| ----------------------- | ------------------------------------- | -------------------- |
| `readOnlyHint: true`    | Tool only reads data, no side effects | More permissive      |
| `destructiveHint: true` | Tool may delete or overwrite data     | More restrictive     |
| Neither                 | Tool behavior is unspecified          | Configurable default |

<Accordion title="Example: How annotations affect access">
  With these organization defaults:

  ```
  read_only.allowed_groups = ["all-users"]
  destructive.allowed_groups = ["admins"]
  unspecified.allowed_groups = ["developers", "admins"]
  ```

  When a user invokes a tool:

  * `list_files` (readOnlyHint: true) → Allowed for all users
  * `delete_file` (destructiveHint: true) → Requires admin group
  * `send_message` (no annotations) → Requires developers or admins
</Accordion>

## Enable capability RBAC

<Tabs>
  <Tab title="Control Plane">
    1. Go to **MCP Servers** > select a server
    2. Navigate to the **Policies** tab > **Permissions** section
    3. Click **Enabled** to turn on capability RBAC
    4. Go to the **Capabilities** tab to view discovered tools, prompts, and resources
    5. Use **Review Changes** to review and approve pending capabilities
  </Tab>

  <Tab title="YAML">
    ```yaml theme={null}
    servers:
      - name: github-mcp
        url: http://localhost:3001
        rbac_enabled: true
        allowed_groups: [developers]
        capability_rbac_enabled: true  # Enable per-capability RBAC
    ```
  </Tab>
</Tabs>

## Configure annotation-based defaults

Set default access groups for each annotation category. These defaults apply to all capabilities that match the annotation.

<Tabs>
  <Tab title="Control Plane">
    **Organization-level defaults:**

    1. Go to **Settings** > **Policies**
    2. Find the **Capability RBAC** section
    3. Configure default groups for each category:
       * **Read-only tools** - Tools with `readOnlyHint: true`
       * **Destructive tools** - Tools with `destructiveHint: true`
       * **Unspecified tools** - Tools without annotations
    4. Click **Save**

    **Gateway-level overrides:**

    1. Go to **Gateways** > select a gateway > **Policies**
    2. Find the **Capability RBAC** section
    3. Override organization defaults as needed (can only be more restrictive)
    4. Click **Save**
  </Tab>

  <Tab title="YAML">
    Configure at the gateway level in `gateway_policy`:

    ```yaml theme={null}
    gateway_policy:
      capability_rbac:
        read_only:
          default_groups: [all-users]        # Permissive for read-only
        destructive:
          default_groups: [admins]           # Restrictive for destructive
        unspecified:
          default_groups: [developers, admins]
    ```

    <Note>
      Organization-level annotation defaults are configured in the Control Plane UI, even when using Distributed mode. The `gateway_policy` in YAML provides gateway-level overrides.
    </Note>
  </Tab>
</Tabs>

## Configure per-capability overrides

For specific tools that need different access than their annotation category, configure per-capability overrides:

<Tabs>
  <Tab title="Control Plane">
    1. Go to **MCP Servers** > select a server > **Capabilities** tab
    2. Find the capability you want to restrict
    3. Click the capability row to expand details
    4. Click **Edit Permissions**
    5. Enable **Custom Access** to override annotation defaults
    6. Select allowed groups for this specific capability
    7. Click **Save**
  </Tab>

  <Tab title="YAML">
    Use `capability_overrides` on the server to set per-capability rules:

    ```yaml theme={null}
    servers:
      - name: github-mcp
        url: http://localhost:3001
        capability_rbac_enabled: true
        capability_overrides:
          # Restrict delete operations to repo admins only
          - capability: "tools/delete_repo"
            rbac_enabled: true
            rbac_mode: allow
            allowed_groups: [repo-admins]

          # Allow all users to list repositories
          - capability: "tools/list_repos"
            rbac_enabled: true
            allowed_groups: [all-users]

          # Use wildcards for patterns
          - capability: "tools/delete_*"
            allowed_groups: [admins]
    ```

    **Capability patterns:**

    * `tools/exact_name` - Match specific tool
    * `tools/prefix_*` - Match tools starting with prefix
    * `resources/*` - Match all resources
    * `prompts/category/*` - Match prompts in category
  </Tab>
</Tabs>

## Pending approval workflow

When capability versioning is enabled, new or modified capabilities require admin approval before becoming active:

<Tabs>
  <Tab title="Control Plane">
    1. Gateway discovers new tool/prompt/resource during connection
    2. Capability appears in the **Capabilities** tab with **New** or **Changed** badge
    3. Click **Review Changes** to see all pending capabilities
    4. Review the capability schema and intended behavior
    5. Click **Approve All** or approve individual changes
    6. Users can now access the approved capabilities
  </Tab>

  <Tab title="YAML">
    To disable pending approval and auto-approve new capabilities:

    ```yaml theme={null}
    servers:
      - name: github-mcp
        capability_versioning_enabled: false  # Auto-approve new capabilities
    ```

    <Warning>
      Disabling capability versioning means new tools are immediately available to users. Only disable this for trusted internal MCP servers.
    </Warning>
  </Tab>
</Tabs>

## Complete example

Here's a complete configuration showing all capability RBAC features:

```yaml theme={null}
# Gateway-level annotation defaults
gateway_policy:
  capability_rbac:
    read_only:
      default_groups: [all-users]
    destructive:
      default_groups: [senior-developers, admins]
    unspecified:
      default_groups: [developers, admins]

servers:
  - name: github-mcp
    url: http://localhost:3001
    rbac_enabled: true
    allowed_groups: [engineering]
    idp: auth0

    # Enable capability RBAC
    capability_rbac_enabled: true

    # Per-capability overrides
    capability_overrides:
      # Only repo admins can delete repositories
      - capability: "tools/delete_repo"
        allowed_groups: [repo-admins]

      # Only security team can manage secrets
      - capability: "tools/*_secret"
        allowed_groups: [security-team]

    # Require approval for new capabilities
    capability_versioning_enabled: true
```

## Verify capability RBAC

1. Connect your MCP client (Claude Desktop, Cursor, etc.) to the gateway as an authorized user
2. Ask the AI to list available tools - verify restricted tools are filtered from the response
3. Try to use a restricted tool (e.g., `delete_repo`) - verify you receive an access denied error
4. Check audit log in Admin Portal > **Audit Logs** for the blocked request

## Troubleshooting

* **Tool not appearing**: Check if capability versioning is enabled and the tool is pending approval
* **Access denied with correct groups**: Verify all layers (org, gateway, capability override) - access is the intersection of all
* **Wildcard not matching**: Patterns use prefix matching with `*`, ensure your pattern is correct

## Related guides

* [Set Up Server RBAC](/gateway/guides/security/setup-server-rbac) - Server-level access control
* [Golf Gateway Overview](/gateway/overview/golf-gateway#capability-rbac) - Policy engine architecture
