← 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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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']