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

# Validate Rule

> Validate a single policy rule for correctness.

Validates CEL expression syntax, undefined variables, action format, and role/group format.
Returns 204 No Content if valid, or 422 with Pydantic validation errors if invalid.



## OpenAPI

````yaml /api-reference/openapi.yaml post /api/policy/v2/policies/rule/validate
openapi: 3.1.0
info:
  title: Barndoor.ai Public API
  description: Unified public API specification for Barndoor.ai platform
  version: 2.18.0
servers:
  - url: https://{host}
    description: Barndoor public API
    variables:
      host:
        default: platform.barndoor.ai
        description: >-
          The host serving your Barndoor deployment. Defaults to production;
          override it for another environment or a dedicated deployment.
security:
  - ApiKey: []
  - OAuth2:
      - openid
      - profile
      - email
tags:
  - name: dlp
    x-group: Data Control Center
  - name: identity
    x-group: Identity
  - name: llm-gateway
    x-group: LLM Gateway
  - name: notification
    x-group: Notifications
  - name: policy
    x-group: Policies
  - name: registry
    x-group: MCP Gateway
  - name: system-management
    x-group: Log Exports
paths:
  /api/policy/v2/policies/rule/validate:
    post:
      tags:
        - policy
      summary: Validate Rule
      description: >-
        Validate a single policy rule for correctness.


        Validates CEL expression syntax, undefined variables, action format, and
        role/group format.

        Returns 204 No Content if valid, or 422 with Pydantic validation errors
        if invalid.
      operationId: validate_policy_rule
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PolicyRule-Input'
        required: true
      responses:
        '204':
          description: Successful Response
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    PolicyRule-Input:
      properties:
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
          description: >-
            Optional display name for the rule. Letters, digits, spaces, hyphens
            and underscores only — a colon or other punctuation is rejected with
            a 422, which is easy to hit because rule names tend to read like
            `Security: view agents`. Names must also be unique within the policy
            once punctuation is normalized, so `My Rule` and `My-Rule` collide.
          default: ''
          examples:
            - Engineering read access
            - Support write with approval
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
          description: >-
            Optional human-readable description for the rule; has no effect on
            enforcement
        authorized:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Authorized
          description: >-
            Effect of the rule: True grants the listed `actions`, False denies
            them. Access is denied by default, so a tool that no rule grants is
            already blocked — an explicit False rule is only needed to carve an
            exception out of a broader allow. The effective model is tri-state
            rather than binary: Always Allow is True on the plain action, Needs
            Approval is True on the `:approve` twin (see `actions`), and Blocked
            is simply the absence of a grant.
          default: false
        active:
          type: boolean
          title: Active
          description: >-
            Whether this rule is enforced. False keeps the rule on the policy
            but omits it from enforcement — use it to disable a rule without
            deleting it.
          default: true
        actions:
          items:
            type: string
          type: array
          title: Actions
          description: >-
            Tool actions this rule matches, in the wire format
            `tools/call:<tool_name>` — for example `tools/call:create_issue`.
            Use `*` to match every action on the server. Tool names are specific
            to the target MCP server: enumerate the server's real tools rather
            than guessing names. A trailing `:approve` selects the
            Needs-Approval variant of a tool
            (`tools/call:create_issue:approve`), which requires per-call human
            confirmation; the plain action is Always Allow. Do not grant both
            twins of the same tool in one rule.
          examples:
            - - tools/call:create_issue
            - - tools/call:delete_page:approve
            - - '*'
        roles_groups:
          items:
            type: string
          type: array
          title: Roles Groups
          description: >-
            Principals this rule applies to, as PREFIXED entries:
            `role:<role_name>` for an IdP/Keycloak role, `group:<group_name>`
            for a user group, or the literal `*` for all users (the default). A
            bare name with no `role:`/`group:` prefix matches NOTHING. Retrieve
            the organization's real role and group names from `GET
            /api/identity/public/v1/users/roles-groups`. A principal set should
            appear on at most ONE rule in a policy — collect all of its actions
            there instead of spreading them over several rules.
          examples:
            - - '*'
            - - group:Engineering
            - - role:admin
              - group:Platform
        condition:
          anyOf:
            - $ref: '#/components/schemas/PolicyRuleCondition-Input'
            - type: 'null'
          description: >-
            Optional CEL condition; the rule applies only when it evaluates
            true. Shape is `{"match": <matcher>}`. Omit entirely for an
            unconditional rule.
      type: object
      required:
        - actions
      title: PolicyRule
      description: >-
        A single rule: which principals may take which tool actions, optionally
        conditioned.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    PolicyRuleCondition-Input:
      properties:
        match:
          oneOf:
            - $ref: '#/components/schemas/Expression'
            - $ref: '#/components/schemas/OperatorAll-Input'
            - $ref: '#/components/schemas/OperatorAny-Input'
            - $ref: '#/components/schemas/OperatorNone-Input'
          title: Match
          description: >-
            Matcher tree. Either a single expression `{"expr": "..."}` or a
            boolean combinator `{"all"|"any"|"none": {"of": [<matcher>, ...]}}`,
            which nest arbitrarily. The variant is selected by WHICH KEY IS
            PRESENT — there is no separate discriminator field. Example: {"all":
            {"of": [{"expr": "P.attr.department == 'Engineering'"}, {"expr":
            "R.attr.env != 'prod'"}]}}
      type: object
      required:
        - match
      title: PolicyRuleCondition
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    Expression:
      properties:
        expr:
          type: string
          title: Expr
          description: >-
            A single CEL expression that must evaluate to a boolean. Top-level
            variables: C, G, P, R, V, constants, globals, request, runtime,
            variables. `P` is the calling principal and `R` the resource (the
            tool call being authorized). Commonly used attributes:
            `P.attr.groups` and `P.attr.roles` hold the UNPREFIXED role and
            group names from the user's profile — note the contrast with a
            rule's `roles_groups`, whose entries are `role:`/`group:`-prefixed;
            other IdP profile fields such as `P.attr.department` are available;
            and `R.attr.<argument>` exposes the tool call's own arguments.
            Expressions are compiled at write time and rejected if invalid or if
            they reference an unknown variable.
          examples:
            - P.attr.department == 'Engineering'
            - R.attr.repository.startsWith('barndoor-ai/')
      type: object
      required:
        - expr
      title: Expression
    OperatorAll-Input:
      properties:
        all:
          $ref: '#/components/schemas/ConditionOf-Input'
          description: Logical AND — every matcher in `of` must evaluate true.
      type: object
      required:
        - all
      title: OperatorAll
    OperatorAny-Input:
      properties:
        any:
          $ref: '#/components/schemas/ConditionOf-Input'
          description: Logical OR — at least one matcher in `of` must evaluate true.
      type: object
      required:
        - any
      title: OperatorAny
    OperatorNone-Input:
      properties:
        none:
          $ref: '#/components/schemas/ConditionOf-Input'
          description: >-
            Logical NOR — the rule applies only if NO matcher in `of` evaluates
            true.
      type: object
      required:
        - none
      title: OperatorNone
    ConditionOf-Input:
      properties:
        of:
          items:
            oneOf:
              - $ref: '#/components/schemas/Expression'
              - $ref: '#/components/schemas/OperatorAll-Input'
              - $ref: '#/components/schemas/OperatorAny-Input'
              - $ref: '#/components/schemas/OperatorNone-Input'
          type: array
          title: Of
          description: >-
            Operand list for the enclosing `all`/`any`/`none` combinator. Each
            operand is itself a matcher — either `{"expr": "..."}` or a further
            nested combinator.
      type: object
      required:
        - of
      title: ConditionOf
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      description: >-
        A Barndoor API key, sent as `Authorization: Bearer <key>`. Keys are
        prefixed `bdai_` and are opaque — do not attempt to decode one.
        Interchangeable with an OAuth 2.0 access token.
    OAuth2:
      type: oauth2
      x-issuer: https://auth.barndoor.ai/realms/barndoor
      description: >-
        An OAuth 2.0 access token from Barndoor's identity provider, sent as
        `Authorization: Bearer <token>`. Public clients must use PKCE.
        Interchangeable with an API key.
      flows:
        authorizationCode:
          authorizationUrl: >-
            https://auth.barndoor.ai/realms/barndoor/protocol/openid-connect/auth
          tokenUrl: >-
            https://auth.barndoor.ai/realms/barndoor/protocol/openid-connect/token
          scopes:
            openid: Issue an OIDC ID token identifying the caller.
            profile: Read the caller's basic profile claims.
            email: Read the caller's email address.
            offline_access: Issue a refresh token. Optional — no operation requires it.
        clientCredentials:
          tokenUrl: >-
            https://auth.barndoor.ai/realms/barndoor/protocol/openid-connect/token
          scopes:
            openid: Issue an OIDC ID token identifying the caller.
            profile: Read the caller's basic profile claims.
            email: Read the caller's email address.
            offline_access: Issue a refresh token. Optional — no operation requires it.

````

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