← Back to Documentation

Test Vectors

Comprehensive test cases for AAP token validation. Use these to verify your implementation against the specification.

15test cases
4
Valid Tokens
Tokens that should pass validation
6
Invalid Tokens
Tokens that should fail validation
2
Constraint Violations
Tests for constraint enforcement
3
Edge Cases
Clock skew, delegation limits, and edge scenarios

Valid Tokens

Tokens that should pass validation

01-basic-research-agent.jsonBasic research agent with web search capability
{
  "filename": "01-basic-research-agent.json",
  "name": "basic-research-agent",
  "description": "Basic research agent with web search capability",
  "token_payload": {
    "iss": "https://as.example.com",
    "sub": "agent-researcher-01",
    "aud": "https://api.example.com",
    "exp": 1735689600,
    "iat": 1735686000,
    "jti": "550e8400-e29b-41d4-a716-446655440000",
    "agent": {
      "id": "agent-researcher-01",
      "type": "llm-autonomous",
      "operator": "org:acme-corp",
      "name": "Research Assistant",
      "version": "1.0.0"
    },
    "task": {
      "id": "task-research-001",
      "purpose": "research_climate_data",
      "created_at": 1735686000,
      "created_by": "user:alice",
      "category": "research"
    },
    "capabilities": [
      {
        "action": "search.web",
        "description": "Search web resources within allowed domains",
        "constraints": {
          "domains_allowed": [
            "example.org",
            "trusted.com"
          ],
          "max_requests_per_hour": 100,
          "max_requests_per_minute": 10
        }
      }
    ],
    "delegation": {
      "depth": 0,
      "max_depth": 2,
      "chain": [
        "agent-researcher-01"
      ]
    },
    "audit": {
      "trace_id": "trace-550e8400-e29b-41d4-a716-446655440001",
      "log_level": "standard"
    }
  },
  "test_cases": [
    {
      "name": "valid_search_allowed_domain",
      "request": {
        "action": "search.web",
        "target_url": "https://example.org/article",
        "method": "GET"
      },
      "expected_result": "AUTHORIZED",
      "description": "Request to allowed domain should succeed"
    },
    {
      "name": "valid_search_subdomain",
      "request": {
        "action": "search.web",
        "target_url": "https://data.example.org/climate",
        "method": "GET"
      },
      "expected_result": "AUTHORIZED",
      "description": "Subdomain of allowed domain should succeed (DNS suffix matching)"
    },
    {
      "name": "invalid_domain",
      "request": {
        "action": "search.web",
        "target_url": "https://malicious.com/data",
        "method": "GET"
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_domain_not_allowed",
      "description": "Request to non-allowed domain should fail"
    },
    {
      "name": "invalid_action",
      "request": {
        "action": "cms.publish",
        "method": "POST"
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_invalid_capability",
      "description": "Request for action not in capabilities should fail"
    }
  ],
  "metadata": {
    "specification_section": "7.5 (Capability Enforcement), 5.6.2 (Domain Constraints)",
    "created": "2025-02-01",
    "version": "1.0"
  }
}
02-delegated-token-depth1.jsonFirst-level delegated token with reduced privileges
{
  "filename": "02-delegated-token-depth1.json",
  "name": "delegated-token-depth1",
  "description": "First-level delegated token with reduced privileges",
  "parent_token": "01-basic-research-agent.json",
  "token_payload": {
    "iss": "https://as.example.com",
    "sub": "agent-researcher-01",
    "aud": "https://tool-scraper.example.com",
    "exp": 1735687800,
    "iat": 1735686000,
    "jti": "550e8400-e29b-41d4-a716-446655440002",
    "agent": {
      "id": "agent-researcher-01",
      "type": "llm-autonomous",
      "operator": "org:acme-corp",
      "name": "Research Assistant",
      "version": "1.0.0"
    },
    "task": {
      "id": "task-research-001",
      "purpose": "research_climate_data",
      "created_at": 1735686000,
      "created_by": "user:alice",
      "category": "research"
    },
    "capabilities": [
      {
        "action": "search.web",
        "description": "Search web resources within allowed domains",
        "constraints": {
          "domains_allowed": [
            "example.org"
          ],
          "max_requests_per_hour": 50,
          "max_requests_per_minute": 5
        }
      }
    ],
    "delegation": {
      "depth": 1,
      "max_depth": 2,
      "chain": [
        "agent-researcher-01",
        "tool-scraper"
      ],
      "parent_jti": "550e8400-e29b-41d4-a716-446655440000",
      "privilege_reduction": {
        "capabilities_removed": [],
        "lifetime_reduced_by": 1800
      }
    },
    "audit": {
      "trace_id": "trace-550e8400-e29b-41d4-a716-446655440003",
      "log_level": "standard"
    }
  },
  "test_cases": [
    {
      "name": "valid_delegated_request",
      "request": {
        "action": "search.web",
        "target_url": "https://example.org/data",
        "method": "GET"
      },
      "expected_result": "AUTHORIZED",
      "description": "Delegated token with reduced constraints should work"
    },
    {
      "name": "depth_validation",
      "validation": {
        "check": "delegation.depth <= delegation.max_depth",
        "expected": true,
        "actual_depth": 1,
        "max_depth": 2
      },
      "expected_result": "VALID",
      "description": "Delegation depth should be within limits"
    },
    {
      "name": "chain_length_validation",
      "validation": {
        "check": "len(delegation.chain) == delegation.depth + 1",
        "expected": true,
        "chain_length": 2,
        "expected_length": 2
      },
      "expected_result": "VALID",
      "description": "Chain length should match depth + 1"
    },
    {
      "name": "reduced_rate_limit",
      "request": {
        "action": "search.web",
        "target_url": "https://example.org/data",
        "method": "GET",
        "note": "51st request in hour (parent limit was 100, delegated is 50)"
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_constraint_violation",
      "description": "Rate limit should be reduced from parent (100 -> 50)"
    },
    {
      "name": "removed_domain",
      "request": {
        "action": "search.web",
        "target_url": "https://trusted.com/data",
        "method": "GET"
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_domain_not_allowed",
      "description": "Domain removed during delegation (trusted.com not in delegated token)"
    }
  ],
  "metadata": {
    "specification_section": "5.7 (Delegation Chain Semantics), RFC 8693 (Token Exchange)",
    "created": "2025-02-01",
    "version": "1.0"
  }
}
03-cms-agent-with-oversight.jsonContent management agent with human approval requirements
{
  "filename": "03-cms-agent-with-oversight.json",
  "name": "cms-agent-with-oversight",
  "description": "Content management agent with human approval requirements",
  "token_payload": {
    "iss": "https://as.example.com",
    "sub": "agent-content-creator-01",
    "aud": "https://cms.example.com",
    "exp": 1735689600,
    "iat": 1735686000,
    "jti": "550e8400-e29b-41d4-a716-446655440010",
    "agent": {
      "id": "agent-content-creator-01",
      "type": "llm-autonomous",
      "operator": "org:acme-corp",
      "name": "Content Creator Bot",
      "version": "2.1.0",
      "model": {
        "provider": "openai",
        "id": "gpt-4",
        "version": "gpt-4-0613"
      }
    },
    "task": {
      "id": "task-content-001",
      "purpose": "create_blog_posts",
      "created_at": 1735686000,
      "created_by": "user:bob",
      "category": "content-creation",
      "priority": "medium"
    },
    "capabilities": [
      {
        "action": "cms.create_draft",
        "description": "Create draft blog posts",
        "constraints": {
          "max_requests_per_hour": 20
        }
      },
      {
        "action": "cms.update_draft",
        "description": "Update existing drafts",
        "constraints": {
          "max_requests_per_hour": 50
        }
      },
      {
        "action": "cms.publish",
        "description": "Publish content (requires human approval)",
        "constraints": {
          "max_requests_per_hour": 10
        }
      }
    ],
    "oversight": {
      "level": "approval",
      "requires_human_approval_for": [
        "cms.publish"
      ],
      "approval_reference": "https://approval.acme-corp.com/agent-actions",
      "supervisor": "user:bob"
    },
    "delegation": {
      "depth": 0,
      "max_depth": 1,
      "chain": [
        "agent-content-creator-01"
      ]
    },
    "audit": {
      "trace_id": "trace-content-550e8400-e29b-41d4-a716-446655440011",
      "log_level": "full",
      "retention_period": 90,
      "compliance_framework": [
        "SOC2",
        "GDPR"
      ]
    }
  },
  "test_cases": [
    {
      "name": "create_draft_allowed",
      "request": {
        "action": "cms.create_draft",
        "method": "POST",
        "payload": {
          "title": "New Blog Post",
          "content": "Content here..."
        }
      },
      "expected_result": "AUTHORIZED",
      "description": "Creating draft should succeed without approval"
    },
    {
      "name": "update_draft_allowed",
      "request": {
        "action": "cms.update_draft",
        "method": "PUT",
        "payload": {
          "draft_id": "draft-123",
          "content": "Updated content..."
        }
      },
      "expected_result": "AUTHORIZED",
      "description": "Updating draft should succeed without approval"
    },
    {
      "name": "publish_requires_approval",
      "request": {
        "action": "cms.publish",
        "method": "POST",
        "payload": {
          "draft_id": "draft-123"
        }
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_approval_required",
      "error_description_contains": "requires human approval",
      "approval_reference": "https://approval.acme-corp.com/agent-actions",
      "description": "Publishing should require human approval"
    }
  ],
  "metadata": {
    "specification_section": "7.6 (Oversight Requirement Enforcement), 5.2 (Oversight Claim)",
    "created": "2025-02-01",
    "version": "1.0"
  }
}
04-time-window-constrained.jsonToken with time window constraints
{
  "filename": "04-time-window-constrained.json",
  "name": "time-window-constrained",
  "description": "Token with time window constraints",
  "token_payload": {
    "iss": "https://as.example.com",
    "sub": "agent-scheduler-01",
    "aud": "https://api.example.com",
    "exp": 1735689600,
    "iat": 1735686000,
    "jti": "550e8400-e29b-41d4-a716-446655440020",
    "agent": {
      "id": "agent-scheduler-01",
      "type": "software",
      "operator": "org:acme-corp"
    },
    "task": {
      "id": "task-scheduled-001",
      "purpose": "scheduled_data_processing",
      "created_at": 1735686000
    },
    "capabilities": [
      {
        "action": "data.process",
        "description": "Process data during business hours only",
        "constraints": {
          "time_window": {
            "start": "2024-01-01T09:00:00Z",
            "end": "2024-12-31T17:00:00Z"
          },
          "allowed_methods": [
            "POST"
          ],
          "max_request_size": 10485760
        }
      }
    ],
    "delegation": {
      "depth": 0,
      "max_depth": 0,
      "chain": [
        "agent-scheduler-01"
      ]
    }
  },
  "test_cases": [
    {
      "name": "within_time_window",
      "request": {
        "action": "data.process",
        "method": "POST",
        "timestamp": "2024-06-15T12:00:00Z"
      },
      "expected_result": "AUTHORIZED",
      "description": "Request within time window should succeed"
    },
    {
      "name": "before_time_window",
      "request": {
        "action": "data.process",
        "method": "POST",
        "timestamp": "2023-12-31T12:00:00Z"
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_capability_expired",
      "description": "Request before time window should fail"
    },
    {
      "name": "after_time_window",
      "request": {
        "action": "data.process",
        "method": "POST",
        "timestamp": "2025-01-01T12:00:00Z"
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_capability_expired",
      "description": "Request after time window should fail"
    },
    {
      "name": "wrong_http_method",
      "request": {
        "action": "data.process",
        "method": "GET",
        "timestamp": "2024-06-15T12:00:00Z"
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_constraint_violation",
      "description": "Wrong HTTP method should fail"
    },
    {
      "name": "request_too_large",
      "request": {
        "action": "data.process",
        "method": "POST",
        "timestamp": "2024-06-15T12:00:00Z",
        "content_length": 20971520
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_constraint_violation",
      "http_status": 413,
      "description": "Request exceeding max size should fail"
    }
  ],
  "metadata": {
    "specification_section": "5.6.3 (Time-Based Constraints), 5.6.5 (Data Constraints)",
    "created": "2025-02-01",
    "version": "1.0"
  }
}

Invalid Tokens

Tokens that should fail validation

01-expired-token.jsonToken with expired 'exp' claim
{
  "filename": "01-expired-token.json",
  "name": "expired-token",
  "description": "Token with expired 'exp' claim",
  "token_payload": {
    "iss": "https://as.example.com",
    "sub": "agent-test-01",
    "aud": "https://api.example.com",
    "exp": 1704067200,
    "iat": 1704063600,
    "jti": "expired-token-001",
    "agent": {
      "id": "agent-test-01",
      "type": "llm-autonomous",
      "operator": "org:test"
    },
    "task": {
      "id": "task-001",
      "purpose": "test"
    },
    "capabilities": [
      {
        "action": "test.action"
      }
    ],
    "delegation": {
      "depth": 0,
      "max_depth": 2,
      "chain": [
        "agent-test-01"
      ]
    }
  },
  "validation_errors": [
    {
      "error_type": "token_expired",
      "error_code": "invalid_token",
      "http_status": 401,
      "description": "Token exp (1704067200 = 2024-01-01 00:00:00) is in the past",
      "specification_section": "7.1 (Standard Token Validation)",
      "validation_check": "exp > current_time (within clock skew tolerance)"
    }
  ],
  "test_cases": [
    {
      "name": "validate_expired_token",
      "current_time": 1735686000,
      "expected_result": "REJECTED",
      "error_code": "invalid_token",
      "error_description_contains": "expired",
      "http_status": 401
    },
    {
      "name": "validate_with_clock_skew",
      "current_time": 1704067500,
      "clock_skew_tolerance": 300,
      "expected_result": "ACCEPTED",
      "description": "Within 5-minute clock skew tolerance should still be valid"
    },
    {
      "name": "validate_beyond_clock_skew",
      "current_time": 1704068000,
      "clock_skew_tolerance": 300,
      "expected_result": "REJECTED",
      "error_code": "invalid_token",
      "description": "Beyond clock skew tolerance should fail"
    }
  ],
  "metadata": {
    "specification_section": "7.1, 12.8 (Clock Skew)",
    "created": "2025-02-01",
    "version": "1.0"
  }
}
02-wrong-audience.jsonToken with audience not matching Resource Server
{
  "filename": "02-wrong-audience.json",
  "name": "wrong-audience",
  "description": "Token with audience not matching Resource Server",
  "token_payload": {
    "iss": "https://as.example.com",
    "sub": "agent-test-01",
    "aud": "https://different-api.example.com",
    "exp": 1735689600,
    "iat": 1735686000,
    "jti": "wrong-aud-001",
    "agent": {
      "id": "agent-test-01",
      "type": "llm-autonomous",
      "operator": "org:test"
    },
    "task": {
      "id": "task-001",
      "purpose": "test"
    },
    "capabilities": [
      {
        "action": "test.action"
      }
    ],
    "delegation": {
      "depth": 0,
      "max_depth": 2,
      "chain": [
        "agent-test-01"
      ]
    }
  },
  "resource_server": {
    "audience": "https://api.example.com",
    "note": "RS expects 'https://api.example.com' but token has 'https://different-api.example.com'"
  },
  "validation_errors": [
    {
      "error_type": "invalid_audience",
      "error_code": "invalid_token",
      "http_status": 401,
      "description": "Token audience does not match Resource Server identifier",
      "specification_section": "7.1 (Standard Token Validation)",
      "validation_check": "aud == RS_AUDIENCE"
    }
  ],
  "test_cases": [
    {
      "name": "validate_wrong_audience",
      "resource_server_audience": "https://api.example.com",
      "expected_result": "REJECTED",
      "error_code": "invalid_token",
      "error_description_contains": "audience",
      "http_status": 401
    },
    {
      "name": "validate_correct_audience",
      "resource_server_audience": "https://different-api.example.com",
      "expected_result": "ACCEPTED",
      "description": "Token should be accepted by the RS matching the audience"
    }
  ],
  "metadata": {
    "specification_section": "7.1, 12.8 (RS Security)",
    "created": "2025-02-01",
    "version": "1.0"
  }
}
03-missing-required-claims.jsonTokens missing various required AAP claims
{
  "filename": "03-missing-required-claims.json",
  "name": "missing-required-claims",
  "description": "Tokens missing various required AAP claims",
  "variants": [
    {
      "variant_name": "missing_agent_claim",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "missing-agent-001",
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "test.action"
          }
        ]
      },
      "validation_error": {
        "error_code": "invalid_token",
        "http_status": 401,
        "description": "Token missing required 'agent' claim",
        "specification_section": "7.3 (Agent Identity Validation)"
      }
    },
    {
      "variant_name": "missing_task_claim",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "missing-task-001",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "capabilities": [
          {
            "action": "test.action"
          }
        ]
      },
      "validation_error": {
        "error_code": "invalid_token",
        "http_status": 401,
        "description": "Token missing required 'task' claim",
        "specification_section": "7.4 (Task Binding Validation)"
      }
    },
    {
      "variant_name": "missing_capabilities_claim",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "missing-capabilities-001",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        }
      },
      "validation_error": {
        "error_code": "invalid_token",
        "http_status": 401,
        "description": "Token missing required 'capabilities' claim",
        "specification_section": "7.5 (Capability Enforcement)"
      }
    },
    {
      "variant_name": "agent_missing_id",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "agent-no-id-001",
        "agent": {
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "test.action"
          }
        ]
      },
      "validation_error": {
        "error_code": "invalid_token",
        "http_status": 401,
        "description": "Agent claim missing required 'id' field",
        "specification_section": "7.3 (Agent Identity Validation)"
      }
    },
    {
      "variant_name": "task_missing_purpose",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "task-no-purpose-001",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001"
        },
        "capabilities": [
          {
            "action": "test.action"
          }
        ]
      },
      "validation_error": {
        "error_code": "invalid_token",
        "http_status": 401,
        "description": "Task claim missing required 'purpose' field",
        "specification_section": "7.4 (Task Binding Validation)"
      }
    }
  ],
  "metadata": {
    "specification_section": "7.1-7.5 (Validation Rules)",
    "created": "2025-02-01",
    "version": "1.0"
  }
}
04-excessive-delegation.jsonToken with delegation depth exceeding max_depth
{
  "filename": "04-excessive-delegation.json",
  "name": "excessive-delegation",
  "description": "Token with delegation depth exceeding max_depth",
  "token_payload": {
    "iss": "https://as.example.com",
    "sub": "agent-test-01",
    "aud": "https://api.example.com",
    "exp": 1735689600,
    "iat": 1735686000,
    "jti": "excessive-delegation-001",
    "agent": {
      "id": "agent-test-01",
      "type": "llm-autonomous",
      "operator": "org:test"
    },
    "task": {
      "id": "task-001",
      "purpose": "test"
    },
    "capabilities": [
      {
        "action": "test.action"
      }
    ],
    "delegation": {
      "depth": 3,
      "max_depth": 2,
      "chain": [
        "agent-test-01",
        "tool-a",
        "tool-b",
        "tool-c"
      ],
      "parent_jti": "parent-token-001"
    }
  },
  "validation_errors": [
    {
      "error_type": "excessive_delegation",
      "error_code": "aap_excessive_delegation",
      "http_status": 403,
      "description": "Delegation depth (3) exceeds maximum allowed depth (2)",
      "specification_section": "7.7 (Delegation Chain Validation), 5.7 (Delegation Semantics)",
      "validation_check": "delegation.depth <= delegation.max_depth"
    }
  ],
  "test_cases": [
    {
      "name": "validate_excessive_depth",
      "expected_result": "REJECTED",
      "error_code": "aap_excessive_delegation",
      "http_status": 403,
      "validation": {
        "depth": 3,
        "max_depth": 2,
        "check": "depth > max_depth"
      }
    }
  ],
  "metadata": {
    "specification_section": "7.7, 5.7",
    "created": "2025-02-01",
    "version": "1.0"
  }
}
05-invalid-delegation-chain.jsonTokens with malformed delegation chains
{
  "filename": "05-invalid-delegation-chain.json",
  "name": "invalid-delegation-chain",
  "description": "Tokens with malformed delegation chains",
  "variants": [
    {
      "variant_name": "chain_length_mismatch",
      "description": "Chain length doesn't match depth + 1",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "chain-mismatch-001",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "test.action"
          }
        ],
        "delegation": {
          "depth": 2,
          "max_depth": 3,
          "chain": [
            "agent-test-01",
            "tool-a"
          ]
        }
      },
      "validation_error": {
        "error_code": "aap_invalid_delegation_chain",
        "http_status": 403,
        "description": "Chain length (2) doesn't match depth+1 (3)",
        "validation_check": "len(chain) == depth + 1"
      }
    },
    {
      "variant_name": "empty_chain",
      "description": "Delegation chain is empty",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "empty-chain-001",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "test.action"
          }
        ],
        "delegation": {
          "depth": 1,
          "max_depth": 2,
          "chain": []
        }
      },
      "validation_error": {
        "error_code": "aap_invalid_delegation_chain",
        "http_status": 403,
        "description": "Chain is empty but depth is 1",
        "validation_check": "len(chain) > 0"
      }
    },
    {
      "variant_name": "missing_depth",
      "description": "Delegation claim missing required 'depth' field",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "missing-depth-001",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "test.action"
          }
        ],
        "delegation": {
          "max_depth": 2,
          "chain": [
            "agent-test-01"
          ]
        }
      },
      "validation_error": {
        "error_code": "aap_invalid_delegation_chain",
        "http_status": 403,
        "description": "Delegation claim missing required 'depth' field",
        "validation_check": "delegation.depth is not None"
      }
    }
  ],
  "metadata": {
    "specification_section": "7.7 (Delegation Chain Validation), 5.7",
    "created": "2025-02-01",
    "version": "1.0"
  }
}
06-invalid-action-format.jsonTokens with action names violating ABNF grammar
{
  "filename": "06-invalid-action-format.json",
  "name": "invalid-action-format",
  "description": "Tokens with action names violating ABNF grammar",
  "variants": [
    {
      "variant_name": "starts_with_digit",
      "description": "Action component starts with digit (invalid)",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "invalid-action-001",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "9api.read"
          }
        ],
        "delegation": {
          "depth": 0,
          "max_depth": 2,
          "chain": [
            "agent-test-01"
          ]
        }
      },
      "validation_error": {
        "error_code": "invalid_token",
        "http_status": 401,
        "description": "Action name '9api.read' violates ABNF grammar (component must start with letter)",
        "specification_section": "5.5 (Action Name Grammar)"
      }
    },
    {
      "variant_name": "double_dot",
      "description": "Action has double dot (empty component)",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "invalid-action-002",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "search..web"
          }
        ],
        "delegation": {
          "depth": 0,
          "max_depth": 2,
          "chain": [
            "agent-test-01"
          ]
        }
      },
      "validation_error": {
        "error_code": "invalid_token",
        "http_status": 401,
        "description": "Action name 'search..web' has empty component (double dot)",
        "specification_section": "5.5"
      }
    },
    {
      "variant_name": "starts_with_dot",
      "description": "Action starts with dot",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "invalid-action-003",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": ".search.web"
          }
        ],
        "delegation": {
          "depth": 0,
          "max_depth": 2,
          "chain": [
            "agent-test-01"
          ]
        }
      },
      "validation_error": {
        "error_code": "invalid_token",
        "http_status": 401,
        "description": "Action name '.search.web' starts with dot",
        "specification_section": "5.5"
      }
    },
    {
      "variant_name": "ends_with_dot",
      "description": "Action ends with dot",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "invalid-action-004",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "search.web."
          }
        ],
        "delegation": {
          "depth": 0,
          "max_depth": 2,
          "chain": [
            "agent-test-01"
          ]
        }
      },
      "validation_error": {
        "error_code": "invalid_token",
        "http_status": 401,
        "description": "Action name 'search.web.' ends with dot",
        "specification_section": "5.5"
      }
    },
    {
      "variant_name": "contains_wildcard",
      "description": "Action contains wildcard (not allowed)",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-test-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "invalid-action-005",
        "agent": {
          "id": "agent-test-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "cms.*"
          }
        ],
        "delegation": {
          "depth": 0,
          "max_depth": 2,
          "chain": [
            "agent-test-01"
          ]
        }
      },
      "validation_error": {
        "error_code": "invalid_token",
        "http_status": 401,
        "description": "Action name 'cms.*' contains wildcard (not allowed)",
        "specification_section": "5.5 (wildcards not permitted in this version)"
      }
    }
  ],
  "metadata": {
    "specification_section": "5.5 (Action Name Grammar)",
    "note": "ABNF: action-name = component *( \".\" component ), component = ALPHA *( ALPHA / DIGIT / \"-\" / \"_\" )",
    "created": "2025-02-01",
    "version": "1.0"
  }
}

Constraint Violations

Tests for constraint enforcement

01-rate-limit-exceeded.jsonToken with rate limiting constraints and violation scenarios
{
  "filename": "01-rate-limit-exceeded.json",
  "name": "rate-limit-exceeded",
  "description": "Token with rate limiting constraints and violation scenarios",
  "token_payload": {
    "iss": "https://as.example.com",
    "sub": "agent-rate-test-01",
    "aud": "https://api.example.com",
    "exp": 1735689600,
    "iat": 1735686000,
    "jti": "rate-limit-test-001",
    "agent": {
      "id": "agent-rate-test-01",
      "type": "llm-autonomous",
      "operator": "org:test"
    },
    "task": {
      "id": "task-rate-001",
      "purpose": "test_rate_limiting"
    },
    "capabilities": [
      {
        "action": "api.call",
        "constraints": {
          "max_requests_per_hour": 50,
          "max_requests_per_minute": 5
        }
      }
    ],
    "delegation": {
      "depth": 0,
      "max_depth": 2,
      "chain": [
        "agent-rate-test-01"
      ]
    }
  },
  "test_scenarios": [
    {
      "name": "hourly_limit_exceeded",
      "description": "51st request in current hour should fail",
      "setup": {
        "previous_requests_this_hour": 50,
        "current_hour_bucket": 481860
      },
      "request": {
        "action": "api.call",
        "method": "GET",
        "timestamp": 1735687200
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_constraint_violation",
      "http_status": 429,
      "error_description_contains": "rate limit",
      "retry_after_seconds": 3600
    },
    {
      "name": "hourly_limit_within",
      "description": "50th request in current hour should succeed",
      "setup": {
        "previous_requests_this_hour": 49,
        "current_hour_bucket": 481860
      },
      "request": {
        "action": "api.call",
        "method": "GET",
        "timestamp": 1735687200
      },
      "expected_result": "AUTHORIZED"
    },
    {
      "name": "minute_limit_exceeded",
      "description": "6th request in sliding 60-second window should fail",
      "setup": {
        "request_timestamps_last_60s": [
          1735686000,
          1735686010,
          1735686020,
          1735686030,
          1735686040
        ]
      },
      "request": {
        "action": "api.call",
        "method": "GET",
        "timestamp": 1735686050
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_constraint_violation",
      "http_status": 429
    },
    {
      "name": "minute_limit_sliding_window",
      "description": "Only 4 requests in sliding window, under limit of 5",
      "setup": {
        "request_timestamps": [
          1735685940,
          1735686010,
          1735686020,
          1735686030,
          1735686040
        ],
        "note": "First timestamp (1735685940) is > 60s ago and should be excluded"
      },
      "request": {
        "action": "api.call",
        "method": "GET",
        "timestamp": 1735686050
      },
      "expected_result": "AUTHORIZED"
    },
    {
      "name": "new_hour_resets_counter",
      "description": "Counter should reset at hour boundary",
      "setup": {
        "previous_requests_this_hour": 50,
        "previous_hour_bucket": 481860,
        "new_hour_bucket": 481861
      },
      "request": {
        "action": "api.call",
        "method": "GET",
        "timestamp": 1735690800,
        "note": "New hour, counter resets"
      },
      "expected_result": "AUTHORIZED"
    }
  ],
  "metadata": {
    "specification_section": "5.6.1 (Rate Limiting Constraints)",
    "rate_limit_semantics": {
      "max_requests_per_hour": "Fixed hourly window, resets at minute 0",
      "max_requests_per_minute": "Sliding 60-second window"
    },
    "created": "2025-02-01",
    "version": "1.0"
  }
}
02-domain-restrictions.jsonDomain allowlist and blocklist constraint violations
{
  "filename": "02-domain-restrictions.json",
  "name": "domain-restrictions",
  "description": "Domain allowlist and blocklist constraint violations",
  "token_payload": {
    "iss": "https://as.example.com",
    "sub": "agent-domain-test-01",
    "aud": "https://api.example.com",
    "exp": 1735689600,
    "iat": 1735686000,
    "jti": "domain-test-001",
    "agent": {
      "id": "agent-domain-test-01",
      "type": "llm-autonomous",
      "operator": "org:test"
    },
    "task": {
      "id": "task-domain-001",
      "purpose": "test_domain_restrictions"
    },
    "capabilities": [
      {
        "action": "fetch.data",
        "constraints": {
          "domains_allowed": [
            "example.org",
            "trusted.com"
          ],
          "domains_blocked": [
            "banned.example.org"
          ]
        }
      }
    ],
    "delegation": {
      "depth": 0,
      "max_depth": 2,
      "chain": [
        "agent-domain-test-01"
      ]
    }
  },
  "test_scenarios": [
    {
      "name": "allowed_domain_exact",
      "request": {
        "action": "fetch.data",
        "target_url": "https://example.org/data"
      },
      "expected_result": "AUTHORIZED",
      "description": "Exact match with allowed domain"
    },
    {
      "name": "allowed_domain_subdomain",
      "request": {
        "action": "fetch.data",
        "target_url": "https://api.example.org/data"
      },
      "expected_result": "AUTHORIZED",
      "description": "Subdomain of allowed domain (DNS suffix matching)"
    },
    {
      "name": "allowed_domain_deep_subdomain",
      "request": {
        "action": "fetch.data",
        "target_url": "https://deep.nested.example.org/data"
      },
      "expected_result": "AUTHORIZED",
      "description": "Deep subdomain of allowed domain"
    },
    {
      "name": "blocked_domain_precedence",
      "request": {
        "action": "fetch.data",
        "target_url": "https://banned.example.org/data"
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_domain_not_allowed",
      "description": "Blocked domain takes precedence over allowed parent domain"
    },
    {
      "name": "not_in_allowlist",
      "request": {
        "action": "fetch.data",
        "target_url": "https://malicious.com/data"
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_domain_not_allowed",
      "description": "Domain not in allowlist"
    },
    {
      "name": "not_suffix_match",
      "request": {
        "action": "fetch.data",
        "target_url": "https://notexample.org/data"
      },
      "expected_result": "FORBIDDEN",
      "error_code": "aap_domain_not_allowed",
      "description": "Domain 'notexample.org' is not a suffix match for 'example.org'"
    },
    {
      "name": "case_sensitive",
      "request": {
        "action": "fetch.data",
        "target_url": "https://EXAMPLE.ORG/data"
      },
      "expected_result": "AUTHORIZED",
      "note": "Domain matching SHOULD be case-insensitive per DNS standards"
    },
    {
      "name": "port_ignored",
      "request": {
        "action": "fetch.data",
        "target_url": "https://example.org:8080/data"
      },
      "expected_result": "AUTHORIZED",
      "description": "Port number should not affect domain matching"
    },
    {
      "name": "path_ignored",
      "request": {
        "action": "fetch.data",
        "target_url": "https://example.org/path/to/resource?query=value"
      },
      "expected_result": "AUTHORIZED",
      "description": "Path and query parameters should not affect domain matching"
    }
  ],
  "metadata": {
    "specification_section": "5.6.2 (Domain and Network Constraints)",
    "matching_algorithm": "DNS suffix matching (rightmost). subdomain.example.org matches example.org in allowlist.",
    "precedence": "domains_blocked takes precedence over domains_allowed",
    "created": "2025-02-01",
    "version": "1.0"
  }
}

Edge Cases

Clock skew, delegation limits, and edge scenarios

01-clock-skew.jsonEdge cases for clock skew tolerance (5-minute window)
{
  "filename": "01-clock-skew.json",
  "name": "clock-skew-tolerance",
  "description": "Edge cases for clock skew tolerance (5-minute window)",
  "token_payload": {
    "iss": "https://as.example.com",
    "sub": "agent-clock-test-01",
    "aud": "https://api.example.com",
    "exp": 1735686000,
    "iat": 1735682400,
    "jti": "clock-skew-test-001",
    "agent": {
      "id": "agent-clock-test-01",
      "type": "llm-autonomous",
      "operator": "org:test"
    },
    "task": {
      "id": "task-clock-001",
      "purpose": "test_clock_skew"
    },
    "capabilities": [
      {
        "action": "test.action"
      }
    ],
    "delegation": {
      "depth": 0,
      "max_depth": 2,
      "chain": [
        "agent-clock-test-01"
      ]
    }
  },
  "test_scenarios": [
    {
      "name": "exactly_expired",
      "description": "Token at exact expiration time",
      "validation_time": 1735686000,
      "token_exp": 1735686000,
      "expected_result": "REJECTED",
      "reason": "Token is expired at exp time (exclusive boundary)"
    },
    {
      "name": "one_second_after_exp",
      "description": "Token one second after expiration",
      "validation_time": 1735686001,
      "token_exp": 1735686000,
      "expected_result": "REJECTED",
      "reason": "Token is expired"
    },
    {
      "name": "within_skew_tolerance",
      "description": "Token 4 minutes past expiration (within 5-min tolerance)",
      "validation_time": 1735686240,
      "token_exp": 1735686000,
      "clock_skew_tolerance": 300,
      "expected_result": "ACCEPTED",
      "reason": "Within 5-minute clock skew tolerance"
    },
    {
      "name": "at_skew_boundary",
      "description": "Token exactly 5 minutes past expiration",
      "validation_time": 1735686300,
      "token_exp": 1735686000,
      "clock_skew_tolerance": 300,
      "expected_result": "ACCEPTED",
      "reason": "At boundary of 5-minute tolerance (inclusive)"
    },
    {
      "name": "beyond_skew_tolerance",
      "description": "Token 5 minutes + 1 second past expiration",
      "validation_time": 1735686301,
      "token_exp": 1735686000,
      "clock_skew_tolerance": 300,
      "expected_result": "REJECTED",
      "reason": "Beyond 5-minute clock skew tolerance"
    },
    {
      "name": "future_token_within_skew",
      "description": "Token not yet valid but within skew (if nbf present)",
      "validation_time": 1735681800,
      "token_nbf": 1735682100,
      "token_exp": 1735686000,
      "clock_skew_tolerance": 300,
      "expected_result": "ACCEPTED",
      "reason": "nbf is 5 minutes in future but within skew tolerance"
    },
    {
      "name": "future_token_beyond_skew",
      "description": "Token not yet valid and beyond skew",
      "validation_time": 1735681700,
      "token_nbf": 1735682100,
      "token_exp": 1735686000,
      "clock_skew_tolerance": 300,
      "expected_result": "REJECTED",
      "reason": "nbf is 6+ minutes in future, beyond skew tolerance"
    }
  ],
  "metadata": {
    "specification_section": "7.1 (Standard Token Validation), 12.8 (Clock Skew)",
    "clock_skew_tolerance": "5 minutes (300 seconds) RECOMMENDED",
    "note": "Clock skew tolerance should be applied to both exp and nbf validation",
    "created": "2025-02-01",
    "version": "1.0"
  }
}
02-maximum-delegation-depth.jsonEdge cases for delegation at maximum depth
{
  "filename": "02-maximum-delegation-depth.json",
  "name": "maximum-delegation-depth",
  "description": "Edge cases for delegation at maximum depth",
  "base_token": {
    "iss": "https://as.example.com",
    "sub": "agent-delegation-test-01",
    "aud": "https://api.example.com",
    "exp": 1735689600,
    "iat": 1735686000,
    "jti": "delegation-depth-base",
    "agent": {
      "id": "agent-delegation-test-01",
      "type": "llm-autonomous",
      "operator": "org:test"
    },
    "task": {
      "id": "task-delegation-001",
      "purpose": "test_max_depth"
    },
    "capabilities": [
      {
        "action": "test.action",
        "constraints": {
          "max_depth": 3
        }
      }
    ],
    "delegation": {
      "depth": 0,
      "max_depth": 3,
      "chain": [
        "agent-delegation-test-01"
      ]
    }
  },
  "test_scenarios": [
    {
      "name": "depth_0_valid",
      "description": "Original token at depth 0",
      "token": {
        "delegation": {
          "depth": 0,
          "max_depth": 3,
          "chain": [
            "agent-delegation-test-01"
          ]
        }
      },
      "expected_result": "VALID",
      "can_delegate": true
    },
    {
      "name": "depth_1_valid",
      "description": "First delegation at depth 1",
      "token": {
        "delegation": {
          "depth": 1,
          "max_depth": 3,
          "chain": [
            "agent-delegation-test-01",
            "tool-a"
          ],
          "parent_jti": "delegation-depth-base"
        }
      },
      "expected_result": "VALID",
      "can_delegate": true
    },
    {
      "name": "depth_2_valid",
      "description": "Second delegation at depth 2",
      "token": {
        "delegation": {
          "depth": 2,
          "max_depth": 3,
          "chain": [
            "agent-delegation-test-01",
            "tool-a",
            "tool-b"
          ],
          "parent_jti": "delegation-depth-1"
        }
      },
      "expected_result": "VALID",
      "can_delegate": true
    },
    {
      "name": "depth_3_at_max",
      "description": "At maximum depth (depth == max_depth)",
      "token": {
        "delegation": {
          "depth": 3,
          "max_depth": 3,
          "chain": [
            "agent-delegation-test-01",
            "tool-a",
            "tool-b",
            "tool-c"
          ],
          "parent_jti": "delegation-depth-2"
        }
      },
      "expected_result": "VALID",
      "can_delegate": false,
      "note": "Token is valid but cannot be delegated further"
    },
    {
      "name": "depth_4_exceeds",
      "description": "Exceeds maximum depth",
      "token": {
        "delegation": {
          "depth": 4,
          "max_depth": 3,
          "chain": [
            "agent-delegation-test-01",
            "tool-a",
            "tool-b",
            "tool-c",
            "tool-d"
          ],
          "parent_jti": "delegation-depth-3"
        }
      },
      "expected_result": "INVALID",
      "error_code": "aap_excessive_delegation",
      "http_status": 403
    },
    {
      "name": "as_prevents_depth_4",
      "description": "AS should prevent issuing token at depth 4",
      "token_exchange_request": {
        "parent_token_depth": 3,
        "parent_token_max_depth": 3
      },
      "as_behavior": "MUST_REJECT",
      "error_code": "invalid_grant",
      "error_description_contains": "delegation depth",
      "reason": "AS must not issue token if resulting depth >= max_depth"
    },
    {
      "name": "zero_max_depth",
      "description": "max_depth=0 means no delegation allowed",
      "token": {
        "delegation": {
          "depth": 0,
          "max_depth": 0,
          "chain": [
            "agent-no-delegation"
          ]
        }
      },
      "expected_result": "VALID",
      "can_delegate": false,
      "note": "Token is valid but delegation is prohibited"
    },
    {
      "name": "attempt_delegate_when_prohibited",
      "description": "Attempting to delegate when max_depth=0",
      "token_exchange_request": {
        "parent_token_depth": 0,
        "parent_token_max_depth": 0
      },
      "as_behavior": "MUST_REJECT",
      "error_code": "invalid_grant",
      "reason": "Cannot delegate when max_depth=0"
    }
  ],
  "metadata": {
    "specification_section": "5.7 (Delegation Chain Semantics), 7.7 (Delegation Validation)",
    "depth_calculation": "depth=0 (origin), depth=n (n delegations via Token Exchange)",
    "validation_rule": "depth <= max_depth (MUST enforce by both AS and RS)",
    "created": "2025-02-01",
    "version": "1.0"
  }
}
03-empty-constraints.jsonEdge cases for capabilities with minimal or no constraints
{
  "filename": "03-empty-constraints.json",
  "name": "empty-and-minimal-constraints",
  "description": "Edge cases for capabilities with minimal or no constraints",
  "test_scenarios": [
    {
      "name": "capability_no_constraints",
      "description": "Capability with no constraints object",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-minimal-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "minimal-001",
        "agent": {
          "id": "agent-minimal-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "unrestricted.action"
          }
        ],
        "delegation": {
          "depth": 0,
          "max_depth": 2,
          "chain": [
            "agent-minimal-01"
          ]
        }
      },
      "expected_result": "VALID",
      "request_test": {
        "action": "unrestricted.action",
        "expected": "AUTHORIZED",
        "note": "No constraints means action is allowed without restrictions"
      }
    },
    {
      "name": "capability_empty_constraints",
      "description": "Capability with empty constraints object",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-empty-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "empty-constraints-001",
        "agent": {
          "id": "agent-empty-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "unrestricted.action",
            "constraints": {}
          }
        ],
        "delegation": {
          "depth": 0,
          "max_depth": 2,
          "chain": [
            "agent-empty-01"
          ]
        }
      },
      "expected_result": "VALID",
      "request_test": {
        "action": "unrestricted.action",
        "expected": "AUTHORIZED",
        "note": "Empty constraints object is equivalent to no constraints"
      }
    },
    {
      "name": "empty_capabilities_array",
      "description": "Token with empty capabilities array (invalid)",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-no-caps-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "no-caps-001",
        "agent": {
          "id": "agent-no-caps-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [],
        "delegation": {
          "depth": 0,
          "max_depth": 2,
          "chain": [
            "agent-no-caps-01"
          ]
        }
      },
      "expected_result": "INVALID",
      "error_code": "invalid_token",
      "reason": "capabilities array MUST contain at least one capability",
      "json_schema_violation": "minItems: 1 in aap-capabilities.schema.json"
    },
    {
      "name": "multiple_capabilities_for_same_action",
      "description": "Multiple capabilities with same action name (OR semantics)",
      "token_payload": {
        "iss": "https://as.example.com",
        "sub": "agent-multi-01",
        "aud": "https://api.example.com",
        "exp": 1735689600,
        "iat": 1735686000,
        "jti": "multi-caps-001",
        "agent": {
          "id": "agent-multi-01",
          "type": "llm-autonomous",
          "operator": "org:test"
        },
        "task": {
          "id": "task-001",
          "purpose": "test"
        },
        "capabilities": [
          {
            "action": "api.call",
            "constraints": {
              "domains_allowed": [
                "example.org"
              ],
              "max_requests_per_hour": 100
            }
          },
          {
            "action": "api.call",
            "constraints": {
              "domains_allowed": [
                "trusted.com"
              ],
              "max_requests_per_hour": 50
            }
          }
        ],
        "delegation": {
          "depth": 0,
          "max_depth": 2,
          "chain": [
            "agent-multi-01"
          ]
        }
      },
      "expected_result": "VALID",
      "request_tests": [
        {
          "action": "api.call",
          "target_url": "https://example.org/data",
          "expected": "AUTHORIZED",
          "note": "Matches first capability"
        },
        {
          "action": "api.call",
          "target_url": "https://trusted.com/data",
          "expected": "AUTHORIZED",
          "note": "Matches second capability (OR semantics)"
        },
        {
          "action": "api.call",
          "target_url": "https://other.com/data",
          "expected": "FORBIDDEN",
          "error_code": "aap_domain_not_allowed",
          "note": "Doesn't match either capability's domain constraints"
        }
      ],
      "note": "First matching capability is used. OR semantics: any matching capability allows the action."
    }
  ],
  "metadata": {
    "specification_section": "5.6 (Constraint Semantics), 7.5 (Capability Enforcement)",
    "constraint_semantics": {
      "multiple_capabilities": "OR - any matching capability allows action",
      "multiple_constraints": "AND - all constraints must be satisfied"
    },
    "created": "2025-02-01",
    "version": "1.0"
  }
}

Using Test Vectors

Test vectors are organized by category. Each vector includes a token payload and expected validation results.

Python Example:

import json
from your_implementation import validate_token

# Load test vector
with open('valid-tokens/01-basic-research-agent.json') as f:
    test_vector = json.load(f)

# Validate
result = validate_token(test_vector['token_payload'])
assert result == test_vector['expected_result']