Skip to main content
Version: v1alpha1
Status: Draft
Last Updated: 2026-01-20
Authors: Eduardo Arango ([email protected])
This is the v1alpha1 specification. For the latest version, see v1alpha2.

Abstract

The Agent Identity Protocol (AIP) defines a standard for policy-based authorization of AI agent tool calls. AIP enables runtime environments to enforce fine-grained access control over Model Context Protocol (MCP) tool invocations, providing a security boundary between AI agents and external resources. This specification defines:
  1. The policy document schema (AgentPolicy)
  2. Evaluation semantics for authorization decisions
  3. Error codes for denied requests
  4. Audit log format for compliance
AIP is designed to be implementation-agnostic. Any MCP-compatible runtime (Cursor, Claude Desktop, VS Code, custom implementations) can implement this specification.

Formal Specification

Download Formal Specification

View the complete formal specification document on GitHub

Introduction

Motivation

AI agents operating through the Model Context Protocol (MCP) have access to powerful tools: file systems, databases, APIs, and cloud infrastructure. Without a policy layer, agents operate with unrestricted access to any tool the MCP server exposes. AIP addresses this gap by introducing:
  • Capability declaration: Explicit allowlists of permitted tools
  • Argument validation: Regex-based constraints on tool parameters
  • Human-in-the-loop: Interactive approval for sensitive operations
  • Audit trail: Immutable logging of all authorization decisions

Goals

  1. Interoperability: Any MCP runtime can implement AIP
  2. Simplicity: YAML-based policies readable by security teams
  3. Defense in depth: Multiple layers (method, tool, argument)
  4. Fail-closed: Unknown tools are denied by default

Relationship to MCP

AIP is designed as a security layer for MCP. It intercepts tools/call requests and applies policy checks before forwarding to the MCP server.
┌─────────┐     ┌─────────────┐     ┌─────────────┐
│  Agent  │────▶│ AIP Policy  │────▶│ MCP Server  │
│         │◀────│   Engine    │◀────│             │
└─────────┘     └─────────────┘     └─────────────┘

Policy Document Schema

apiVersion: aip.io/v1alpha1      # REQUIRED
kind: AgentPolicy                 # REQUIRED

metadata:                         # REQUIRED
  name: string                    # REQUIRED - Policy identifier
  version: string                 # OPTIONAL - Semantic version
  owner: string                   # OPTIONAL - Contact email

spec:                             # REQUIRED
  mode: enforce | monitor         # OPTIONAL, default: enforce
  
  allowed_tools:                  # OPTIONAL
    - string
  
  allowed_methods:                # OPTIONAL
    - string
  
  denied_methods:                 # OPTIONAL
    - string
  
  protected_paths:                # OPTIONAL
    - string
  
  strict_args_default: boolean    # OPTIONAL, default: false
  
  tool_rules:                     # OPTIONAL
    - tool: string                # REQUIRED
      action: allow|block|ask     # OPTIONAL, default: allow
      rate_limit: string          # OPTIONAL, format: "N/period"
      strict_args: boolean        # OPTIONAL
      allow_args:                 # OPTIONAL
        <arg_name>: <regex>
  
  dlp:                            # OPTIONAL
    enabled: boolean              # OPTIONAL, default: true
    detect_encoding: boolean      # OPTIONAL, default: false
    filter_stderr: boolean        # OPTIONAL, default: false
    patterns:                     # REQUIRED if dlp present
      - name: string              # REQUIRED
        regex: string             # REQUIRED

Required Fields

apiVersion
string
required
MUST be aip.io/v1alpha1
kind
string
required
MUST be AgentPolicy
metadata.name
string
required
Unique identifier for this policy. Must be a valid DNS-1123 subdomain (lowercase alphanumeric + hyphens).

Metadata Fields

metadata.version
string
Semantic version (e.g., “1.0.0”, “2.1.0-beta”)
metadata.owner
string
Contact email for policy questions

Spec Fields

spec.mode
enum
default:"enforce"
Controls enforcement behavior:
  • enforce: Violations are blocked (default)
  • monitor: Violations are logged but allowed
Use monitor mode to test new policies in production before enforcement.
spec.allowed_tools
array
A list of tool names that the agent MAY invoke.
allowed_tools:
  - github_get_repo
  - read_file
  - list_directory
Tool names are subject to normalization (see Evaluation Semantics).
spec.allowed_methods
array
A list of JSON-RPC methods that are permitted. If not specified, implementations MUST use the default safe list.
Default allowed methods (when not specified):
allowed_methods:
  - initialize
  - initialized
  - ping
  - tools/call
  - tools/list
  - completion/complete
  - notifications/initialized
  - notifications/progress
  - notifications/message
  - notifications/resources/updated
  - notifications/resources/list_changed
  - notifications/tools/list_changed
  - notifications/prompts/list_changed
  - cancelled
The wildcard * MAY be used to allow all methods.
spec.denied_methods
array
A list of JSON-RPC methods that are explicitly denied. Denied methods take precedence over allowed methods.
denied_methods:
  - resources/read
  - resources/write
spec.protected_paths
array
A list of file paths that tools MUST NOT access. Any tool argument containing a protected path MUST be blocked.
protected_paths:
  - ~/.ssh
  - ~/.aws/credentials
  - .env
Implementations MUST:
  • Expand ~ to the user’s home directory
  • Automatically protect the policy file itself
spec.strict_args_default
boolean
default:"false"
When true, tool rules reject any arguments not explicitly declared in allow_args.

Tool Rules

Tool rules provide fine-grained control over specific tools.
tool_rules:
  - tool: <string>              # REQUIRED - Tool name
    action: <string>            # OPTIONAL - allow|block|ask (default: allow)
    rate_limit: <string>        # OPTIONAL - e.g., "10/minute"
    strict_args: <bool>         # OPTIONAL - Override strict_args_default
    allow_args:                 # OPTIONAL
      <arg_name>: <regex>
ActionBehavior
allowPermit (subject to argument validation)
blockDeny unconditionally
askRequire interactive user approval
Example:
tool_rules:
  - tool: delete_file
    action: block
  
  - tool: run_training
    action: ask
Format: <count>/<period>
PeriodAliases
secondsec, s
minutemin, m
hourhr, h
Example:
tool_rules:
  - tool: list_gpus
    rate_limit: "10/minute"
Rate limiting algorithm is implementation-defined (token bucket, sliding window, etc.).
The allow_args field maps argument names to regex patterns.
allow_args:
  url: "^https://github\.com/.*"
  query: "^SELECT\s+.*"
Implementations MUST:
  • Use a regex engine with linear-time guarantees (RE2 or equivalent)
  • Match against the string representation of the argument value
  • Treat missing constrained arguments as a violation

DLP Configuration

Data Loss Prevention (DLP) scans tool responses for sensitive data.
dlp:
  enabled: <bool>             # OPTIONAL, default: true when dlp block present
  detect_encoding: <bool>     # OPTIONAL, default: false
  filter_stderr: <bool>       # OPTIONAL, default: false
  patterns:
    - name: <string>          # REQUIRED - Rule identifier
      regex: <string>         # REQUIRED - Detection pattern
Redaction format: When a pattern matches, the matched content MUST be replaced with:
[REDACTED:<name>]
Example:
dlp:
  patterns:
    - name: "AWS Key"
      regex: "(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}"
    
    - name: "GitHub Token"
      regex: "ghp_[a-zA-Z0-9]{36}"

Evaluation Semantics

Name Normalization

Tool names and method names MUST be normalized before comparison using the following algorithm:
NORMALIZE(input):
  1. Apply NFKC Unicode normalization
  2. Convert to lowercase
  3. Trim leading/trailing whitespace
  4. Remove non-printable and control characters
  5. Return result
This prevents bypass attacks using:
  • Fullwidth characters: deletedelete
  • Ligatures: filefile
  • Zero-width characters: dele​tedelete

Method-Level Authorization

Method authorization is the FIRST line of defense, evaluated BEFORE tool-level checks.
IS_METHOD_ALLOWED(method):
  normalized = NORMALIZE(method)
  
  IF normalized IN denied_methods:
    RETURN DENY
  
  IF "*" IN allowed_methods:
    RETURN ALLOW
  
  IF normalized IN allowed_methods:
    RETURN ALLOW
  
  RETURN DENY

Tool-Level Authorization

IS_TOOL_ALLOWED(tool_name, arguments):
  normalized = NORMALIZE(tool_name)
  
  # Step 1: Check rate limiting
  IF rate_limiter_exceeded(normalized):
    RETURN RATE_LIMITED
  
  # Step 2: Check protected paths
  IF arguments_contain_protected_path(arguments):
    RETURN PROTECTED_PATH
  
  # Step 3: Check tool rules
  rule = find_rule(normalized)
  IF rule EXISTS:
    IF rule.action == "block":
      RETURN BLOCK
    IF rule.action == "ask":
      IF validate_arguments(rule, arguments):
        RETURN ASK
      ELSE:
        RETURN BLOCK
    # action == "allow" falls through
  
  # Step 4: Check allowed_tools list
  IF normalized NOT IN allowed_tools:
    RETURN BLOCK
  
  # Step 5: Validate arguments (if rule exists)
  IF rule EXISTS AND rule.allow_args NOT EMPTY:
    IF NOT validate_arguments(rule, arguments):
      RETURN BLOCK
  
  # Step 6: Strict args check
  IF strict_args_enabled(rule):
    IF arguments has undeclared keys:
      RETURN BLOCK
  
  RETURN ALLOW

Decision Outcomes

DecisionMode=enforceMode=monitor
ALLOWForward requestForward request
BLOCKReturn errorForward request, log violation
ASKPrompt userPrompt user
RATE_LIMITEDReturn errorReturn error (always enforced)
PROTECTED_PATHReturn errorReturn error (always enforced)

Error Codes

AIP defines the following JSON-RPC error codes:
-32001
Forbidden
Tool not in allowed_tools list
-32002
Rate Limited
Rate limit exceeded
-32004
User Denied
User rejected approval prompt
-32005
User Timeout
Approval prompt timed out
-32006
Method Not Allowed
JSON-RPC method not permitted
-32007
Protected Path
Access to protected path blocked

Error Response Format

{
  "jsonrpc": "2.0",
  "id": <request_id>,
  "error": {
    "code": <error_code>,
    "message": "<error_message>",
    "data": {
      "tool": "<tool_name>",
      "reason": "<human_readable_reason>"
    }
  }
}

Audit Log Format

Implementations SHOULD log all authorization decisions in JSON Lines format.

Required Fields

timestamp
string
required
ISO 8601 timestamp of the decision
direction
enum
required
upstream (client→server) or downstream (server→client)
decision
enum
required
ALLOW, BLOCK, ALLOW_MONITOR, RATE_LIMITED
policy_mode
enum
required
enforce or monitor
violation
boolean
required
Whether a policy violation was detected

Example Audit Entry

{
  "timestamp": "2026-01-20T10:30:45.123Z",
  "direction": "upstream",
  "method": "tools/call",
  "tool": "delete_file",
  "args": {"path": "/etc/passwd"},
  "decision": "BLOCK",
  "policy_mode": "enforce",
  "violation": true,
  "failed_arg": "path",
  "failed_rule": "^/home/.*"
}

Conformance

Conformance Levels

Requirements: Method authorization, tool allowlist, error codesMinimum viable implementation suitable for simple use cases.

Implementation Requirements

Implementations MUST:
  • Parse apiVersion: aip.io/v1alpha1 documents
  • Reject documents with unknown apiVersion
  • Apply NFKC normalization to names
  • Return specified error codes
  • Support enforce and monitor modes
Implementations SHOULD:
  • Log decisions in the specified format
  • Support DLP scanning
  • Support rate limiting
Implementations MAY:
  • Use any regex engine with RE2 semantics
  • Implement additional security features (egress control, sandboxing)

Security Considerations

Policy File Protection: The policy file itself MUST be protected from modification by the agent. Implementations MUST automatically add the policy file path to protected_paths.
Regex Denial of Service (ReDoS): Implementations MUST use a regex engine that guarantees linear-time matching (RE2 or equivalent). Pathological patterns like (a+)+$ MUST NOT cause exponential execution time.
Unicode Normalization: Implementations MUST apply NFKC normalization to prevent homoglyph attacks. However, implementers should be aware that NFKC does not normalize all visually similar characters (e.g., Cyrillic ‘а’ vs Latin ‘a’).
Monitor Mode Risks: Monitor mode allows all requests through. Implementations SHOULD warn users when monitor mode is enabled in production environments.

Version History

v1alpha1 (2026-01-20)

  • Initial draft specification
  • Defined core policy schema
  • Defined evaluation semantics
  • Defined error codes
  • Defined audit log format

References

See Also

Build docs developers (and LLMs) love