{ "openapi": "3.0.0", "info": { "title": "APort API - Runtime Trust Rail for AI Agents", "description": "The runtime trust rail that makes KYA (Know Your Agent) actionable at the point of action. Pre-action authorization with sub-100ms verification decisions and cryptographically signed receipts.", "version": "1.0.0", "contact": { "name": "APort", "url": "https://aport.io", "email": "support@aport.io" }, "x-logo": { "url": "https://avatars.githubusercontent.com/u/233553076?s=200&v=4", "altText": "APort - The Passport Officer for AI Agents" } }, "servers": [ { "url": "https://aport.io", "description": "Production server" }, { "url": "https://aport.io", "description": "Development server" }, { "url": "http://localhost:8787", "description": "Local development server" } ], "components": { "schemas": { "Passport": { "title": "Open Agent Passport", "description": "Schema for Open Agent Passport (OAP) v1.0 passport objects", "type": "object", "required": [ "passport_id", "kind", "spec_version", "owner_id", "owner_type", "status", "assurance_level", "capabilities", "limits", "regions", "created_at", "updated_at", "version" ], "properties": { "passport_id": { "type": "string", "format": "uuid", "description": "Unique identifier for the passport (UUID v4)", "example": "550e8400-e29b-41d4-a716-446655440000" }, "kind": { "type": "string", "enum": [ "template", "instance" ], "description": "Type of passport - template (canonical identity) or instance (tenant-specific)", "example": "template" }, "spec_version": { "type": "string", "const": "oap/1.0", "description": "OAP specification version", "example": "oap/1.0" }, "template_id": { "type": "string", "format": "uuid", "description": "Template passport ID (required for instances)", "example": "550e8400-e29b-41d4-a716-446655440001" }, "owner_id": { "type": "string", "description": "Unique identifier for the owner (organization or user)", "example": "org_12345678" }, "owner_type": { "type": "string", "enum": [ "org", "user" ], "description": "Type of owner (organization or user)", "example": "org" }, "assurance_level": { "type": "string", "enum": [ "L0", "L1", "L2", "L3", "L4KYC", "L4FIN" ], "description": "Assurance level of the passport owner", "example": "L2" }, "status": { "type": "string", "enum": [ "draft", "active", "suspended", "revoked" ], "description": "Current status of the passport", "example": "active" }, "capabilities": { "type": "array", "items": { "type": "object", "required": [ "id" ], "properties": { "id": { "type": "string", "pattern": "^[a-z0-9]+(\\.[a-z0-9]+)*$", "description": "Capability identifier", "example": "finance.payment.refund" }, "params": { "type": "object", "description": "Optional parameters for the capability", "additionalProperties": true, "example": { "max_amount": 5000, "currency": "USD" } } } }, "description": "List of capabilities granted to the agent", "example": [ { "id": "finance.payment.refund", "params": { "max_amount": 5000, "currency": "USD" } }, { "id": "data.export" } ] }, "limits": { "type": "object", "description": "Operational limits for the agent", "properties": { "finance.payment.refund": { "type": "object", "properties": { "currency_limits": { "type": "object", "patternProperties": { "^[A-Z]{3}$": { "type": "object", "properties": { "max_per_tx": { "type": "integer", "minimum": 0, "description": "Maximum amount per transaction in minor units" }, "daily_cap": { "type": "integer", "minimum": 0, "description": "Maximum daily total in minor units" } } } } }, "reason_codes": { "type": "array", "items": { "type": "string" }, "description": "Allowed reason codes for refunds" }, "idempotency_required": { "type": "boolean", "description": "Whether idempotency keys are required" } } }, "data.export": { "type": "object", "properties": { "max_rows": { "type": "integer", "minimum": 1, "description": "Maximum number of rows per export" }, "allow_pii": { "type": "boolean", "description": "Whether PII can be included in exports" }, "allowed_collections": { "type": "array", "items": { "type": "string" }, "description": "Allowed data collections for export" } } }, "messaging.send": { "type": "object", "properties": { "msgs_per_min": { "type": "integer", "minimum": 1, "description": "Maximum messages per minute" }, "msgs_per_day": { "type": "integer", "minimum": 1, "description": "Maximum messages per day" }, "allowed_recipients": { "oneOf": [ { "type": "array", "items": { "type": "string" }, "description": "Simple list of allowed recipient IDs" }, { "type": "array", "items": { "type": "object", "required": [ "id" ], "properties": { "id": { "type": "string", "description": "Recipient identifier (username, email, account ID, etc.)" }, "limits": { "type": "object", "properties": { "currency": { "type": "string", "pattern": "^[A-Z]{3}$", "description": "ISO 4217 currency code" }, "max_amount": { "type": "integer", "minimum": 0, "description": "Maximum amount per transaction in minor units" }, "daily_cap": { "type": "integer", "minimum": 0, "description": "Daily spending cap in minor units" } } } } }, "description": "List of recipients with per-recipient limits" } ] }, "approval_required": { "type": "boolean", "description": "Whether messages require manual approval before sending" } } }, "payments.payout": { "type": "object", "properties": { "supported_currencies": { "type": "array", "items": { "type": "string", "pattern": "^[A-Z]{3}$" }, "description": "Supported currencies for payouts" }, "currency_limits": { "type": "object", "patternProperties": { "^[A-Z]{3}$": { "type": "object", "properties": { "max_per_tx": { "type": "integer", "minimum": 0, "description": "Maximum amount per transaction in minor units" }, "max_daily_amount": { "type": "integer", "minimum": 0, "description": "Maximum daily total in minor units" } } } } }, "allowed_destination_types": { "type": "array", "items": { "type": "string" }, "description": "Allowed destination account types" }, "allowed_recipients": { "oneOf": [ { "type": "array", "items": { "type": "string" }, "description": "Simple list of allowed recipient IDs" }, { "type": "array", "items": { "type": "object", "required": [ "id" ], "properties": { "id": { "type": "string", "description": "Recipient identifier" }, "limits": { "type": "object", "properties": { "currency": { "type": "string", "pattern": "^[A-Z]{3}$" }, "max_amount": { "type": "integer", "minimum": 0 }, "daily_cap": { "type": "integer", "minimum": 0 } } } } } } ] }, "approval_required": { "type": "boolean", "description": "Whether payouts require manual approval" }, "max_payouts_per_day": { "type": "integer", "minimum": 1, "description": "Maximum number of payouts per day" }, "compliance_checks_required": { "type": "boolean", "description": "Whether compliance checks are required" } } }, "repo.release.publish": { "type": "object", "properties": { "allowed_branches": { "type": "array", "items": { "type": "string" }, "description": "Allowed branches for releases" }, "max_releases_per_day": { "type": "integer", "minimum": 1, "description": "Maximum releases per day" }, "require_signed_artifacts": { "type": "boolean", "description": "Whether artifacts must be signed" } } } }, "additionalProperties": true }, "regions": { "type": "array", "items": { "type": "string", "pattern": "^[A-Z]{2}(-[A-Z]{2})?$" }, "description": "Geographic regions where the agent is authorized to operate", "example": [ "US", "EU", "CA" ] }, "metadata": { "type": "object", "description": "Additional metadata for the passport", "additionalProperties": true }, "created_at": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp of creation", "example": "2024-01-01T00:00:00Z" }, "updated_at": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp of last update", "example": "2024-01-15T10:30:00Z" }, "version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$", "description": "Version of the passport schema", "example": "1.0.0" }, "parent_agent_id": { "type": "string", "format": "uuid", "description": "Parent template passport ID (required for instances)", "example": "550e8400-e29b-41d4-a716-446655440001" } }, "additionalProperties": false }, "Decision": { "title": "Open Agent Passport Decision", "description": "Schema for Open Agent Passport (OAP) v1.0 decision objects", "type": "object", "required": [ "decision_id", "passport_id", "policy_id", "owner_id", "assurance_level", "allow", "reasons", "issued_at", "expires_at", "passport_digest", "signature", "kid" ], "properties": { "decision_id": { "type": "string", "format": "uuid", "description": "Unique identifier for the decision (UUID v4)", "example": "550e8400-e29b-41d4-a716-446655440000" }, "policy_id": { "type": "string", "pattern": "^[a-z0-9]+(\\.[a-z0-9]+)*\\.v[0-9]+$", "description": "Policy pack identifier", "example": "finance.payment.refund.v1" }, "agent_id": { "type": "string", "format": "uuid", "description": "Agent ID that was evaluated", "example": "550e8400-e29b-41d4-a716-446655440001" }, "owner_id": { "type": "string", "description": "Owner ID from the passport", "example": "org_12345678" }, "assurance_level": { "type": "string", "enum": [ "L0", "L1", "L2", "L3", "L4KYC", "L4FIN" ], "description": "Assurance level from the passport", "example": "L2" }, "allow": { "type": "boolean", "description": "Whether the action is allowed", "example": true }, "reasons": { "type": "array", "items": { "type": "object", "required": [ "code" ], "properties": { "code": { "type": "string", "description": "Error or success code", "example": "oap.limit_exceeded" }, "message": { "type": "string", "description": "Human-readable message", "example": "Transaction amount exceeds daily limit" } } }, "description": "Array of reasons for the decision", "minItems": 1 }, "created_at": { "type": "string", "format": "date-time", "description": "When the decision was created", "example": "2024-01-15T10:30:00Z" }, "expires_in": { "type": "integer", "minimum": 0, "description": "Number of seconds until the decision expires", "example": 3600 }, "passport_digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$", "description": "SHA-256 hash of JCS-canonicalized passport view", "example": "sha256:abcd1234efgh5678ijkl9012mnop3456qrst7890uvwx1234yzab5678cdef" }, "signature": { "type": "string", "pattern": "^ed25519:[A-Za-z0-9+/=]+$", "description": "Ed25519 signature over JCS-canonicalized decision payload", "example": "ed25519:abcd1234efgh5678ijkl9012mnop3456qrst7890uvwx1234yzab5678cdef==" }, "kid": { "type": "string", "pattern": "^oap:(registry|owner):[a-zA-Z0-9._-]+$", "description": "Key identifier for signature verification", "example": "oap:registry:key-2025-01" }, "decision_token": { "type": "string", "description": "Optional compact JWT for sub-TTL caching", "example": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..." } }, "additionalProperties": false }, "ErrorResponse": { "type": "object", "required": [ "error" ], "properties": { "error": { "type": "string", "description": "Error code", "example": "not_found" }, "message": { "type": "string", "description": "Human-readable error message", "example": "Agent passport not found" } } }, "CreateApiKeyRequest": { "type": "object", "required": [ "owner_id", "owner_type", "scopes" ], "properties": { "owner_id": { "type": "string", "description": "ID of the user or organization", "example": "ap_user_12345678" }, "owner_type": { "type": "string", "enum": [ "user", "org" ], "description": "Type of the owner", "example": "user" }, "scopes": { "type": "array", "items": { "type": "string", "enum": [ "issue", "update", "status", "read", "list_agents", "read_audit", "manage_webhooks", "manage_keys" ] }, "description": "API key scopes", "example": [ "read", "list_agents" ] }, "name": { "type": "string", "description": "Optional human-readable name", "example": "My API Key" } } }, "CreateApiKeyResponse": { "type": "object", "required": [ "key_id", "key", "owner_id", "owner_type", "scopes", "created_at" ], "properties": { "key_id": { "type": "string", "example": "apk_abc123def456" }, "key": { "type": "string", "description": "API key (shown only once)", "example": "apk_xyz789uvw012" }, "owner_id": { "type": "string", "example": "ap_user_12345678" }, "owner_type": { "type": "string", "enum": [ "user", "org" ], "example": "user" }, "scopes": { "type": "array", "items": { "type": "string" }, "example": [ "read", "list_agents" ] }, "created_at": { "type": "string", "format": "date-time", "example": "2025-01-15T10:30:00Z" }, "name": { "type": "string", "example": "My API Key" } } }, "Alert": { "type": "object", "required": [ "id", "rule_id", "triggered_at", "status", "severity", "message", "metric_value", "threshold" ], "properties": { "id": { "type": "string", "example": "p95_latency_high_1640995200000_abc123" }, "rule_id": { "type": "string", "example": "p95_latency_high" }, "triggered_at": { "type": "string", "format": "date-time", "example": "2024-01-15T10:30:00Z" }, "resolved_at": { "type": "string", "format": "date-time", "example": "2024-01-15T10:35:00Z" }, "status": { "type": "string", "enum": [ "active", "resolved" ], "example": "active" }, "severity": { "type": "string", "enum": [ "low", "medium", "high", "critical" ], "example": "high" }, "message": { "type": "string", "example": "P95 Latency High: 95 exceeded threshold of 80" }, "metric_value": { "type": "number", "example": 95 }, "threshold": { "type": "number", "example": 80 }, "metadata": { "type": "object", "additionalProperties": true } } }, "AlertRule": { "type": "object", "required": [ "id", "name", "condition", "threshold", "operator", "metric_type", "enabled", "cooldown_minutes" ], "properties": { "id": { "type": "string", "example": "p95_latency_high" }, "name": { "type": "string", "example": "P95 Latency High" }, "condition": { "type": "string", "example": "p95_latency" }, "threshold": { "type": "number", "example": 80 }, "operator": { "type": "string", "enum": [ "gt", "lt", "eq", "gte", "lte" ], "example": "gt" }, "metric_type": { "type": "string", "example": "verify_latency" }, "enabled": { "type": "boolean", "example": true }, "cooldown_minutes": { "type": "number", "example": 5 }, "last_triggered": { "type": "string", "format": "date-time", "example": "2024-01-15T10:30:00Z" } } }, "MetricsResponse": { "type": "object", "required": [ "ok", "metrics", "slo_data", "slo_breach" ], "properties": { "ok": { "type": "boolean", "description": "Success status", "example": true }, "metrics": { "type": "object", "properties": { "period": { "type": "string", "example": "day" }, "start_time": { "type": "string", "example": "2024-01-01T00:00:00Z" }, "end_time": { "type": "string", "example": "2024-01-02T00:00:00Z" }, "total_requests": { "type": "number", "example": 10000 }, "success_rate": { "type": "number", "example": 99.9 }, "error_rate": { "type": "number", "example": 0.1 }, "p50_latency": { "type": "number", "example": 50 }, "p95_latency": { "type": "number", "example": 80 }, "p99_latency": { "type": "number", "example": 120 }, "avg_latency": { "type": "number", "example": 60 }, "blocked_attempts": { "type": "number", "example": 5 }, "avg_approval_time": { "type": "number", "example": 2000 }, "top_agents": { "type": "array", "items": { "type": "object", "properties": { "agent_id": { "type": "string", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "requests": { "type": "number", "example": 1000 } } } }, "region_breakdown": { "type": "array", "items": { "type": "object", "properties": { "region": { "type": "string", "example": "us-east-1" }, "requests": { "type": "number", "example": 5000 }, "avg_latency": { "type": "number", "example": 55 } } } } } }, "slo_data": { "type": "object", "properties": { "period": { "type": "string", "example": "2024-01-01T00:00:00Z to 2024-01-02T00:00:00Z" }, "availability": { "type": "number", "example": 99.9 }, "p95_latency": { "type": "number", "example": 80 }, "error_rate": { "type": "number", "example": 0.1 }, "mtts": { "type": "number", "example": 60 }, "blocked_attempts": { "type": "number", "example": 5 }, "total_requests": { "type": "number", "example": 10000 } } }, "slo_breach": { "type": "object", "properties": { "breached": { "type": "boolean", "example": false }, "breaches": { "type": "array", "items": { "type": "string" }, "example": [] } } } } }, "SyntheticProbeRequest": { "type": "object", "required": [ "agent_ids", "regions" ], "properties": { "agent_ids": { "type": "array", "items": { "type": "string" }, "description": "List of agent IDs to probe", "example": [ "ap_a2d10232c6534523812423eec8a1425c", "ap_456" ] }, "regions": { "type": "array", "items": { "type": "string" }, "description": "List of regions to probe from", "example": [ "us-east-1", "eu-west-1", "ap-southeast-1" ] }, "probe_type": { "type": "string", "enum": [ "verify", "health" ], "description": "Type of probe to perform", "example": "verify" } } }, "SyntheticProbeResponse": { "type": "object", "required": [ "ok", "message", "results" ], "properties": { "ok": { "type": "boolean", "description": "Success status", "example": true }, "message": { "type": "string", "description": "Success message", "example": "Synthetic probes completed" }, "results": { "type": "array", "items": { "type": "object", "properties": { "agent_id": { "type": "string", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "region": { "type": "string", "example": "us-east-1" }, "success": { "type": "boolean", "example": true }, "latency": { "type": "number", "example": 45 }, "error": { "type": "string", "example": null } } } } } } }, "securitySchemes": { "BearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" }, "ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "X-API-Key" }, "OrgKeyAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "OrgKeySecret", "description": "Use the organization key secret as the bearer token and include the x-org-key-id header." } } }, "paths": { "/api/about/{agent_id}": { "get": { "summary": "Get agent passport Agent Passport page", "description": "Retrieve public information about an agent passport for display on Agent Passport pages", "operationId": "getAboutPage", "tags": [ "Public" ], "parameters": [ { "name": "agent_id", "in": "path", "required": true, "description": "The agent passport ID", "schema": { "type": "string", "example": "ap_a2d10232c6534523812423eec8a1425c" } } ], "responses": { "200": { "description": "Agent passport Agent Passport page data", "content": { "application/json": { "schema": { "type": "object", "properties": { "agent_id": { "type": "string", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "name": { "type": "string", "example": "Customer Support Bot" }, "owner": { "type": "string", "example": "Acme Corp" }, "description": { "type": "string", "example": "AI-powered customer support agent" }, "status": { "type": "string", "enum": [ "active", "suspended", "revoked" ], "example": "active" }, "verification_status": { "type": "string", "enum": [ "unverified", "email_verified", "github_verified" ], "example": "email_verified" }, "verification_method": { "type": "string", "example": "email" }, "created_at": { "type": "string", "format": "date-time", "example": "2024-01-15T10:30:00Z" }, "updated_at": { "type": "string", "format": "date-time", "example": "2024-01-15T10:30:00Z" }, "badge_url": { "type": "string", "example": "https://aport.io/badge/ap_a2d10232c6534523812423eec8a1425c.svg" } } } } } }, "404": { "description": "Agent passport not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "not_found" } } } } } } } } }, "/api/agents/{agent_id}/did.json": { "get": { "summary": "Resolve W3C DID Document", "description": "Resolves a did:web Decentralized Identifier (DID) according to the W3C DID specification. Returns a W3C DID Document containing verification methods, service endpoints, and agent metadata.", "operationId": "getDIDDocument", "tags": [ "DIDs" ], "parameters": [ { "in": "path", "name": "agent_id", "required": true, "schema": { "type": "string", "pattern": "^ap_[a-zA-Z0-9_-]+$" }, "description": "Unique agent identifier", "example": "ap_abc123" } ], "responses": { "200": { "description": "DID Document retrieved successfully", "content": { "application/did+ld+json": { "schema": { "type": "object", "required": [ "@context", "id", "verificationMethod" ], "properties": { "@context": { "type": "array", "description": "JSON-LD context for DID Document", "items": { "type": "string" }, "example": [ "https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/ed25519-2020/v1" ] }, "id": { "type": "string", "description": "The DID subject (did:web format)", "example": "did:web:api.aport.io:agents:ap_abc123" }, "controller": { "type": "string", "description": "DID controller (usually same as id)", "example": "did:web:api.aport.io:agents:ap_abc123" }, "verificationMethod": { "type": "array", "description": "Cryptographic verification methods", "items": { "type": "object", "properties": { "id": { "type": "string", "example": "did:web:api.aport.io:agents:ap_abc123#key-1" }, "type": { "type": "string", "example": "Ed25519VerificationKey2020" }, "controller": { "type": "string", "example": "did:web:api.aport.io:agents:ap_abc123" }, "publicKeyMultibase": { "type": "string", "description": "Base58-encoded public key", "example": "z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH" } } } }, "authentication": { "type": "array", "description": "Authentication methods", "items": { "type": "string" }, "example": [ "did:web:api.aport.io:agents:ap_abc123#key-1" ] }, "assertionMethod": { "type": "array", "description": "Assertion methods for issuing VCs", "items": { "type": "string" }, "example": [ "did:web:api.aport.io:agents:ap_abc123#key-1" ] }, "service": { "type": "array", "description": "Service endpoints", "items": { "type": "object", "properties": { "id": { "type": "string", "example": "did:web:api.aport.io:agents:ap_abc123#passport-service" }, "type": { "type": "string", "example": "AgentPassportService" }, "serviceEndpoint": { "oneOf": [ { "type": "string" }, { "type": "object" } ], "example": { "passport": "https://api.aport.io/api/passports/ap_abc123", "verify": "https://api.aport.io/api/verify/ap_abc123", "vc": "https://api.aport.io/api/passports/ap_abc123?format=vc" } } } } }, "alsoKnownAs": { "type": "array", "description": "Alternative identifiers (e.g., repo URL)", "items": { "type": "string" }, "example": [ "https://github.com/acme/agent-bot" ] } } } } } }, "400": { "description": "Bad request - invalid agent ID", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "invalid_agent_id", "message": "Agent ID must start with 'ap_'" } } } }, "403": { "description": "Forbidden - passport expired", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "passport_expired", "message": "Passport has expired" } } } }, "404": { "description": "Passport not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "passport_not_found", "message": "No passport found for this agent ID" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "Failed to generate DID document" } } } } } } }, "/api/assurance": { "get": { "summary": "Get assurance levels", "description": "Retrieve all available assurance levels with metadata", "operationId": "getAssuranceLevels", "tags": [ "Assurance" ], "responses": { "200": { "description": "Assurance levels retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "levels": { "type": "array", "items": { "type": "object", "properties": { "level": { "type": "string", "enum": [ "L0", "L1", "L2", "L3", "L4KYC", "L4FIN" ] }, "name": { "type": "string" }, "description": { "type": "string" }, "requirements": { "type": "array", "items": { "type": "string" } }, "verificationMethods": { "type": "array", "items": { "type": "string" } }, "riskLevel": { "type": "string", "enum": [ "low", "medium", "high", "very_high" ] }, "order": { "type": "number" }, "color": { "type": "string" }, "icon": { "type": "string" } } } } } }, "example": { "levels": [ { "level": "L0", "name": "Self-Attested", "description": "Owner self-declares identity without verification", "requirements": [ "Self-declaration" ], "verificationMethods": [ "self_attested" ], "riskLevel": "very_high", "order": 0, "color": "#EF4444", "icon": "warning" } ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/assurance/validate": { "post": { "summary": "Validate assurance level and method", "description": "Validate assurance level and method combinations", "operationId": "validateAssurance", "tags": [ "Assurance" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "level": { "type": "string", "description": "Assurance level to validate" }, "method": { "type": "string", "description": "Assurance method to validate" } }, "required": [ "level", "method" ] } } } }, "responses": { "200": { "description": "Validation successful", "content": { "application/json": { "schema": { "type": "object", "properties": { "valid": { "type": "boolean" }, "level": { "type": "string" }, "method": { "type": "string" } } } } } }, "400": { "description": "Validation failed", "content": { "application/json": { "schema": { "type": "object", "properties": { "valid": { "type": "boolean" }, "errors": { "type": "array", "items": { "type": "string" } } } } } } } } } }, "/api/attestation/hashes/{tenant_id}": { "get": { "summary": "Get audit hash-chain for tenant", "description": "Returns the last N audit hashes for a tenant to enable tampering detection", "operationId": "getAuditHashes", "tags": [ "Attestation" ], "parameters": [ { "name": "tenant_id", "in": "path", "required": true, "description": "The tenant ID (organization ID)", "schema": { "type": "string", "pattern": "^ap_org_", "example": "ap_org_acme" } }, { "name": "limit", "in": "query", "description": "Number of recent hashes to return", "schema": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 100, "example": 100 } }, { "name": "agent_id", "in": "query", "description": "Filter by specific agent ID", "schema": { "type": "string", "example": "ap_123456789" } }, { "name": "policy_pack_id", "in": "query", "description": "Filter by specific policy pack ID", "schema": { "type": "string", "example": "refunds" } }, { "name": "since", "in": "query", "description": "Only return hashes since this timestamp (ISO 8601)", "schema": { "type": "string", "format": "date-time", "example": "2024-01-01T00:00:00Z" } } ], "responses": { "200": { "description": "Audit hash-chain retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "tenant_id": { "type": "string", "example": "ap_org_acme" }, "region": { "type": "string", "example": "US" }, "total_entries": { "type": "integer", "example": 150 }, "hashes": { "type": "array", "items": { "type": "object", "properties": { "decision_id": { "type": "string", "example": "dec_1234567890" }, "agent_id": { "type": "string", "example": "ap_123456789" }, "policy_pack_id": { "type": "string", "example": "refunds" }, "decision": { "type": "string", "enum": [ "allow", "deny" ], "example": "allow" }, "reason": { "type": "string", "example": "Within daily limit" }, "created_at": { "type": "string", "format": "date-time", "example": "2024-01-15T10:30:00Z" }, "prev_hash": { "type": "string", "nullable": true, "example": "sha256:abc123..." }, "record_hash": { "type": "string", "example": "sha256:def456..." }, "org_id": { "type": "string", "example": "ap_org_acme" } } } }, "chain_integrity": { "type": "object", "properties": { "valid": { "type": "boolean", "example": true }, "first_hash": { "type": "string", "nullable": true, "example": "sha256:abc123..." }, "last_hash": { "type": "string", "nullable": true, "example": "sha256:def456..." }, "break_points": { "type": "array", "items": { "type": "integer" }, "example": [] } } }, "generated_at": { "type": "string", "format": "date-time", "example": "2024-01-15T10:30:00Z" }, "expires_at": { "type": "string", "format": "date-time", "example": "2024-01-16T10:30:00Z" } } } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Invalid tenant ID format" } } } } } }, "404": { "description": "Tenant not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Tenant not found" } } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "Failed to retrieve audit hashes" } } } } } } } } }, "/api/claim/confirm": { "get": { "summary": "Confirm agent passport claim via token", "description": "Verify and complete the agent passport claim process using a magic link token", "operationId": "confirmClaim", "tags": [ "Claims" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "token", "in": "query", "required": true, "description": "The claim token received via email", "schema": { "type": "string", "example": "eyJhZ2VudF9pZCI6ImFwXzEyMyIsImVtYWlsIjoib3duZXJAZXhhbXBsZS5jb20ifQ==.abc123..." } } ], "responses": { "200": { "description": "Claim confirmed successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Agent passport claimed successfully" }, "agent_id": { "type": "string", "example": "ap_a2d10232c6534523812423eec8a1425c" } } } } } }, "400": { "description": "Invalid or missing token" }, "404": { "description": "Token not found or expired" }, "500": { "description": "Internal server error" } } } }, "/api/claim/request": { "post": { "summary": "Request agent passport claim via email", "description": "Send a magic link email to claim an agent passport", "operationId": "requestClaim", "tags": [ "Claims" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "agent_id": { "type": "string", "description": "The agent passport ID to claim", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "email": { "type": "string", "format": "email", "description": "Email address to send the claim link to", "example": "owner@example.com" }, "turnOffNotification": { "type": "boolean", "description": "Whether to turn off notification", "example": false } }, "required": [ "agent_id", "email" ] } } } }, "responses": { "200": { "description": "Claim request sent successfully" }, "400": { "description": "Missing required fields" }, "404": { "description": "Agent passport not found" }, "500": { "description": "Internal server error" } } } }, "/api/claim/token-info": { "get": { "summary": "Get claim token information", "description": "Retrieve information about a claim token", "operationId": "getClaimTokenInfo", "tags": [ "Claims" ], "parameters": [ { "name": "token", "in": "query", "required": true, "description": "The claim token", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Token information retrieved successfully" }, "400": { "description": "Missing token parameter" }, "404": { "description": "Token not found or expired" }, "500": { "description": "Internal server error" } } } }, "/api/keys/{key_id}": { "get": { "summary": "Get API key details", "description": "Get details of a specific API key (without the actual key)", "operationId": "getApiKey", "tags": [ "API Keys" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "in": "path", "name": "key_id", "required": true, "schema": { "type": "string" }, "description": "API key ID" } ], "responses": { "200": { "description": "API key details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiKeyListItem" } } } }, "403": { "description": "Forbidden - insufficient permissions" }, "404": { "description": "API key not found" }, "500": { "description": "Internal server error" } } }, "put": { "summary": "Activate API key", "description": "Activate a revoked API key (re-enable it)", "operationId": "activateApiKey", "tags": [ "API Keys" ], "parameters": [ { "in": "path", "name": "key_id", "required": true, "schema": { "type": "string" }, "description": "API key ID" } ], "responses": { "200": { "description": "API key activated successfully" }, "403": { "description": "Forbidden - insufficient permissions" }, "404": { "description": "API key not found" }, "500": { "description": "Internal server error" } } }, "post": { "summary": "Revoke API key", "description": "Revoke an API key (mark as inactive but keep in database)", "operationId": "revokeApiKey", "tags": [ "API Keys" ], "parameters": [ { "in": "path", "name": "key_id", "required": true, "schema": { "type": "string" }, "description": "API key ID" } ], "responses": { "200": { "description": "API key revoked successfully" }, "403": { "description": "Forbidden - insufficient permissions" }, "404": { "description": "API key not found" }, "500": { "description": "Internal server error" } } }, "delete": { "summary": "Delete API key", "description": "Delete an API key completely", "operationId": "deleteApiKey", "tags": [ "API Keys" ], "parameters": [ { "in": "path", "name": "key_id", "required": true, "schema": { "type": "string" }, "description": "API key ID" } ], "responses": { "200": { "description": "API key deleted successfully" }, "403": { "description": "Forbidden - insufficient permissions" }, "404": { "description": "API key not found" }, "500": { "description": "Internal server error" } } }, "patch": { "summary": "Rotate API key", "description": "Generate a new API key and revoke the old one", "operationId": "rotateApiKey", "tags": [ "API Keys" ], "parameters": [ { "in": "path", "name": "key_id", "required": true, "schema": { "type": "string" }, "description": "API key ID" } ], "responses": { "200": { "description": "API key rotated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateApiKeyResponse" } } } }, "403": { "description": "Forbidden - insufficient permissions" }, "404": { "description": "API key not found" }, "500": { "description": "Internal server error" } } } }, "/api/keys": { "post": { "summary": "Create API key", "description": "Create a new API key for a user or organization", "operationId": "createApiKey", "tags": [ "API Keys" ], "security": [ { "BearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateApiKeyRequest" } } } }, "responses": { "201": { "description": "API key created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateApiKeyResponse" } } } }, "400": { "description": "Bad request" }, "403": { "description": "Forbidden - insufficient permissions" }, "500": { "description": "Internal server error" } } }, "get": { "summary": "List API keys", "description": "List API keys for the authenticated user or organization", "operationId": "listApiKeys", "tags": [ "API Keys" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "in": "query", "name": "owner_type", "schema": { "type": "string", "enum": [ "user", "org" ] }, "description": "Filter by owner type" }, { "in": "query", "name": "owner_id", "schema": { "type": "string" }, "description": "Filter by owner ID" } ], "responses": { "200": { "description": "List of API keys", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ApiKeyListItem" } } } } }, "400": { "description": "Bad request" }, "403": { "description": "Forbidden - insufficient permissions" }, "500": { "description": "Internal server error" } } } }, "/api/openapi-json": { "get": { "summary": "Get OpenAPI JSON specification", "description": "Returns the complete OpenAPI 3.0 specification in JSON format", "operationId": "getOpenAPIJson", "tags": [ "API Documentation" ], "responses": { "200": { "description": "OpenAPI specification in JSON format", "content": { "application/json": { "schema": { "type": "object", "description": "Complete OpenAPI 3.0 specification" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/org/status": { "post": { "summary": "Update organization status", "description": "Update organization status (active/suspended) using organization key authentication.\nThis endpoint allows organizations to programmatically manage their status.\nThe organization key must be provided in the Authorization header with x-org-key-id header.\nSupports multi-tenant/multi-region architecture.\n", "operationId": "updateOrgStatus", "tags": [ "Organizations" ], "security": [ { "OrgKeyAuth": [] } ], "parameters": [ { "name": "x-org-key-id", "in": "header", "required": true, "schema": { "type": "string" }, "description": "Organization key ID that matches the bearer secret." }, { "name": "Authorization", "in": "header", "required": true, "schema": { "type": "string" }, "description": "Org key secret in bearer format: Bearer ." }, { "in": "header", "name": "x-org-key-id", "required": true, "schema": { "type": "string" }, "description": "Organization key identifier paired with the Bearer secret." } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "status" ], "properties": { "status": { "type": "string", "enum": [ "active", "suspended" ], "description": "New status for the organization", "example": "suspended" } } } } } }, "responses": { "200": { "description": "Organization status updated successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "org_id", "status", "updated_at", "message" ], "properties": { "ok": { "type": "boolean", "example": true }, "org_id": { "type": "string", "example": "ap_org_12345678" }, "status": { "type": "string", "enum": [ "active", "suspended" ], "example": "suspended" }, "updated_at": { "type": "string", "format": "date-time", "example": "2025-01-15T10:30:00Z" }, "message": { "type": "string", "example": "Organization status updated successfully" } } } } } }, "400": { "description": "Bad request - invalid status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "bad_request", "message": "Status must be 'active' or 'suspended'" } } } }, "401": { "description": "Unauthorized - invalid org key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "unauthorized", "message": "Invalid organization key" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "not_found", "message": "Organization not found" } } } }, "429": { "description": "Rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "rate_limit_exceeded", "message": "Too many requests, please try again later" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "Failed to update organization status" } } } } } } }, "/api/org/update": { "post": { "summary": "Update agent passport via organization key", "description": "Update an agent passport using organization key authentication.\nAllows organizations to programmatically manage their agents (suspend/resume, update contact info, etc.).\nThe organization key must be provided in the Authorization header with x-org-key-id header.\nOnly allows status changes between 'active' and 'suspended'.\nSupports multi-tenant/multi-region architecture with proper tenant resolution.\n", "operationId": "updateAgentViaOrgKey", "tags": [ "Organizations" ], "security": [ { "OrgKeyAuth": [] } ], "parameters": [ { "name": "x-org-key-id", "in": "header", "required": true, "schema": { "type": "string" }, "description": "Organization key ID that pairs with the bearer secret (e.g., orgkey_abc123). Required for all org key-authenticated requests." }, { "name": "Authorization", "in": "header", "required": true, "schema": { "type": "string" }, "description": "Org key secret in bearer format: Bearer ." } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "agent_id" ], "properties": { "agent_id": { "type": "string", "description": "Agent ID to update (must belong to the organization)", "pattern": "^ap_[a-zA-Z0-9]+$", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "status": { "type": "string", "enum": [ "active", "suspended" ], "description": "New status for the agent (only active/suspended allowed)", "example": "suspended" }, "webhook_url": { "type": "string", "format": "uri", "description": "Webhook URL for notifications", "example": "https://example.com/webhook" }, "email": { "type": "string", "format": "email", "description": "Contact email for the agent", "example": "contact@example.com" } } } } } }, "responses": { "200": { "description": "Agent updated successfully. Returns the updated status and actor information so the caller can confirm which org key performed the change.", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "message", "agent_id", "status" ], "properties": { "ok": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Agent updated successfully" }, "agent_id": { "type": "string", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "status": { "type": "string", "example": "suspended" }, "updated_by": { "type": "string", "description": "Actor who performed the update", "example": "org_key:orgkey_abc123" } } } } } }, "400": { "description": "Bad request - validation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "invalid_status", "message": "Org keys can only change status between 'active' and 'suspended'" } } } }, "401": { "description": "Unauthorized - invalid or missing org key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "invalid_org_key", "message": "Invalid organization key" } } } }, "403": { "description": "Forbidden - org key mismatch", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "org_key_mismatch", "message": "Organization key does not match agent ownership" } } } }, "404": { "description": "Agent not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "not_found", "message": "Agent not found" } } } }, "429": { "description": "Too many requests - rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "rate_limit_exceeded", "message": "Too many org requests. Please try again later." } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "Failed to update agent" } } } } } } }, "/api/orgs/{id}/issue": { "post": { "summary": "Delegated passport issuance by organization", "description": "Create a passport for an agent on behalf of an organization with multi-tenant/multi-region support.\n\n**Access Control:**\n- Requires organization admin privileges (`org_admin` role) OR\n- API key owned by the organization (API key's `owner_id` must match the organization ID)\n- The organization must have `can_issue_for_others` permission enabled\n\n**Passport Metadata:**\n- The created passport will have `issued_by`, `provisioned_by_org_id`, and `sponsor_orgs` set to the organization ID\n- This allows the organization to update the passport later, even if `owner_id` is a user (delegated issuance scenario)\n\n**Assurance Providers:**\n- The organization must have configured assurance providers (via admin endpoint)\n- The `assurance` field must specify a provider that the organization is configured to use\n- Supports pending owner claim flow for delegated issuance.\n\n**Owner Options:**\n- **Org as Owner**: Set `org_as_owner: true` to make the organization the owner (no claim required, passport is immediately claimed)\n- **User Claim Flow**: Set `pending_owner` to create an unclaimed passport that requires claim\n- `owner_id` cannot be provided directly - use `org_as_owner` or `pending_owner` instead\n\n**Claim Flow (when pending_owner is provided):**\n- `pending_owner` is required (must have either email or github_username)\n- `contact` can be provided directly or via `pending_owner.email` (will use `pending_owner.email` if `contact` not provided)\n- Claim email is automatically sent to `pending_owner.email` unless `send_claim_email: false` is set\n- When user clicks claim link, their account is auto-created (if needed) and passport is claimed\n- User does NOT need to sign up separately - account is created from email during claim\n", "operationId": "issuePassportForOrg", "tags": [ "Organizations" ], "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Organization ID (must start with 'ap_org_')", "schema": { "type": "string", "pattern": "^ap_org_[a-zA-Z0-9]+$", "example": "ap_org_12345678" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "name", "role", "description", "regions", "pending_owner" ], "optional": [ "contact" ], "properties": { "name": { "type": "string", "description": "Human-readable name for the agent", "example": "Platform AI Assistant", "minLength": 1, "maxLength": 100 }, "role": { "type": "string", "description": "Functional role of the agent", "example": "customer_support", "enum": [ "agent", "assistant", "tool", "service" ] }, "description": { "type": "string", "description": "Detailed description of the agent's purpose and capabilities", "example": "AI assistant for customer support queries", "minLength": 10, "maxLength": 1000 }, "capabilities": { "type": "array", "description": "List of agent capabilities with optional parameters", "items": { "type": "object", "required": [ "id" ], "properties": { "id": { "type": "string", "example": "finance.payment.refund" }, "params": { "type": "object", "additionalProperties": true } } } }, "regions": { "type": "array", "description": "Geographic regions where the agent can operate", "items": { "type": "string", "enum": [ "US", "EU", "CA", "AP", "global" ] }, "example": [ "US", "CA" ], "minItems": 1 }, "contact": { "type": "string", "format": "email", "description": "Contact email for the agent owner. If not provided, will use pending_owner.email", "example": "owner@example.com" }, "links": { "type": "object", "properties": { "homepage": { "type": "string", "format": "uri" }, "docs": { "type": "string", "format": "uri" }, "repo": { "type": "string", "format": "uri" } } }, "categories": { "type": "array", "items": { "type": "string" }, "description": "Agent categories" }, "framework": { "type": "array", "items": { "type": "string" }, "description": "AI frameworks used" }, "logo_url": { "type": "string", "format": "uri", "description": "Agent logo URL" }, "status": { "type": "string", "enum": [ "draft", "active", "suspended", "revoked" ], "default": "active" }, "org_as_owner": { "type": "boolean", "description": "If true, the organization becomes the owner of the passport (no claim required).\nPassport is immediately claimed and owned by the issuing organization.\nCannot be used together with pending_owner.\n", "example": false }, "pending_owner": { "type": "object", "description": "Intended owner for claim flow. Required if org_as_owner is false.\nMust have either email or github_username.\nEmail is required for claim flow. If contact is not provided, pending_owner.email will be used as contact.\n", "properties": { "email": { "type": "string", "format": "email", "example": "newowner@example.com" }, "github_username": { "type": "string", "example": "newowner" } } }, "send_claim_email": { "type": "boolean", "description": "Whether to send claim email automatically. Defaults to true.\nSet to false if your organization wants to send claim emails through your own system.\nClaim token is still generated and stored - you can retrieve it via API or share the claim link manually.\n", "default": true, "example": false }, "assurance": { "type": "object", "description": "Explicitly specify which assurance provider to use for this passport issuance.\nMust match one of the organization's configured assurance providers.\nRequired fields: type, assurance_level. Optional: proof.\n", "properties": { "type": { "type": "string", "description": "Provider type (e.g., \"kyc\", \"kyb\", \"financial\")", "example": "kyb" }, "assurance_level": { "type": "string", "description": "Assurance level (e.g., \"L4KYC\", \"L4FIN\")", "enum": [ "L0", "L1", "L2", "L3", "L4KYC", "L4FIN" ], "example": "L4KYC" }, "proof": { "type": "object", "description": "Optional proof/evidence for the assurance", "additionalProperties": true, "example": { "verification_id": "ver_123456", "verified_at": "2024-01-15T10:30:00Z" } } } } } } } } }, "responses": { "201": { "description": "Passport issued successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "agent_id", "claimed", "message" ], "properties": { "ok": { "type": "boolean", "example": true }, "agent_id": { "type": "string", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "claimed": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "Passport issued and ready for claim" }, "claim_email_sent": { "type": "boolean", "description": "Whether claim email was sent (if pending_owner.email provided)", "example": true } } } } } }, "400": { "description": "Bad request - validation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "missing_required_fields": { "summary": "Missing required fields", "value": { "error": "missing_required_fields", "message": "Missing required fields: name, role, description, regions. Note: contact can be provided directly or via pending_owner.email." } }, "owner_id_not_allowed": { "summary": "owner_id not allowed", "value": { "error": "validation_failed", "message": "owner_id cannot be provided. Use pending_owner to create an unclaimed passport that requires claim." } }, "pending_owner_required": { "summary": "pending_owner required", "value": { "error": "validation_failed", "message": "pending_owner is required. Must have either email or github_username." } } } } } }, "401": { "description": "Unauthorized - invalid or missing authentication", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "unauthorized", "message": "Valid authentication required" } } } }, "403": { "description": "Forbidden - insufficient permissions or organization cannot issue", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "insufficient_permissions": { "summary": "Insufficient permissions", "value": { "error": "forbidden", "message": "Insufficient permissions - organization admin required" } }, "org_cannot_issue": { "summary": "Organization cannot issue", "value": { "error": "org_cannot_issue", "message": "Organization does not have permission to issue passports for others" } }, "invalid_assurance_provider": { "summary": "Invalid assurance provider", "value": { "error": "validation_failed", "message": "Invalid assurance provider. Available providers: [{\"type\":\"kyb\",\"assurance_level\":\"L4KYC\"}]" } } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "not_found", "message": "Organization not found" } } } }, "409": { "description": "Conflict - agent already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "conflict", "message": "Agent with this name already exists" } } } }, "429": { "description": "Too many requests - rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "rate_limit_exceeded", "message": "Too many requests, please try again later" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "Failed to issue passport" } } } } } } }, "/api/orgs/{id}/issuer": { "get": { "summary": "Get organization issuer status", "description": "Get whether the organization can issue passports for others.\nPublic endpoint - no authentication required.\nSupports multi-tenant/multi-region architecture.\n", "operationId": "getOrgIssuerStatus", "tags": [ "Organizations" ], "parameters": [ { "in": "path", "name": "id", "required": true, "schema": { "type": "string", "pattern": "^ap_org_[a-zA-Z0-9]+$" }, "description": "Organization ID", "example": "ap_org_12345678" } ], "responses": { "200": { "description": "Organization issuer status", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "org_id", "can_issue_for_others", "message" ], "properties": { "ok": { "type": "boolean", "example": true }, "org_id": { "type": "string", "example": "ap_org_12345678" }, "can_issue_for_others": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Issuer status retrieved successfully" } } } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/orgs/{id}/members/{user_id}": { "delete": { "summary": "Remove organization member", "description": "Remove a member from the organization.\nRequires organization admin or member management permissions.\nSupports multi-tenant/multi-region architecture.\n", "operationId": "removeOrgMember", "tags": [ "Organizations" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "in": "path", "name": "id", "required": true, "schema": { "type": "string", "pattern": "^ap_org_[a-zA-Z0-9]+$" }, "description": "Organization ID", "example": "ap_org_12345678" }, { "in": "path", "name": "user_id", "required": true, "schema": { "type": "string", "pattern": "^ap_user_[a-zA-Z0-9]+$" }, "description": "User ID to remove", "example": "ap_user_12345678" } ], "responses": { "200": { "description": "Member removed successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "message" ], "properties": { "ok": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Member removed successfully" } } } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or member not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "patch": { "summary": "Update member role", "description": "Update the role of an organization member.\nRequires organization admin or member management permissions.\nSupports multi-tenant/multi-region architecture.\n", "operationId": "updateMemberRole", "tags": [ "Organizations" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "in": "path", "name": "id", "required": true, "schema": { "type": "string", "pattern": "^ap_org_[a-zA-Z0-9]+$" }, "description": "Organization ID", "example": "ap_org_12345678" }, { "in": "path", "name": "user_id", "required": true, "schema": { "type": "string", "pattern": "^ap_user_[a-zA-Z0-9]+$" }, "description": "User ID to update", "example": "ap_user_12345678" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "role" ], "properties": { "role": { "type": "string", "enum": [ "org_admin", "org_member", "org_issuer", "org_security", "org_billing", "org_auditor" ], "description": "New role for the member", "example": "org_member" } } } } } }, "responses": { "200": { "description": "Member role updated successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "message" ], "properties": { "ok": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Member role updated successfully" } } } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization or member not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/orgs/{id}/members": { "post": { "summary": "Add or update organization member", "description": "Add a new member to the organization or update their role.\nRequires organization admin or member management permissions.\nSupports multi-tenant/multi-region architecture.\n", "operationId": "addOrgMember", "tags": [ "Organizations" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "in": "path", "name": "id", "required": true, "schema": { "type": "string", "pattern": "^ap_org_[a-zA-Z0-9]+$" }, "description": "Organization ID", "example": "ap_org_12345678" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "user_id", "role" ], "properties": { "user_id": { "type": "string", "description": "User ID to add/update", "example": "ap_user_12345678" }, "role": { "type": "string", "enum": [ "org_admin", "org_member", "org_issuer", "org_security", "org_billing", "org_auditor" ], "description": "Member role", "example": "org_admin" } } } } } }, "responses": { "200": { "description": "Member added/updated successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "data", "message" ], "properties": { "ok": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/OrgMembership" }, "message": { "type": "string", "example": "Member added successfully" } } } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "get": { "summary": "List organization members", "description": "Get all members of the organization.\nRequires organization membership (any role).\nSupports multi-tenant/multi-region architecture.\n", "operationId": "listOrgMembers", "tags": [ "Organizations" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "in": "path", "name": "id", "required": true, "schema": { "type": "string", "pattern": "^ap_org_[a-zA-Z0-9]+$" }, "description": "Organization ID", "example": "ap_org_12345678" } ], "responses": { "200": { "description": "List of organization members", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "data", "message" ], "properties": { "ok": { "type": "boolean", "example": true }, "data": { "type": "array", "items": { "$ref": "#/components/schemas/OrgMembership" } }, "message": { "type": "string", "example": "Members retrieved successfully" } } } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/orgs/{id}/orgkey": { "post": { "summary": "Generate organization key", "description": "Generate an HMAC key for the organization to suspend/resume their agents programmatically.\nThe secret is shown only once and must be stored securely.\nRequires organization admin or key management permissions.\nSupports multi-tenant/multi-region architecture.\n", "operationId": "generateOrgKey", "tags": [ "Organizations" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "in": "path", "name": "id", "required": true, "schema": { "type": "string", "pattern": "^ap_org_[a-zA-Z0-9]+$" }, "description": "Organization ID", "example": "ap_org_12345678" } ], "responses": { "201": { "description": "Organization key generated successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "data", "message" ], "properties": { "ok": { "type": "boolean", "example": true }, "data": { "type": "object", "required": [ "org_key_id", "secret" ], "properties": { "org_key_id": { "type": "string", "description": "Organization key ID (store this)", "example": "orgkey_abc123def456" }, "secret": { "type": "string", "description": "Organization key secret (shown only once - store securely)", "example": "orgkey_xyz789uvw012" } } }, "message": { "type": "string", "example": "Organization key generated successfully" } } } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "429": { "description": "Too many requests - rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/orgs/{id}": { "get": { "summary": "Get organization by ID", "description": "Retrieves detailed information about a specific organization with multi-tenant/multi-region support.\nReturns organization details including members, permissions, and user-specific access information.\nSupports both JWT and API key authentication.\n", "operationId": "getOrganization", "tags": [ "Organizations" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Organization ID (must start with 'ap_org_')", "schema": { "type": "string", "pattern": "^ap_org_[a-zA-Z0-9]+$", "example": "ap_org_12345678" } } ], "responses": { "200": { "description": "Organization details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "data", "message" ], "properties": { "ok": { "type": "boolean", "example": true }, "data": { "type": "object", "required": [ "org_id", "name", "contact_email", "user_permissions" ], "properties": { "org_id": { "type": "string", "example": "ap_org_12345678" }, "name": { "type": "string", "example": "Acme Corp" }, "domain": { "type": "string", "example": "acme.com" }, "contact_email": { "type": "string", "format": "email", "example": "admin@acme.com" }, "members": { "type": "array", "items": { "$ref": "#/components/schemas/OrgMembership" } }, "created_at": { "type": "string", "format": "date-time", "example": "2025-01-15T10:30:00Z" }, "updated_at": { "type": "string", "format": "date-time", "example": "2025-01-15T10:30:00Z" }, "assurance_level": { "type": "string", "enum": [ "L0", "L1", "L2", "L3", "L4KYC", "L4FIN" ], "example": "L1" }, "can_issue_for_others": { "type": "boolean", "example": false }, "user_role": { "type": "string", "enum": [ "org_admin", "org_member", "org_issuer", "org_security", "org_billing", "org_auditor" ], "example": "org_admin" }, "org_key_id": { "type": "string", "example": "orgkey_abc123" }, "status": { "type": "string", "enum": [ "active", "suspended" ], "example": "active" }, "user_permissions": { "type": "object", "properties": { "can_view": { "type": "boolean", "example": true }, "can_edit": { "type": "boolean", "example": true }, "can_admin": { "type": "boolean", "example": true }, "can_manage_members": { "type": "boolean", "example": true }, "can_manage_keys": { "type": "boolean", "example": true } } } } }, "message": { "type": "string", "example": "Organization retrieved successfully" } } } } } }, "400": { "description": "Bad request - invalid organization ID", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "bad_request", "message": "Organization ID is required" } } } }, "401": { "description": "Unauthorized - invalid or missing authentication", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "unauthorized", "message": "Valid authentication required" } } } }, "403": { "description": "Forbidden - user is not a member of this organization", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "forbidden", "message": "Access denied - not a member of this organization" } } } }, "404": { "description": "Organization not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "not_found", "message": "Organization not found" } } } }, "429": { "description": "Too many requests - rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "rate_limit_exceeded", "message": "Too many requests, please try again later" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "Failed to get organization details" } } } } } } }, "/api/passports/{agent_id}": { "get": { "summary": "Get passport details", "description": "Retrieves detailed information about a specific agent passport by agent ID.\n\n**Access Control:**\n- Passport owner (user or org) can read their own passports\n- Organization members with `org_admin`, `org_issuer`, or `org_member` role can read org-owned passports\n- Organizations that issued/provisioned/sponsored a passport can read it, even if `owner_id` is a user\n- API keys owned by an org can read passports owned by that org or issued by that org\n- Platform admins can read any passport\n- Public access is allowed for basic passport data (DID service endpoints)\n", "operationId": "getPassportDetails", "tags": [ "Passports" ], "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "in": "path", "name": "agent_id", "required": true, "schema": { "type": "string", "pattern": "^ap_[a-zA-Z0-9_-]+$" }, "description": "Unique agent identifier", "example": "ap_agent_123456789" }, { "in": "query", "name": "format", "schema": { "type": "string", "enum": [ "json", "vc", "vp" ], "default": "json" }, "description": "Response format - 'json' for native OAP format, 'vc' for W3C Verifiable Credential format, 'vp' for W3C Verifiable Presentation format", "example": "vc" } ], "responses": { "200": { "description": "Passport details retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "success", "requestId" ], "properties": { "success": { "type": "boolean", "example": true }, "requestId": { "type": "string", "description": "Unique request identifier", "example": "req_123456789" }, "agent_id": { "type": "string", "example": "ap_agent_123456789" }, "name": { "type": "string", "example": "Acme Support Bot" }, "links": { "type": "object", "properties": { "homepage": { "type": "string", "example": "https://example.com" }, "docs": { "type": "string", "example": "https://docs.example.com" }, "repo": { "type": "string", "example": "https://github.com/example/repo" } } }, "admin_notes": { "type": "string", "description": "Admin notes (admin only)", "example": "Internal notes about this agent" }, "internal_metadata": { "type": "object", "description": "Internal metadata (admin only)", "example": { "internal_id": "12345" } }, "audit_trail": { "type": "array", "description": "Audit trail (admin only)", "items": { "type": "object" } } } } } } }, "400": { "description": "Bad request - invalid agent ID", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "invalid_agent_id", "message": "Agent ID must start with 'ap_'" } } } }, "401": { "description": "Unauthorized - invalid or missing authentication", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "unauthorized", "message": "Valid authentication required" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "forbidden", "message": "You don't have permission to access this passport" } } } }, "404": { "description": "Passport not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "passport_not_found", "message": "Passport with the specified agent ID was not found" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/passports/{agent_id}/status": { "put": { "summary": "Update passport status", "description": "Changes the status of an existing passport (suspend, activate, revoke) with comprehensive validation, Verifiable Attestation, and admin support. Triggers webhooks and cache invalidation.", "operationId": "updatePassportStatus", "tags": [ "Passports" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "agent_id", "in": "path", "required": true, "description": "The unique identifier of the agent passport", "schema": { "type": "string", "pattern": "^ap_[a-zA-Z0-9]+$", "example": "ap_a2d10232c6534523812423eec8a1425c" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "agent_id", "owner_id", "status" ], "properties": { "agent_id": { "type": "string", "description": "The agent passport ID (must match path parameter)", "pattern": "^ap_[a-zA-Z0-9]+$", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "owner_id": { "type": "string", "description": "The owner ID of the passport", "pattern": "^(ap_org_|ap_user_)[a-zA-Z0-9]+$", "example": "ap_org_456" }, "status": { "type": "string", "description": "New status for the passport", "enum": [ "draft", "active", "suspended", "revoked" ], "example": "suspended" }, "reason": { "type": "string", "description": "Reason for the status change", "example": "Policy violation detected", "maxLength": 500 }, "admin_notes": { "type": "string", "description": "Admin-only notes (requires admin token)", "example": "Suspended due to suspicious activity", "maxLength": 1000 }, "force_change": { "type": "boolean", "description": "Force status change even if validation fails (admin only)", "default": false }, "notify_owner": { "type": "boolean", "description": "Whether to notify the passport owner of the status change", "default": true }, "webhook_data": { "type": "object", "description": "Additional data to include in webhook notifications", "additionalProperties": true, "example": { "source": "admin_panel", "admin_user": "admin@company.com" } } } } } } }, "responses": { "200": { "description": "Status updated successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "success", "data", "requestId" ], "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "required": [ "success" ], "properties": { "success": { "type": "boolean", "example": true }, "previous_status": { "type": "string", "description": "Previous status of the passport", "example": "active" }, "new_status": { "type": "string", "description": "New status of the passport", "example": "suspended" }, "changed_at": { "type": "string", "format": "date-time", "description": "Timestamp when status was changed", "example": "2025-01-16T10:30:00Z" } } }, "requestId": { "type": "string", "description": "Unique request identifier", "example": "req_123456789" }, "audit_id": { "type": "string", "description": "Audit trail identifier", "example": "audit_123456789" } } } } } }, "400": { "description": "Bad request - validation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "validation_failed", "message": "Invalid status transition from active to draft" } } } }, "401": { "description": "Unauthorized - invalid or missing authentication", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "unauthorized", "message": "Valid authentication required" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "forbidden", "message": "Only passport owner or admin can change status" } } } }, "404": { "description": "Passport not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "not_found", "message": "Passport with ID ap_a2d10232c6534523812423eec8a1425c not found" } } } }, "409": { "description": "Conflict - invalid status transition", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "conflict", "message": "Cannot change status from revoked to active" } } } }, "429": { "description": "Too many requests - rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "rate_limit_exceeded", "message": "Too many requests, please try again later" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "An unexpected error occurred" } } } } } } }, "/api/passports/{agent_id}/update": { "put": { "summary": "Update an existing passport", "description": "Updates an existing agent passport with comprehensive validation, Verifiable Attestation, and admin support.\nSupports partial updates and admin overrides.\n\n**Access Control:**\n- Passport owner (user or org) can update their own passports\n- Organization members with `org_admin` or `org_issuer` role can update org-owned passports\n- Organizations that issued/provisioned/sponsored a passport can update it, even if `owner_id` is a user (delegated issuance)\n- API keys owned by an org can update passports owned by that org or issued by that org\n- Platform admins can update any passport\n", "operationId": "updatePassport", "tags": [ "Passports" ], "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "name": "agent_id", "in": "path", "required": true, "description": "The unique identifier of the agent passport to update", "schema": { "type": "string", "pattern": "^ap_[a-zA-Z0-9]+$", "example": "ap_a2d10232c6534523812423eec8a1425c" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "description": "Updated human-readable name for the agent", "example": "Updated Support Bot", "minLength": 1, "maxLength": 100 }, "slug": { "type": "string", "description": "Updated URL-friendly identifier", "example": "updated-support-bot", "pattern": "^[a-z0-9-]+$" }, "role": { "type": "string", "description": "Updated functional role of the agent", "example": "senior_support", "enum": [ "agent", "assistant", "tool", "service" ] }, "description": { "type": "string", "description": "Updated description of the agent's purpose and capabilities", "example": "Enhanced AI-powered customer support agent with advanced capabilities", "minLength": 10, "maxLength": 1000 }, "capabilities": { "type": "array", "description": "Updated list of agent capabilities with optional parameters", "items": { "type": "object", "required": [ "id" ], "properties": { "id": { "type": "string", "description": "Capability identifier", "example": "finance.payment.refund", "enum": [ "finance.payment.refund", "data.export", "messaging.send", "repo.pr.create", "repo.merge" ] }, "params": { "type": "object", "description": "Capability-specific parameters", "additionalProperties": true, "example": { "max_amount": 2000, "currency": "USD" } } } } }, "limits": { "type": "object", "description": "Updated operational limits and constraints", "properties": { "refund_amount_max_per_tx": { "type": "number", "description": "Maximum refund amount per transaction (USD cents)", "example": 10000, "minimum": 0 }, "refund_amount_daily_cap": { "type": "number", "description": "Maximum daily refund amount (USD cents)", "example": 100000, "minimum": 0 }, "max_export_rows": { "type": "number", "description": "Maximum rows in data exports", "example": 20000, "minimum": 1 }, "allow_pii": { "type": "boolean", "description": "Whether PII access is allowed", "example": true }, "msgs_per_day": { "type": "number", "description": "Maximum messages per day", "example": 2000, "minimum": 1 }, "max_prs_per_day": { "type": "number", "description": "Maximum pull requests per day", "example": 20, "minimum": 1 } } }, "regions": { "type": "array", "description": "Updated geographic regions where the agent can operate", "items": { "type": "string", "example": "EU", "enum": [ "US", "EU", "CA", "AP", "global" ] }, "minItems": 1 }, "contact": { "type": "string", "description": "Updated contact information for the agent owner", "example": "support@acme.com", "format": "email" }, "links": { "type": "object", "description": "Updated external links and resources", "properties": { "homepage": { "type": "string", "format": "uri", "description": "Agent homepage URL", "example": "https://acme.com/updated-bot" }, "docs": { "type": "string", "format": "uri", "description": "Documentation URL", "example": "https://docs.acme.com/updated-bot" }, "repo": { "type": "string", "format": "uri", "description": "Source code repository URL", "example": "https://github.com/acme/updated-support-bot" } } }, "category": { "type": "string", "description": "Updated agent category classification", "example": "senior_support", "enum": [ "customer_support", "sales", "development", "security", "general" ] }, "framework": { "type": "string", "description": "Updated AI framework used", "example": "anthropic", "enum": [ "openai", "anthropic", "google", "meta", "custom" ] }, "model_info": { "type": "object", "description": "Updated AI model information and capabilities", "properties": { "model_refs": { "type": "array", "description": "AI models used by the agent", "items": { "type": "object", "properties": { "provider": { "type": "string", "example": "Anthropic" }, "id": { "type": "string", "example": "claude-3.5-sonnet" }, "version": { "type": "string", "example": "2025-01-01" }, "modality": { "type": "string", "example": "text" } } } }, "tools": { "type": "array", "description": "External tools integrated", "items": { "type": "object", "properties": { "name": { "type": "string", "example": "payments" }, "provider": { "type": "string", "example": "Stripe" } } } } } }, "admin_notes": { "type": "string", "description": "Admin-only notes (requires admin token)", "example": "Updated for enterprise requirements", "maxLength": 1000 }, "force_update": { "type": "boolean", "description": "Force update even if validation fails (admin only)", "default": false }, "skip_validation": { "type": "boolean", "description": "Skip validation checks (admin only)", "default": false }, "notify_owner": { "type": "boolean", "description": "Whether to notify the passport owner of the update", "default": true }, "webhook_data": { "type": "object", "description": "Additional data to include in webhook notifications", "additionalProperties": true, "example": { "source": "admin_panel", "admin_user": "admin@company.com" } } } } } } }, "responses": { "200": { "description": "Passport updated successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "success", "data", "requestId" ], "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/Passport" }, "requestId": { "type": "string", "description": "Unique request identifier", "example": "req_123456789" }, "audit_id": { "type": "string", "description": "Audit trail identifier", "example": "audit_123456789" }, "changes": { "type": "array", "description": "List of fields that were changed", "items": { "type": "object", "properties": { "field": { "type": "string", "example": "name" }, "old_value": { "type": "string", "example": "Old Support Bot" }, "new_value": { "type": "string", "example": "Updated Support Bot" } } } } } } } } }, "400": { "description": "Bad request - validation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "validation_failed", "message": "Name is required and must be between 1-100 characters" } } } }, "401": { "description": "Unauthorized - invalid or missing authentication", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "unauthorized", "message": "Valid authentication required" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "forbidden", "message": "You don't have permission to update this passport", "details": { "auth_user_id": "ap_user_123", "passport_owner_id": "ap_org_456", "passport_issued_by": "ap_org_789" } } } } }, "404": { "description": "Passport not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "not_found", "message": "Passport with ID ap_a2d10232c6534523812423eec8a1425c not found" } } } }, "409": { "description": "Conflict - update conflicts with existing data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "conflict", "message": "Passport with this name already exists" } } } }, "429": { "description": "Too many requests - rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "rate_limit_exceeded", "message": "Too many requests, please try again later" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "An unexpected error occurred" } } } } } } }, "/api/passports/{agent_id}/verifiable-attestation": { "get": { "summary": "Get verifiable attestation and audit trail for agent", "description": "Retrieves comprehensive verifiable attestation data with immutable audit trail, supporting CSV, PDF, and JSONL export formats. Each audit record contains complete identity, intent, time, location, decision, and immutability proof for compliance purposes.", "operationId": "getVerifiableAttestation", "tags": [ "Passports" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "agent_id", "in": "path", "required": true, "description": "The unique identifier of the agent passport", "schema": { "type": "string", "pattern": "^ap_[a-zA-Z0-9]+$", "example": "ap_a2d10232c6534523812423eec8a1425c" } }, { "name": "export_type", "in": "query", "description": "Export format for audit trail data", "schema": { "type": "string", "enum": [ "csv", "pdf", "jsonl" ], "default": "jsonl", "example": "csv" } }, { "name": "since", "in": "query", "description": "Only include audit records since this timestamp (ISO 8601)", "schema": { "type": "string", "format": "date-time", "example": "2025-01-01T00:00:00Z" } }, { "name": "until", "in": "query", "description": "Only include audit records until this timestamp (ISO 8601)", "schema": { "type": "string", "format": "date-time", "example": "2025-01-31T23:59:59Z" } }, { "name": "action_types", "in": "query", "description": "Filter by specific action types (comma-separated)", "schema": { "type": "string", "example": "create,update,verify,policy_decision" } }, { "name": "include_decision_details", "in": "query", "description": "Include full decision details in audit records", "schema": { "type": "boolean", "default": true, "example": true } }, { "name": "include_context", "in": "query", "description": "Include full context data in audit records", "schema": { "type": "boolean", "default": false, "example": false } } ], "responses": { "200": { "description": "Verifiable attestation retrieved successfully", "headers": { "Content-Type": { "description": "Content type based on export format", "schema": { "type": "string", "enum": [ "application/json", "text/csv", "application/pdf" ] } }, "Content-Disposition": { "description": "File download header", "schema": { "type": "string", "example": "attachment; filename=audit-trail-ap_123456789-2025-01-16.csv" } } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "success", "data", "requestId" ], "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "required": [ "agent_id", "owner_id", "attestation_summary", "audit_trail", "chain_integrity" ], "properties": { "agent_id": { "type": "string", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "owner_id": { "type": "string", "example": "ap_org_456" }, "attestation_summary": { "type": "object", "properties": { "total_actions": { "type": "integer", "example": 150 }, "first_action": { "type": "string", "format": "date-time", "example": "2025-01-01T00:00:00Z" }, "last_action": { "type": "string", "format": "date-time", "example": "2025-01-16T10:30:00Z" }, "chain_valid": { "type": "boolean", "example": true }, "last_hash": { "type": "string", "example": "sha256:abc123def456" } } }, "audit_trail": { "type": "array", "items": { "type": "object", "required": [ "action_id", "action_type", "timestamp", "actor", "decision", "record_hash", "prev_hash" ], "properties": { "action_id": { "type": "string", "example": "audit_1234567890" }, "action_type": { "type": "string", "example": "policy_decision" }, "timestamp": { "type": "string", "format": "date-time", "example": "2025-01-16T10:30:00Z" }, "actor": { "type": "object", "properties": { "agent_id": { "type": "string", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "owner_id": { "type": "string", "example": "ap_org_456" }, "user_id": { "type": "string", "example": "user_123" } } }, "intent": { "type": "object", "properties": { "policy_id": { "type": "string", "example": "finance.payment.refund.v1" }, "context": { "type": "object", "additionalProperties": true }, "decision_requested": { "type": "string", "example": "refund_approval" } } }, "location": { "type": "object", "properties": { "source_ip": { "type": "string", "example": "192.168.1.100" }, "region": { "type": "string", "example": "US" }, "cf_ray": { "type": "string", "example": "abc123def456" } } }, "decision": { "type": "object", "properties": { "decision_id": { "type": "string", "example": "dec_1234567890" }, "allowed": { "type": "boolean", "example": true }, "reasons": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string", "example": "capability_verified" }, "message": { "type": "string", "example": "Agent has required refund capability" }, "severity": { "type": "string", "enum": [ "info", "warning", "error" ], "example": "info" } } } }, "signature": { "type": "string", "example": "ed25519:xyz789" }, "expires_at": { "type": "string", "format": "date-time", "example": "2025-01-16T11:30:00Z" } } }, "immutability": { "type": "object", "properties": { "record_hash": { "type": "string", "example": "sha256:def456ghi789" }, "prev_hash": { "type": "string", "example": "sha256:abc123def456" }, "registry_signature": { "type": "string", "example": "ed25519:registry_xyz789" }, "verified": { "type": "boolean", "example": true } } } } } } } }, "requestId": { "type": "string", "example": "attestation_123456789_abc123" }, "export_info": { "type": "object", "properties": { "format": { "type": "string", "example": "jsonl" }, "record_count": { "type": "integer", "example": 150 }, "generated_at": { "type": "string", "format": "date-time", "example": "2025-01-16T10:30:00Z" }, "expires_at": { "type": "string", "format": "date-time", "example": "2025-01-17T10:30:00Z" } } } } } } } }, "400": { "description": "Bad request - invalid parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "invalid_export_type", "message": "Export type must be one of: csv, pdf, jsonl" } } } }, "401": { "description": "Unauthorized - invalid or missing authentication", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "unauthorized", "message": "Valid authentication required" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "forbidden", "message": "You don't have permission to access this agent's audit trail" } } } }, "404": { "description": "Agent passport not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "passport_not_found", "message": "Passport with ID ap_a2d10232c6534523812423eec8a1425c not found" } } } }, "429": { "description": "Too many requests - rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "rate_limit_exceeded", "message": "Too many requests, please try again later" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "An unexpected error occurred" } } } } } } }, "/api/passports/{agent_id}/webhooks": { "get": { "summary": "List webhooks for a specific agent", "description": "Get all webhooks configured for a specific agent/passport", "operationId": "listAgentWebhooks", "tags": [ "Webhooks" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "agent_id", "in": "path", "required": true, "description": "The agent/passport ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Webhooks retrieved successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookListResponse" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Agent not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "summary": "Create webhook for a specific agent", "description": "Register a webhook endpoint for a specific agent/passport", "operationId": "createAgentWebhook", "tags": [ "Webhooks" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "agent_id", "in": "path", "required": true, "description": "The agent/passport ID", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateWebhookRequest" } } } }, "responses": { "201": { "description": "Webhook created successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookConfig" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Agent not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/passports/{template_id}/instances": { "get": { "summary": "List instances of a template passport", "description": "Get a paginated list of all instances created from a template", "operationId": "listPassportInstances", "tags": [ "Passports" ], "parameters": [ { "in": "path", "name": "template_id", "required": true, "schema": { "type": "string" }, "description": "Template passport ID", "example": "agt_tmpl_abc123" }, { "in": "query", "name": "cursor", "schema": { "type": "string" }, "description": "Pagination cursor" }, { "in": "query", "name": "limit", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 }, "description": "Number of instances to return" } ], "responses": { "200": { "description": "List of instances", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean", "example": true }, "instances": { "type": "array", "items": { "type": "object", "properties": { "instance_id": { "type": "string", "example": "agt_inst_def456" }, "platform_id": { "type": "string", "example": "gorgias" }, "tenant_ref": { "type": "string", "example": "tenant_123" }, "controller_id": { "type": "string", "example": "ap_org_456" }, "controller_type": { "type": "string", "example": "org" }, "status": { "type": "string", "example": "active" }, "created_at": { "type": "string", "example": "2025-01-15T10:30:00Z" }, "updated_at": { "type": "string", "example": "2025-01-15T10:30:00Z" } } } }, "next_cursor": { "type": "string", "description": "Cursor for next page" }, "total_count": { "type": "integer", "description": "Total number of instances" } } } } } }, "400": { "description": "Invalid template ID" }, "404": { "description": "Template not found" }, "500": { "description": "Internal server error" } } }, "post": { "summary": "Create an instance of a template passport", "description": "Creates a new instance passport based on an existing template passport.\n\n**Access Control:**\n- Requires access to the template passport (owner, org member, or issuer)\n- API keys owned by an org can create instances from templates owned by that org or issued by that org\n\n**Instance Properties:**\n- Instance passports inherit the assurance level from the template (user's KYC/KYB level)\n- Instance-specific overrides can be provided for limits, regions, status, contact, and links\n- The creating organization is tracked in `issued_by`, `provisioned_by_org_id`, and `sponsor_orgs` metadata\n- This allows the creating org to update the instance passport later\n- Instances inherit tags, expiry settings (expires_at, never_expires) from template\n- Each instance gets a unique W3C DID generated based on the instance agent_id (not copied from template)\n\n**Template Requirements:**\n- Template passport must be claimed before instances can be created\n- If template is unclaimed, a claim email will be sent and an error returned\n- Template must have a valid owner_id (ap_org_* or ap_user_* format)\n\n**Owner Determination:**\n- Instance `owner_id` is determined by: authenticated user ID > valid controller_id > creating org > template owner\n- Ensures `owner_id` is always a valid user/org ID (`ap_user_*` or `ap_org_*`)\n", "operationId": "createPassportInstance", "tags": [ "Passports" ], "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "parameters": [ { "in": "path", "name": "template_id", "required": true, "schema": { "type": "string" }, "description": "Template passport ID", "example": "agt_tmpl_abc123" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "platform_id", "tenant_ref", "controller_id", "controller_type" ], "properties": { "platform_id": { "type": "string", "description": "Platform identifier", "example": "gorgias" }, "tenant_ref": { "type": "string", "description": "Platform's tenant identifier", "example": "tenant_123" }, "controller_id": { "type": "string", "description": "Controller org/user ID", "example": "ap_org_456" }, "controller_type": { "type": "string", "enum": [ "org", "user" ], "description": "Controller type (must be valid user/org ID format if controller_id is provided)", "example": "org" }, "overrides": { "type": "object", "description": "Instance-specific overrides (only allowed keys)", "properties": { "limits": { "type": "object", "description": "Instance-specific limits overrides", "additionalProperties": true, "example": { "refund_amount_max_per_tx": 5000, "refund_amount_daily_cap": 50000 } }, "regions": { "type": "array", "items": { "type": "string" }, "description": "Instance-specific regions", "example": [ "US", "EU" ] }, "status": { "type": "string", "enum": [ "draft", "active", "suspended", "revoked" ], "description": "Instance status", "example": "active" }, "contact": { "type": "string", "format": "email", "description": "Instance contact email", "example": "support@tenant.com" }, "links": { "type": "object", "description": "Instance-specific links", "properties": { "homepage": { "type": "string", "format": "uri" }, "docs": { "type": "string", "format": "uri" }, "repo": { "type": "string", "format": "uri" } } } } }, "agent_data": { "type": "object", "description": "Agent-specific data overrides", "properties": { "name": { "type": "string", "description": "Instance name (overrides template name)", "example": "Acme Corp Support Agent" }, "description": { "type": "string", "description": "Instance description (overrides template description)", "example": "Gorgias instance for Acme Corp" }, "capabilities": { "type": "array", "items": { "type": "string" }, "description": "Instance capabilities (overrides template capabilities)" }, "limits": { "type": "object", "additionalProperties": true, "description": "Instance limits (overrides template limits)" }, "regions": { "type": "array", "items": { "type": "string" }, "description": "Instance regions (overrides template regions)" }, "assurance_level": { "type": "string", "description": "Instance assurance level (inherits from template if not provided)", "example": "L4KYC" } } }, "install_token": { "type": "string", "description": "Optional install token for authentication (alternative to API key)", "example": "install_token_abc123" } } } } } }, "responses": { "201": { "description": "Instance created successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Instance created successfully" }, "instance_id": { "type": "string", "example": "agt_inst_def456" }, "template_id": { "type": "string", "example": "agt_tmpl_abc123" }, "key": { "type": "string", "example": "passport:agt_inst_def456" } } } } } }, "400": { "description": "Bad request - invalid request data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "validation_failed": { "summary": "Invalid request data", "value": { "error": "validation_failed", "message": "Invalid controller_id format" } }, "template_unclaimed": { "summary": "Template not claimed", "value": { "error": "validation_failed", "message": "Template passport must be claimed before creating instances. A claim email has been sent to {email}. Please claim the template passport first, then try again.", "details": { "template_id": "agt_tmpl_abc123", "template_claimed": false, "claim_email_sent": true, "template_contact": "owner@example.com" } } } } } } }, "403": { "description": "Forbidden - insufficient permissions to access template passport", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "forbidden", "message": "You don't have permission to access this template passport" } } } }, "404": { "description": "Template passport not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "not_found", "message": "Template passport not found" } } } }, "409": { "description": "Conflict - instance already exists for this platform and tenant", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "conflict", "message": "Instance already exists for this platform and tenant" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/passports/{template_id}/webhooks": { "post": { "summary": "Apply for Passport-specific webhook", "description": "Register a webhook endpoint for a specific agent/passport", "operationId": "createAgentWebhook", "tags": [ "Webhooks" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "template_id", "in": "path", "required": true, "description": "The agent/passport ID", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "url", "secret", "events" ], "properties": { "url": { "type": "string", "format": "uri", "description": "The webhook endpoint URL" }, "secret": { "type": "string", "description": "Secret for signing webhook payloads" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "status.changed", "passport.updated", "assurance.updated", "attestation.created", "attestation.verified", "instance.created", "instance.suspended" ] }, "description": "List of events to subscribe to" }, "active": { "type": "boolean", "default": true, "description": "Whether the webhook is active" }, "retry_attempts": { "type": "integer", "default": 3, "minimum": 1, "maximum": 10, "description": "Number of retry attempts" }, "timeout_ms": { "type": "integer", "default": 5000, "minimum": 1000, "maximum": 30000, "description": "Request timeout in milliseconds" } } } } } }, "responses": { "201": { "description": "Webhook created successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "message": { "type": "string" }, "webhook": { "$ref": "#/components/schemas/WebhookConfig" } } } } } }, "400": { "description": "Bad request" }, "401": { "description": "Unauthorized" }, "404": { "description": "Agent not found" }, "500": { "description": "Internal server error" } } }, "get": { "summary": "List agent webhooks", "description": "Get all webhooks for a specific agent", "operationId": "listAgentWebhooks", "tags": [ "Webhooks" ], "parameters": [ { "name": "template_id", "in": "path", "required": true, "description": "The agent/passport ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of webhooks", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookListResponse" } } } }, "401": { "description": "Unauthorized" }, "404": { "description": "Agent not found" }, "500": { "description": "Internal server error" } } } }, "/api/passports/by-slug/{slug}": { "get": { "summary": "Get passport details by slug", "description": "Retrieves passport information by slug (passport username).\nSame response format and access control as GET /api/passports/{agent_id}.\n", "operationId": "getPassportBySlug", "tags": [ "Passports" ], "parameters": [ { "in": "path", "name": "slug", "required": true, "schema": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$" }, "description": "URL-friendly passport identifier (passport username)" }, { "in": "query", "name": "format", "schema": { "type": "string", "enum": [ "json", "vc", "vp" ], "default": "json" } } ], "responses": { "200": { "description": "Passport details retrieved successfully" }, "404": { "description": "Passport with the specified slug was not found" } } } }, "/api/passports/create": { "post": { "summary": "Create a new agent passport", "description": "Creates a new agent passport (template or instance) with comprehensive validation, Verifiable Attestation, and admin support.\n\n**Access Control:**\n- Users can create passports with `owner_id` set to their own user ID\n- Organization members with `org_admin` or `org_issuer` role can create passports with `owner_id` set to their org\n- API keys owned by an org can create passports with `owner_id` set to that org\n- Platform admins can create passports with any `owner_id`\n\nSupports both regular user creation and admin-created passports.\n", "operationId": "createPassport", "tags": [ "Passports" ], "security": [ { "BearerAuth": [] }, { "ApiKeyAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "name", "role", "description", "capabilities", "limits", "regions", "contact" ], "properties": { "name": { "type": "string", "description": "Human-readable name for the agent", "example": "Acme Support Bot", "minLength": 1, "maxLength": 100 }, "slug": { "type": "string", "description": "URL-friendly identifier (auto-generated if not provided)", "example": "acme-support-bot", "pattern": "^[a-z0-9-]+$" }, "role": { "type": "string", "description": "Functional role of the agent", "example": "customer_support", "enum": [ "agent", "assistant", "tool", "service" ] }, "description": { "type": "string", "description": "Detailed description of the agent's purpose and capabilities", "example": "AI-powered customer support agent for handling common inquiries", "minLength": 10, "maxLength": 1000 }, "capabilities": { "type": "array", "description": "List of agent capabilities with optional parameters", "items": { "type": "object", "required": [ "id" ], "properties": { "id": { "type": "string", "description": "Capability identifier", "example": "finance.payment.refund", "enum": [ "finance.payment.refund", "data.export", "messaging.send", "repo.pr.create", "repo.merge" ] }, "params": { "type": "object", "description": "Capability-specific parameters", "additionalProperties": true, "example": { "max_amount": 1000, "currency": "USD" } } } } }, "limits": { "type": "object", "description": "Operational limits and constraints", "properties": { "refund_amount_max_per_tx": { "type": "number", "description": "Maximum refund amount per transaction (USD cents)", "example": 5000, "minimum": 0 }, "refund_amount_daily_cap": { "type": "number", "description": "Maximum daily refund amount (USD cents)", "example": 50000, "minimum": 0 }, "max_export_rows": { "type": "number", "description": "Maximum rows in data exports", "example": 10000, "minimum": 1 }, "allow_pii": { "type": "boolean", "description": "Whether PII access is allowed", "example": false }, "msgs_per_day": { "type": "number", "description": "Maximum messages per day", "example": 1000, "minimum": 1 }, "max_prs_per_day": { "type": "number", "description": "Maximum pull requests per day", "example": 10, "minimum": 1 } } }, "regions": { "type": "array", "description": "Geographic regions where the agent can operate", "items": { "type": "string", "example": "US", "enum": [ "US", "EU", "CA", "AP", "global" ] }, "minItems": 1 }, "contact": { "type": "string", "description": "Contact information for the agent owner", "example": "admin@acme.com", "format": "email" }, "links": { "type": "object", "description": "External links and resources", "properties": { "homepage": { "type": "string", "format": "uri", "description": "Agent homepage URL", "example": "https://acme.com/bot" }, "docs": { "type": "string", "format": "uri", "description": "Documentation URL", "example": "https://docs.acme.com/bot" }, "repo": { "type": "string", "format": "uri", "description": "Source code repository URL", "example": "https://github.com/acme/support-bot" } } }, "category": { "type": "string", "description": "Agent category classification", "example": "customer_support", "enum": [ "customer_support", "sales", "development", "security", "general" ] }, "framework": { "type": "string", "description": "AI framework used", "example": "openai", "enum": [ "openai", "anthropic", "google", "meta", "custom" ] }, "model_info": { "type": "object", "description": "AI model information and capabilities", "properties": { "model_refs": { "type": "array", "description": "AI models used by the agent", "items": { "type": "object", "properties": { "provider": { "type": "string", "example": "OpenAI" }, "id": { "type": "string", "example": "gpt-4o-mini" }, "version": { "type": "string", "example": "2025-08-01" }, "modality": { "type": "string", "example": "text" } } } }, "tools": { "type": "array", "description": "External tools integrated", "items": { "type": "object", "properties": { "name": { "type": "string", "example": "payments" }, "provider": { "type": "string", "example": "Stripe" } } } } } }, "admin_notes": { "type": "string", "description": "Admin-only notes (requires admin token)", "example": "Created for enterprise client" }, "force_create": { "type": "boolean", "description": "Force creation even if validation fails (admin only)", "default": false }, "template_id": { "type": "string", "description": "Template ID for instance creation", "example": "ap_template_123" }, "instance_overrides": { "type": "object", "description": "Instance-specific overrides for template-based creation", "additionalProperties": true }, "skip_validation": { "type": "boolean", "description": "Skip validation checks (admin only)", "default": false }, "expires_at": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp when passport expires (optional - for ephemeral credentials)", "example": "2025-12-31T23:59:59Z" }, "expires_in_days": { "type": "number", "description": "Number of days until expiration (alternative to expires_at - will auto-compute expires_at)", "example": 7, "minimum": 0, "maximum": 3650 }, "never_expires": { "type": "boolean", "description": "Explicit flag for perpetual credentials (default true if no expiry specified)", "default": true } } } } } }, "responses": { "201": { "description": "Passport created successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "ok", "message", "success", "data", "audit_id", "requestId" ], "properties": { "ok": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Passport created successfully" }, "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/Passport" }, "audit_id": { "type": "string", "description": "Audit trail identifier", "example": "audit_123456789" }, "requestId": { "type": "string", "description": "Unique request identifier", "example": "req_123456789" } } } } } }, "400": { "description": "Bad request - validation failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "validation_failed", "message": "Name is required and must be between 1-100 characters" } } } }, "401": { "description": "Unauthorized - invalid or missing authentication", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "unauthorized", "message": "Valid authentication required" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "forbidden", "message": "Admin privileges required for this operation" } } } }, "409": { "description": "Conflict - passport already exists", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "conflict", "message": "Passport with this name already exists" } } } }, "429": { "description": "Too many requests - rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "rate_limit_exceeded", "message": "Too many requests, please try again later" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "An unexpected error occurred" } } } } } } }, "/api/passports/list": { "get": { "summary": "List agent passports", "description": "Lists agent passports for the authenticated user/organization. Admin users can list all passports in the database.", "operationId": "listPassports", "tags": [ "Passports" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "in": "query", "name": "owner_id", "schema": { "type": "string" }, "description": "Filter by specific owner ID (admin only)", "example": "ap_user_123" }, { "in": "query", "name": "status", "schema": { "type": "string", "enum": [ "active", "suspended", "draft", "revoked" ] }, "description": "Filter by passport status", "example": "active" }, { "in": "query", "name": "limit", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "description": "Maximum number of passports to return", "example": 20 }, { "in": "query", "name": "offset", "schema": { "type": "integer", "minimum": 0, "default": 0 }, "description": "Number of passports to skip", "example": 0 } ], "responses": { "200": { "description": "Passports retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "success", "passports", "total", "limit", "offset", "requestId" ], "properties": { "success": { "type": "boolean", "example": true }, "passports": { "type": "array", "items": { "$ref": "#/components/schemas/Passport" } }, "total": { "type": "integer", "description": "Total number of passports matching filters", "example": 25 }, "limit": { "type": "integer", "description": "Maximum number of passports returned", "example": 20 }, "offset": { "type": "integer", "description": "Number of passports skipped", "example": 0 }, "requestId": { "type": "string", "description": "Unique request identifier", "example": "req_123456789" } } } } } }, "400": { "description": "Bad request - invalid parameters", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Unauthorized - invalid or missing authentication", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "403": { "description": "Forbidden - insufficient permissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/policies/{policy_name}": { "get": { "summary": "Get a policy pack by name and version", "description": "Retrieves a specific policy pack configuration", "tags": [ "Policies" ], "parameters": [ { "in": "path", "name": "policy_name", "required": true, "schema": { "type": "string" }, "description": "Policy pack name with version (e.g., finance.payment.refund.v1)" } ], "responses": { "200": { "description": "Policy pack configuration", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "description": { "type": "string" }, "version": { "type": "string" }, "status": { "type": "string", "enum": [ "active", "suspended", "deprecated" ] }, "requires_capabilities": { "type": "array", "items": { "type": "string" } }, "min_assurance": { "type": "string", "enum": [ "L0", "L1", "L2", "L3", "L4KYC", "L4FIN" ] }, "limits_required": { "type": "array", "items": { "type": "string" } }, "required_fields": { "type": "array", "items": { "type": "string" } }, "optional_fields": { "type": "array", "items": { "type": "string" } }, "enforcement": { "type": "object", "additionalProperties": { "oneOf": [ { "type": "string" }, { "type": "boolean" } ] } }, "mcp": { "type": "object", "description": "Model Context Protocol requirements" }, "advice": { "type": "array", "items": { "type": "string" } }, "deprecation": { "type": "string", "nullable": true }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } } } } }, "400": { "description": "Invalid policy pack name format" }, "404": { "description": "Policy pack not found" } } } }, "/api/schema/capabilities-limits": { "get": { "summary": "Get capabilities and limits schema", "description": "Returns comprehensive metadata about all available capabilities and limits.\nThis endpoint is useful for:\n- Frontend developers to know what fields to collect from users\n- Backend developers to know what to expect and validate\n- Understanding the relationship between capabilities and limits\n", "operationId": "getCapabilitiesLimitsSchema", "tags": [ "Schema" ], "responses": { "200": { "description": "Capabilities and limits schema retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "required": [ "capabilities", "limits", "regions", "version" ], "properties": { "version": { "type": "string", "description": "Schema version", "example": "1.0.0" }, "capabilities": { "type": "array", "description": "All available capabilities with metadata", "items": { "type": "object", "properties": { "id": { "type": "string", "example": "finance.payment.refund" }, "name": { "type": "string", "example": "Payment Refunds" }, "description": { "type": "string", "example": "Process payment refunds and chargebacks" }, "category": { "type": "string", "enum": [ "payments", "data", "communication", "development", "business", "infrastructure" ], "example": "payments" }, "riskLevel": { "type": "string", "enum": [ "low", "medium", "high", "critical" ], "example": "high" }, "status": { "type": "string", "enum": [ "active", "deprecated", "beta" ], "example": "active" }, "relatedLimits": { "type": "array", "description": "Limit keys that are relevant to this capability", "items": { "type": "string" }, "example": [ "refund_amount_max_per_tx", "refund_amount_daily_cap", "supported_currencies" ] }, "relatedPolicies": { "type": "array", "description": "Policy packs that require this capability", "items": { "type": "object", "properties": { "id": { "type": "string", "example": "finance.payment.refund.v1" }, "name": { "type": "string", "example": "Refunds Protection Policy" }, "version": { "type": "string", "example": "1.0.0" }, "status": { "type": "string", "enum": [ "active", "deprecated", "beta" ], "example": "active" }, "min_assurance": { "type": "string", "example": "L2" }, "limits_required": { "type": "array", "items": { "type": "string" }, "example": [ "supported_currencies", "currency_limits" ] } } } } } } }, "limits": { "type": "object", "description": "All available limits with metadata, keyed by limit key", "additionalProperties": { "type": "object", "properties": { "key": { "type": "string", "example": "refund_amount_max_per_tx" }, "type": { "type": "string", "enum": [ "number", "boolean", "string[]", "object" ], "example": "number" }, "min": { "type": "number", "description": "Minimum value (for number types)", "example": 0 }, "max": { "type": "number", "description": "Maximum value (for number types)", "example": 1000000 }, "description": { "type": "string", "example": "Maximum refund amount per transaction in USD cents (legacy)" }, "category": { "type": "string", "enum": [ "payments", "data", "actions", "deployment", "privacy", "messaging", "repository", "compliance" ], "example": "payments" }, "relatedCapabilities": { "type": "array", "description": "Capability IDs that use this limit", "items": { "type": "string" }, "example": [ "finance.payment.refund" ] }, "validationRules": { "type": "array", "description": "Validation rules for this limit", "items": { "type": "string" }, "example": [ "Must be non-negative", "Must be <= refund_amount_daily_cap if both are set" ] }, "uiHint": { "type": "object", "description": "UI hints for frontend developers", "properties": { "inputType": { "type": "string", "enum": [ "number", "boolean", "multiselect", "text", "textarea", "object" ], "example": "number" }, "unit": { "type": "string", "description": "Unit of measurement (for number types)", "example": "cents" }, "placeholder": { "type": "string", "example": "Enter maximum refund amount" }, "helpText": { "type": "string", "example": "Maximum refund amount per transaction in USD cents" } } } } } }, "regions": { "type": "object", "description": "Region and jurisdiction information. All region codes use ISO-3166-1 alpha-2 format\n(2-letter uppercase country codes). This includes passport-level regions and\nlimit-specific jurisdiction controls.\n", "properties": { "format": { "type": "string", "example": "ISO-3166-1 alpha-2" }, "description": { "type": "string", "example": "All region and jurisdiction codes use ISO-3166-1 alpha-2 country codes" }, "reference": { "type": "string", "format": "uri", "example": "https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2" }, "examples": { "type": "array", "items": { "type": "string" }, "example": [ "US", "GB", "CA", "DE", "FR", "JP" ] }, "passportLevel": { "type": "object", "description": "Passport-level regions field", "properties": { "field": { "type": "string", "example": "regions" }, "type": { "type": "string", "example": "string[]" }, "description": { "type": "string" }, "example": { "type": "array", "items": { "type": "string" }, "example": [ "US", "CA", "GB" ] } } }, "limitTypes": { "type": "object", "description": "Region-related limits available in the system", "additionalProperties": { "type": "object", "properties": { "description": { "type": "string" }, "category": { "type": "string" }, "usedBy": { "type": "array", "items": { "type": "string" } } } } }, "evaluation": { "type": "object", "description": "How region limits are evaluated by policy evaluators", "properties": { "description": { "type": "string" }, "evaluators": { "type": "array", "items": { "type": "string" } } } } } } } }, "example": { "version": "1.0.0", "capabilities": [ { "id": "finance.payment.refund", "name": "Payment Refunds", "description": "Process payment refunds and chargebacks", "category": "payments", "riskLevel": "high", "status": "active", "relatedLimits": [ "refund_amount_max_per_tx", "refund_amount_daily_cap", "supported_currencies" ], "relatedPolicies": [ { "id": "finance.payment.refund.v1", "name": "Refunds Protection Policy", "version": "1.0.0", "status": "active", "min_assurance": "L2", "limits_required": [ "supported_currencies", "currency_limits" ] } ] } ], "limits": { "refund_amount_max_per_tx": { "key": "refund_amount_max_per_tx", "type": "number", "min": 0, "max": 1000000, "description": "Maximum refund amount per transaction in USD cents (legacy)", "category": "payments", "relatedCapabilities": [ "finance.payment.refund" ], "validationRules": [ "Must be non-negative", "Must be <= refund_amount_daily_cap if both are set" ], "uiHint": { "inputType": "number", "unit": "cents", "placeholder": "Enter maximum refund amount" } } }, "regions": { "format": "ISO-3166-1 alpha-2", "description": "All region and jurisdiction codes use ISO-3166-1 alpha-2 country codes", "reference": "https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2", "examples": [ "US", "GB", "CA", "DE", "FR", "JP" ], "passportLevel": { "field": "regions", "type": "string[]", "description": "Passport-level regions array for general authorization", "example": [ "US", "CA", "GB" ] }, "limitTypes": { "allowed_jurisdictions": { "description": "Allowed data jurisdictions for data access", "category": "data", "usedBy": [ "governance.data.access.v1" ] }, "allowed_destination_jurisdictions": { "description": "Allowed destination jurisdictions for data transfer", "category": "data", "usedBy": [ "governance.data.access.v1" ] }, "allowed_contract_jurisdictions": { "description": "Allowed jurisdictions for legal contract review", "category": "legal", "usedBy": [ "legal.contract.review.v1" ] }, "allowed_attorney_jurisdictions": { "description": "Jurisdictions where attorneys are licensed", "category": "legal", "usedBy": [ "legal.contract.review.v1" ] }, "allowed_countries": { "description": "Allowed countries for payment charges (nested under payments.charge)", "category": "payments", "usedBy": [ "finance.payment.charge.v1" ], "note": "This limit is nested under limits.payments.charge.allowed_countries" } }, "evaluation": { "description": "Region limits are evaluated by policy evaluators", "evaluators": [ "functions/utils/policy/regions.ts", "functions/utils/policy/governance.data.access.v1.ts", "functions/utils/policy/legal.contract.review.v1.ts", "functions/utils/policy/finance.payment.charge.v1.ts" ] } } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/status": { "get": { "tags": [ "Monitoring" ], "summary": "Get system status", "description": "Returns current system status including SLO metrics and health", "responses": { "200": { "description": "Status retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "operational", "degraded", "outage" ] }, "slo_data": { "type": "object", "properties": { "p95_latency": { "type": "number" }, "error_rate": { "type": "number" }, "availability": { "type": "number" } } }, "last_updated": { "type": "string", "format": "date-time" } } } } } } } } }, "/api/taxonomy/badges": { "get": { "summary": "Get badge data for specific categories and frameworks", "description": "Generate badge display data for AgentCard components", "operationId": "getTaxonomyBadges", "tags": [ "Taxonomy" ], "parameters": [ { "name": "categories", "in": "query", "description": "Comma-separated list of category IDs", "required": false, "schema": { "type": "string", "example": "support,commerce" } }, { "name": "frameworks", "in": "query", "description": "Comma-separated list of framework IDs", "required": false, "schema": { "type": "string", "example": "n8n,LangGraph" } } ], "responses": { "200": { "description": "Badge data generated successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "categories": { "type": "array", "items": { "type": "object" } }, "frameworks": { "type": "array", "items": { "type": "object" } } } } } } }, "400": { "description": "Invalid taxonomy values", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/taxonomy": { "get": { "summary": "Get taxonomy data", "description": "Retrieve controlled enums for categories and frameworks with display metadata", "operationId": "getTaxonomy", "tags": [ "Taxonomy" ], "responses": { "200": { "description": "Taxonomy data retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "categories": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "enum": [ "support", "commerce", "devops", "ops", "analytics", "marketing" ] }, "name": { "type": "string" }, "description": { "type": "string" }, "color": { "type": "string" }, "icon": { "type": "string" }, "order": { "type": "number" }, "capabilities": { "type": "array", "items": { "type": "string" } } } } }, "frameworks": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "enum": [ "n8n", "LangGraph", "CrewAI", "AutoGen", "OpenAI", "LlamaIndex", "Custom" ] }, "name": { "type": "string" }, "description": { "type": "string" }, "color": { "type": "string" }, "icon": { "type": "string" }, "website": { "type": "string" }, "order": { "type": "number" }, "capabilities": { "type": "array", "items": { "type": "string" } } } } } } }, "example": { "categories": [ { "id": "support", "name": "Support", "description": "Customer support and helpdesk automation", "color": "#3B82F6", "icon": "headset", "order": 1, "capabilities": [ "messaging.send", "crm.update", "data.export" ] } ], "frameworks": [ { "id": "n8n", "name": "n8n", "description": "Workflow automation platform", "color": "#FF6D5A", "icon": "workflow", "website": "https://n8n.io", "order": 1, "capabilities": [ "*" ] } ] } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/verify/{agent_id}": { "get": { "summary": "Verify agent passport (new multi-tenant multi-region tiered lookup)", "description": "Ultra-fast passport verification with cache-first tiered lookup, multi-tenant/multi-region support, and comprehensive security features. Optimized for sub-50ms p95 performance.", "operationId": "verifyAgentPassportNew", "tags": [ "Verification" ], "parameters": [ { "name": "agent_id", "in": "path", "required": true, "description": "The unique identifier of the agent passport to verify", "schema": { "type": "string", "pattern": "^ap_[a-zA-Z0-9]+$", "example": "ap_a2d10232c6534523812423eec8a1425c" } }, { "name": "include_attestation", "in": "query", "description": "Include verifiable attestation data", "schema": { "type": "boolean", "default": false } }, { "name": "include_audit_trail", "in": "query", "description": "Include audit trail information", "schema": { "type": "boolean", "default": false } }, { "name": "cache_control", "in": "query", "description": "Cache control preference", "schema": { "type": "string", "enum": [ "no-cache", "max-age", "stale-while-revalidate" ], "default": "max-age" } }, { "name": "tenant_ref", "in": "query", "description": "Tenant reference for multi-tenant support", "schema": { "type": "string", "example": "tenant_123" } }, { "name": "platform_id", "in": "query", "description": "Platform identifier for context", "schema": { "type": "string", "example": "platform_456" } } ], "responses": { "200": { "description": "Passport verification successful", "headers": { "Server-Timing": { "description": "Performance timing information", "schema": { "type": "string", "example": "cache-l1;dur=2, kv-read;dur=15, total;dur=17" } }, "ETag": { "description": "Entity tag for caching", "schema": { "type": "string", "example": "W/\"ap_a2d10232c6534523812423eec8a1425c_2025-01-16T10:30:00Z_v1.0\"" } }, "Cache-Control": { "description": "Cache control directives", "schema": { "type": "string", "example": "public, max-age=300, stale-while-revalidate=60" } } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "success", "data", "requestId" ], "properties": { "success": { "type": "boolean", "example": true }, "data": { "$ref": "#/components/schemas/Passport" }, "requestId": { "type": "string", "description": "Unique request identifier", "example": "verify_123456789_abc123" }, "performance": { "type": "object", "description": "Performance metrics", "properties": { "total_time_ms": { "type": "number", "example": 17 }, "cache_hit": { "type": "boolean", "example": true }, "cache_level": { "type": "string", "example": "L1" }, "kv_read_time_ms": { "type": "number", "example": 15 } } }, "attestation": { "type": "object", "description": "Verifiable attestation data (if requested)", "properties": { "hash": { "type": "string", "example": "sha256:abc123def456" }, "signature": { "type": "string", "example": "ed25519:xyz789" }, "timestamp": { "type": "string", "format": "date-time", "example": "2025-01-16T10:30:00Z" } } }, "audit_trail": { "type": "array", "description": "Audit trail entries (if requested)", "items": { "type": "object", "properties": { "action": { "type": "string", "example": "passport_verified" }, "timestamp": { "type": "string", "format": "date-time", "example": "2025-01-16T10:30:00Z" }, "details": { "type": "object", "additionalProperties": true } } } }, "expiry": { "type": "object", "description": "Expiry information (if passport has expiry set)", "properties": { "expires_at": { "type": "string", "format": "date-time", "example": "2025-12-31T23:59:59Z" }, "expires_in_seconds": { "type": "number", "example": 86400 }, "expires_in_minutes": { "type": "number", "example": 1440 }, "expires_in_hours": { "type": "number", "example": 24 }, "expires_in_days": { "type": "number", "example": 1 }, "severity": { "type": "string", "enum": [ "ok", "warning", "critical", "expired" ], "example": "ok" }, "message": { "type": "string", "example": "Passport expires in 24 hours" } } } } } } } }, "304": { "description": "Not modified - passport unchanged", "headers": { "ETag": { "description": "Entity tag for caching", "schema": { "type": "string", "example": "W/\"ap_a2d10232c6534523812423eec8a1425c_2025-01-16T10:30:00Z_v1.0\"" } } } }, "400": { "description": "Bad request - invalid agent ID", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "invalid_agent_id", "message": "Agent ID must match pattern ap_[a-zA-Z0-9]+" } } } }, "403": { "description": "Forbidden - agent not indexed or passport expired", "headers": { "X-Expiry-Status": { "description": "Expiry status (only present for expired passports)", "schema": { "type": "string", "enum": [ "expired" ] } }, "X-Expired-At": { "description": "ISO 8601 timestamp when passport expired", "schema": { "type": "string", "format": "date-time" } } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "agent_not_indexed": { "value": { "error": "agent_not_indexed", "message": "Agent not found in registry" } }, "passport_expired": { "value": { "error": "passport_expired", "message": "Passport expired at 2025-01-16T10:30:00Z" } } } } } }, "404": { "description": "Passport not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "passport_not_found", "message": "Passport with ID ap_a2d10232c6534523812423eec8a1425c not found" } } } }, "429": { "description": "Too many requests - rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "rate_limit_exceeded", "message": "Too many requests, please try again later" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "An unexpected error occurred" } } } }, "503": { "description": "Service unavailable - high availability fallback failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "service_unavailable", "message": "All verification services are temporarily unavailable" } } } } } } }, "/api/verify/attestation/{attestation_id}": { "get": { "summary": "Verify an attestation", "description": "Public endpoint to verify attestations cryptographically without requiring authentication. Provides cryptographic verification of attestations and their Verifiable Attestation chain.", "operationId": "verifyAttestationPublic", "tags": [ "Public" ], "parameters": [ { "name": "attestation_id", "in": "path", "required": true, "description": "The attestation ID to verify", "schema": { "type": "string", "pattern": "^att_[a-zA-Z0-9_]+$", "example": "att_1234567890_abcdef" } }, { "name": "public_key", "in": "query", "required": false, "description": "Registry public key for verification (if not using default)", "schema": { "type": "string", "format": "base64", "example": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0K..." } } ], "responses": { "200": { "description": "Attestation verification successful", "content": { "application/json": { "schema": { "type": "object", "required": [ "valid" ], "properties": { "valid": { "type": "boolean", "description": "Whether the attestation is cryptographically valid", "example": true }, "attestation": { "type": "object", "description": "Public attestation data (if valid)", "properties": { "id": { "type": "string", "example": "att_1234567890_abcdef" }, "type": { "type": "string", "example": "email_verification" }, "subject": { "type": "string", "example": "user@example.com" }, "issued_at": { "type": "string", "format": "date-time", "example": "2025-01-16T10:30:00Z" }, "expires_at": { "type": "string", "format": "date-time", "example": "2025-02-16T10:30:00Z" }, "evidence": { "type": "object", "description": "Verification evidence", "additionalProperties": true } } }, "audit_trail": { "type": "array", "description": "Verifiable audit trail", "items": { "type": "object", "properties": { "action": { "type": "string", "example": "attestation_created" }, "timestamp": { "type": "string", "format": "date-time", "example": "2025-01-16T10:30:00Z" }, "signature": { "type": "string", "example": "ed25519:xyz789" }, "hash": { "type": "string", "example": "sha256:abc123def456" } } } }, "verification_details": { "type": "object", "description": "Cryptographic verification details", "properties": { "signature_valid": { "type": "boolean", "example": true }, "key_id": { "type": "string", "example": "key_123" }, "algorithm": { "type": "string", "example": "Ed25519" }, "verified_at": { "type": "string", "format": "date-time", "example": "2025-01-16T10:30:00Z" } } }, "errors": { "type": "array", "description": "Any verification errors", "items": { "type": "string" }, "example": [] } } } } } }, "400": { "description": "Bad request - invalid attestation ID or missing public key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "invalid_attestation_id", "message": "Attestation ID must match pattern att_[a-zA-Z0-9_]+" } } } }, "404": { "description": "Attestation not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "valid": { "type": "boolean", "example": false }, "errors": { "type": "array", "items": { "type": "string" }, "example": [ "Attestation not found" ] } } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "An unexpected error occurred during verification" } } } } } } }, "/api/verify/audit/{record_id}": { "get": { "summary": "Verify an immutable audit record", "description": "External verification endpoint for immutable audit records that allows third-party auditors\nto verify audit records independently without requiring Aport authentication. This endpoint\nprovides cryptographic proof of record integrity and tamper-proof verification.\n\n**Key Features:**\n- **Independent Verification**: No Aport authentication required\n- **Cryptographic Proof**: Ed25519 signature verification\n- **Hash Chain Validation**: Detect tampering in audit chains\n- **Multiple Lookup Methods**: Search by record ID or record hash\n- **Compliance Ready**: Meets SOX, GDPR, PCI DSS, HIPAA requirements\n\n**Lookup Methods:**\n- By Record ID: `imm_audit_${timestamp}_${random}`\n- By Record Hash: `sha256:${hash}` or base64-encoded hash\n- By Decision ID: `dec_${timestamp}_${random}` (finds audit record for a policy decision)\n- With Tenant/Agent: Direct lookup for faster performance\n\n**Verification Process:**\n1. Locate record by ID or hash\n2. Verify Ed25519 signature\n3. Validate hash chain integrity\n4. Check timestamp validity\n5. Verify registry key authenticity\n\n**Use Cases:**\n- Regulatory compliance audits\n- Third-party security assessments\n- Legal discovery processes\n- Internal audit verification\n- Forensic analysis\n", "operationId": "verifyAuditRecord", "tags": [ "Audit Verification" ], "parameters": [ { "in": "path", "name": "record_id", "required": true, "description": "The audit record identifier. Can be either:\n- Record ID: `imm_audit_${timestamp}_${random}`\n- Record Hash: `sha256:${hash}` or base64-encoded hash\n- Decision ID: UUID v4 format (e.g., `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`) or legacy `dec_${timestamp}_${random}` format\n- Special value `debug` for storage inspection\n", "schema": { "type": "string", "pattern": "^(imm_audit_|sha256:|dec_|debug$|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$", "example": "imm_audit_1759871608197_km0oe6peg" } }, { "in": "query", "name": "tenant_id", "required": false, "description": "Tenant ID for direct lookup (faster than search)", "schema": { "type": "string", "pattern": "^ap_user_[a-f0-9]{16}$", "example": "ap_user_1e635f2460229a9d" } }, { "in": "query", "name": "agent_id", "required": false, "description": "Agent ID for direct lookup (faster than search)", "schema": { "type": "string", "pattern": "^ap_[a-f0-9]{32}$", "example": "ap_49bf9a40de2e487eb2e470414c7a568b" } }, { "in": "query", "name": "public_key", "required": false, "description": "Registry public key for signature verification (uses default if not provided)", "schema": { "type": "string", "example": "iba2e5EXB5NKN4Fu0U0XcvTjzRNq9fR9Uyo2g7mcXE4=" } }, { "in": "query", "name": "include_chain", "required": false, "description": "Include hash chain verification details", "schema": { "type": "boolean", "default": false } }, { "in": "query", "name": "include_instructions", "required": false, "description": "Include detailed verification instructions for external auditors", "schema": { "type": "boolean", "default": false } } ], "responses": { "200": { "description": "Audit record verification result", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "description": "Whether the verification was successful", "example": true }, "record": { "type": "object", "description": "The verified audit record", "properties": { "id": { "type": "string", "description": "Unique record identifier", "example": "imm_audit_1759871608197_km0oe6peg" }, "tenant_id": { "type": "string", "description": "Tenant/organization ID", "example": "ap_user_1e635f2460229a9d" }, "agent_id": { "type": "string", "description": "Agent ID", "example": "ap_49bf9a40de2e487eb2e470414c7a568b" }, "action_type": { "type": "string", "description": "Type of action performed", "enum": [ "create", "update", "status_change", "verify", "policy_decision" ], "example": "policy_decision" }, "timestamp": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp of the action", "example": "2025-10-07T21:13:28.179Z" }, "record_hash": { "type": "string", "description": "SHA-256 hash of the record (base64-encoded)", "example": "ztIM/nI7hVD8VW3dTmziVxOHg0EfBs5DP/FcBSQmZUQ=" }, "prev_hash": { "type": "string", "description": "Hash of the previous record in the chain", "example": "OkevyHauxuuaofSGYdGsWgpSoG8V5N28wwHr8ruWti4=" }, "signature": { "type": "string", "description": "Ed25519 signature of the record", "example": "ed25519:rmkQxbH/5QiczMF5M6pU2ddJCYU1SmvKxKj0fBgZg9GwkRjJwf8VVlzS5YU7rFYhJ4mxqUlSkzLoLvp+oh0DJQ==" }, "registry_key_id": { "type": "string", "description": "Registry key identifier used for signing", "example": "reg-2025-01" }, "created_at": { "type": "string", "format": "date-time", "description": "Record creation timestamp", "example": "2025-10-07T21:13:28.197Z" } } }, "verification_result": { "type": "object", "description": "Detailed verification results", "properties": { "valid": { "type": "boolean", "description": "Overall verification status", "example": true }, "record_id": { "type": "string", "description": "Verified record ID", "example": "imm_audit_1759871608197_km0oe6peg" }, "signature_verified": { "type": "boolean", "description": "Ed25519 signature verification status", "example": true }, "hash_chain_verified": { "type": "boolean", "description": "Hash chain integrity verification status", "example": true }, "prev_hash_verified": { "type": "boolean", "description": "Previous record hash verification status", "example": true }, "timestamp_valid": { "type": "boolean", "description": "Timestamp validity check", "example": true }, "registry_key_verified": { "type": "boolean", "description": "Registry key authenticity verification", "example": true }, "errors": { "type": "array", "items": { "type": "string" }, "description": "List of verification errors (if any)", "example": [] }, "verification_timestamp": { "type": "string", "format": "date-time", "description": "When the verification was performed", "example": "2025-10-07T21:56:28.187Z" }, "public_key_used": { "type": "string", "description": "Public key used for verification", "example": "iba2e5EXB5NKN4Fu0U0XcvTjzRNq9fR9Uyo2g7mcXE4=" } } }, "chain_integrity": { "type": "object", "description": "Hash chain integrity details (if include_chain=true)", "properties": { "valid": { "type": "boolean", "description": "Overall chain integrity status", "example": true }, "total_records": { "type": "integer", "description": "Total records in the chain", "example": 45 }, "first_hash": { "type": "string", "description": "Hash of the first record in the chain", "example": "sha256:d14724d4d55afecd9e39a6771532185cc7c87c5e90cef15c7d5ad1a0e2031521" }, "last_hash": { "type": "string", "description": "Hash of the last record in the chain", "example": "sha256:b1bf085461f575c9407b87010c4dc90e67d17b7c3333ef6cf4a6e8c6084ccfae" }, "break_points": { "type": "array", "items": { "type": "integer" }, "description": "Positions where chain integrity breaks (if any)", "example": [] } } }, "instructions": { "type": "string", "description": "Detailed verification instructions for external auditors (if include_instructions=true)", "example": "# External Audit Record Verification Instructions\n\n## Record Information\n- Record ID: imm_audit_1759871608197_km0oe6peg\n- Action Type: policy_decision\n- Timestamp: 2025-10-07T21:13:28.179Z\n- Agent ID: ap_49bf9a40de2e487eb2e470414c7a568b\n\n## Verification Steps\n1. Verify Ed25519 signature using the provided public key\n2. Validate hash chain integrity\n3. Check timestamp validity\n4. Verify registry key authenticity\n" }, "verification_endpoints": { "type": "array", "description": "Available verification endpoints", "items": { "type": "object", "properties": { "endpoint": { "type": "string", "example": "/verify/audit" }, "method": { "type": "string", "example": "GET" }, "parameters": { "type": "array", "items": { "type": "string" }, "example": [ "record_id", "tenant_id", "agent_id", "public_key" ] }, "description": { "type": "string", "example": "Verify a single audit record" } } } } } } } } }, "400": { "description": "Bad request - invalid parameters", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "error": { "type": "string", "example": "record_id is required" }, "verification_endpoints": { "type": "array", "description": "Available verification endpoints" } } } } } }, "404": { "description": "Record not found or access denied", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "error": { "type": "string", "example": "Record not found or access denied" }, "verification_endpoints": { "type": "array", "description": "Available verification endpoints" } } } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "error": { "type": "string", "example": "Internal server error" } } } } } } }, "security": [], "externalDocs": { "description": "External Verification Documentation", "url": "https://aport.io/docs" } } }, "/api/verify/audit/agent/{agent_id}": { "get": { "summary": "Get all audit records for an agent", "description": "Retrieves the complete immutable audit chain for an agent, enabling\ncomprehensive audit trail browsing and verification. This endpoint provides\nall audit records (policy decisions, passport changes, etc.) with full\ncryptographic proof.\n\n**Use Cases:**\n- Browse complete audit history for an agent\n- Verify chain integrity over time\n- Compliance auditing and reporting\n- Security incident investigation\n\n**Returns:**\n- Complete audit chain (all immutable records)\n- Chain integrity verification\n- Each record includes cryptographic signatures\n- Hash chain validation status\n", "operationId": "getAgentAuditTrail", "tags": [ "Audit Verification" ], "parameters": [ { "in": "path", "name": "agent_id", "required": true, "description": "The agent ID to retrieve audit records for", "schema": { "type": "string", "pattern": "^ap_[a-f0-9]{32}$", "example": "ap_49bf9a40de2e487eb2e470414c7a568b" } }, { "in": "query", "name": "limit", "description": "Maximum number of records to return (default 100)", "schema": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 100 } }, { "in": "query", "name": "offset", "description": "Number of records to skip (for pagination)", "schema": { "type": "integer", "minimum": 0, "default": 0 } }, { "in": "query", "name": "verify_integrity", "description": "Verify hash chain integrity (default true)", "schema": { "type": "boolean", "default": true } }, { "in": "query", "name": "action_type", "description": "Filter by action type (e.g., policy_decision, create, update)", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Audit records retrieved successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "agent_id": { "type": "string", "example": "ap_49bf9a40de2e487eb2e470414c7a568b" }, "total_records": { "type": "integer", "example": 45 }, "records": { "type": "array", "items": { "type": "object" } }, "chain_integrity": { "type": "object", "properties": { "valid": { "type": "boolean" }, "first_record": { "type": "string" }, "last_record": { "type": "string" }, "break_points": { "type": "array", "items": { "type": "integer" } } } } } } } } }, "400": { "description": "Invalid agent ID format" }, "404": { "description": "Agent not found" } } } }, "/api/verify/decisions/{agent_id}": { "get": { "summary": "Verify policy decisions for an agent", "description": "Comprehensive verification of policy decisions with Merkle tree, chain integrity, and cross-reference validation", "operationId": "verifyAgentDecisions", "tags": [ "Verification" ], "parameters": [ { "name": "agent_id", "in": "path", "required": true, "description": "The agent ID to verify decisions for", "schema": { "type": "string", "example": "ap_123456789" } }, { "name": "limit", "in": "query", "description": "Number of recent decisions to verify", "schema": { "type": "integer", "minimum": 1, "maximum": 1000, "default": 100 } }, { "name": "include_invalid", "in": "query", "description": "Include invalid decisions in response", "schema": { "type": "boolean", "default": false } }, { "name": "verify_chain", "in": "query", "description": "Verify decision chain integrity", "schema": { "type": "boolean", "default": true } }, { "name": "verify_merkle", "in": "query", "description": "Verify Merkle tree integrity", "schema": { "type": "boolean", "default": true } }, { "name": "cross_reference", "in": "query", "description": "Cross-reference with audit trail", "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Decision verification completed successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "agent_id": { "type": "string", "example": "ap_123456789" }, "total_decisions": { "type": "integer", "example": 150 }, "verified_decisions": { "type": "integer", "example": 148 }, "invalid_decisions": { "type": "integer", "example": 2 }, "verification_result": { "type": "object", "properties": { "valid_decisions": { "type": "array", "items": { "type": "string" } }, "invalid_decisions": { "type": "array", "items": { "type": "string" } }, "merkle_tree_valid": { "type": "boolean" }, "chain_integrity_valid": { "type": "boolean" }, "cross_reference_valid": { "type": "boolean" }, "verification_timestamp": { "type": "string", "format": "date-time" } } }, "decision_chain": { "type": "object", "properties": { "valid": { "type": "boolean" }, "first_decision": { "type": "string", "nullable": true }, "last_decision": { "type": "string", "nullable": true }, "break_points": { "type": "array", "items": { "type": "integer" } } } }, "merkle_tree": { "type": "object", "properties": { "valid": { "type": "boolean" }, "root_hash": { "type": "string" }, "tree_size": { "type": "integer" } } }, "cross_reference": { "type": "object", "properties": { "valid": { "type": "boolean" }, "audit_trail_matches": { "type": "integer" }, "total_audit_entries": { "type": "integer" } } }, "high_availability": { "type": "object", "properties": { "primary_available": { "type": "boolean" }, "backup_available": { "type": "boolean" }, "replication_status": { "type": "array", "items": { "type": "string" } } } }, "generated_at": { "type": "string", "format": "date-time" }, "expires_at": { "type": "string", "format": "date-time" } } } } } }, "400": { "description": "Bad request" }, "404": { "description": "Agent not found" }, "500": { "description": "Internal server error" } } } }, "/api/verify/decisions/{decision_id}": { "get": { "summary": "Look up a policy decision by decision ID", "description": "Retrieve a policy decision by its decision ID. This endpoint allows platforms\nto audit what caused a transaction (e.g., data export, payment) to be allowed\nor denied. Returns the decision details along with optional audit trail context.\n\n**Use Cases:**\n- Platform auditing: \"What decision allowed my data to be exported?\"\n- Transaction tracing: \"Why was this payment approved?\"\n- Compliance reporting: \"Show me the decision that authorized this action\"\n\n**Features:**\n- Lookup by decision ID (e.g., `dec_1234567890_abc123`)\n- Includes full decision context (policy, agent, reasons)\n- Optional audit record retrieval\n- Cryptographic verification of decision integrity\n", "operationId": "getDecisionById", "tags": [ "Decisions" ], "parameters": [ { "name": "decision_id", "in": "path", "required": true, "description": "The decision ID to look up. Can be:\n- UUID v4 format: `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx` (primary format)\n- Legacy format: `dec_${timestamp}_${random}`\n", "schema": { "type": "string", "pattern": "^(dec_[a-zA-Z0-9_]+|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$", "example": "a3c13eba-95d5-44b5-8f4e-b4b55c241aa9" } }, { "name": "include_audit", "in": "query", "required": false, "description": "Include the related audit record in the response", "schema": { "type": "boolean", "default": false } }, { "name": "include_context", "in": "query", "required": false, "description": "Include the full policy context that was evaluated", "schema": { "type": "boolean", "default": true } }, { "name": "verify_signature", "in": "query", "required": false, "description": "Verify the cryptographic signature of the decision", "schema": { "type": "boolean", "default": true } } ], "responses": { "200": { "description": "Decision found and returned", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "decision": { "type": "object", "properties": { "decision_id": { "type": "string", "example": "dec_1234567890_abc123" }, "agent_id": { "type": "string", "example": "ap_49bf9a40de2e487eb2e470414c7a568b" }, "policy_id": { "type": "string", "example": "governance.data.access.v1" }, "allow": { "type": "boolean", "example": true }, "reasons": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "severity": { "type": "string" } } } }, "timestamp": { "type": "string", "format": "date-time" }, "signature": { "type": "string", "description": "Ed25519 signature of the decision" }, "integrity_proof": { "type": "object", "description": "Cryptographic proof of decision integrity" } } }, "audit_record": { "type": "object", "description": "Related audit record (if include_audit=true)" }, "verification": { "type": "object", "properties": { "signature_valid": { "type": "boolean" }, "integrity_valid": { "type": "boolean" }, "verified_at": { "type": "string", "format": "date-time" } } } } } } } }, "400": { "description": "Bad request - invalid decision ID format" }, "404": { "description": "Decision not found", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "error": { "type": "string", "example": "Decision not found" } } } } } }, "500": { "description": "Internal server error" } } } }, "/api/verify/policy/{pack_id}": { "post": { "summary": "Verify policy decision", "description": "Hot path policy verification, multi-region/multi-tenant support, and comprehensive performance monitoring.\nEvaluates policy decisions based on agent capabilities and context.\n\n**Request Structure & OAP Spec Compliance:**\n- **Three modes supported:**\n 1. **Local Mode**: Provide `passport` in request body (optional `agent_id` in context)\n 2. **Cloud Mode**: Provide `agent_id` in `body.context.agent_id` (passport fetched from registry)\n 3. **Policy-in-body Mode**: Set path `pack_id` to the literal **IN_BODY** and provide the full OAP policy pack in `body.policy`. Use for dynamic or generated policies (e.g. SHIELD→OAP adapter output). Passport can be in body (local) or via `agent_id` (cloud). When `pack_id` is IN_BODY, `body.policy` is **required** and must include `id` and `requires_capabilities`.\n- Policy-specific fields (OAP context) go directly in `body.context` alongside `agent_id` and `policy_id`\n- The validation automatically extracts only the OAP context (policy-specific fields) by excluding `agent_id` and `policy_id`\n- **Note**: Per OAP v1.0 spec, \"context\" contains only policy-specific fields. Our API's `body.context` is a\n convenience wrapper that includes `agent_id`, `policy_id`, and the OAP context for a single request structure.\n\n**Policy Schema Discovery:**\nSince context fields vary by policy type, use these endpoints to discover the exact required fields:\n- `GET /api/policies` - Get all policies with their `required_context` schemas\n- `GET /api/policies/{pack_id}` - Get a specific policy with its `required_context` schema\n- `GET /api/policies/{pack_id}?format=schema` - Get only the `required_context` JSON schema\n", "operationId": "verifyPolicyDecision", "tags": [ "Verification" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "pack_id", "in": "path", "required": true, "description": "Policy pack identifier to evaluate, or the literal **IN_BODY** to supply the policy in the request body.\n- **Named pack**: Use a registered policy id (e.g. `finance.payment.refund.v1`, `system.command.execute.v1`). Policy is loaded from the registry.\n- **IN_BODY**: Supply the full OAP policy pack in `body.policy` (required when pack_id is IN_BODY). Use for dynamic/generated policies (e.g. from SHIELD→OAP adapter).\n", "schema": { "type": "string", "pattern": "^(IN_BODY|[a-z_]+\\.[a-z_]+\\.v\\d+|[a-z_]+\\.v\\d+)$", "example": "finance.payment.refund.v1" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "context" ], "properties": { "context": { "type": "object", "required": [], "description": "Verification context containing agent identification and policy-specific data.\nAll fields (agent_id, policy_id, and policy-specific fields) are at the same level.\n\n**OAP Spec Compliance:**\nPer OAP v1.0 specification, \"context\" contains only policy-specific fields (amount, currency,\norder_id, etc.). This API's `body.context` is a convenience wrapper that includes:\n- `agent_id` (optional): Agent passport identifier\n - **Required** when `passport` is NOT provided (cloud mode - fetches from registry)\n - **Optional** when `passport` is provided (local mode - uses passport.agent_id)\n- `policy_id` (optional): Policy identifier (defaults to pack_id from URL)\n- OAP context fields: Policy-specific fields as defined in the policy's `required_context` schema\n\nThe validation automatically extracts and validates only the OAP context (policy-specific fields)\nby excluding `agent_id` and `policy_id`, ensuring compliance with OAP v1.0 specification.\n\n**Schema Discovery:**\nFor the exact required fields for each policy, query:\n- `GET /api/policies` - Get all policies with their schemas\n- `GET /api/policies/{pack_id}` - Get a specific policy with its `required_context` schema\n- `GET /api/policies/{pack_id}?format=schema` - Get only the `required_context` JSON schema\n", "additionalProperties": true, "properties": { "agent_id": { "type": "string", "required": false, "description": "Agent passport identifier.\n- **Required** when `passport` is NOT provided in request body (cloud mode)\n- **Optional** when `passport` is provided (local mode - will use passport.agent_id if omitted)\n- If both `agent_id` and `passport.agent_id` are provided, they must match\n", "pattern": "^ap_[a-zA-Z0-9]+$", "example": "ap_a2d10232c6534523812423eec8a1425c" }, "policy_id": { "type": "string", "required": false, "description": "Optional policy identifier. If omitted, uses the pack_id from the URL path.\nUseful when the same policy pack has multiple policy variants.\n", "example": "finance.payment.refund.v1" }, "amount": { "type": "number", "description": "Transaction amount (policy-specific)", "example": 5000 }, "currency": { "type": "string", "description": "Currency code (ISO 4217)", "example": "USD" }, "transaction_id": { "type": "string", "description": "Transaction identifier", "example": "txn_123456" }, "mcp_servers": { "type": "array", "description": "Array of MCP server identifiers being used (preferred over single mcp_server).\nEach server must be in the agent's passport allowlist.\n", "items": { "type": "string" }, "example": [ "mcp_server_1", "mcp_server_2" ] }, "mcp_tools": { "type": "array", "description": "Array of MCP tool identifiers being used (preferred over single mcp_tool).\nEach tool must be in the agent's passport allowlist.\n", "items": { "type": "string" }, "example": [ "mcp_tool_1", "mcp_tool_2" ] }, "mcp_session": { "type": "string", "description": "Optional MCP session identifier for audit trail", "example": "session_abc123" }, "mcp_server": { "type": "string", "description": "Single MCP server identifier (backward compatibility).\nUse mcp_servers array for multiple servers.\n", "example": "mcp_server_1" }, "mcp_tool": { "type": "string", "description": "Single MCP tool identifier (backward compatibility).\nUse mcp_tools array for multiple tools.\n", "example": "mcp_tool_1" } }, "example": { "agent_id": "ap_a2d10232c6534523812423eec8a1425c", "amount": 5000, "currency": "USD", "transaction_id": "txn_123456", "mcp_servers": [ "mcp_server_1", "mcp_server_2" ], "mcp_tools": [ "mcp_tool_1" ], "mcp_session": "session_abc123", "idempotency_key": { "type": "string", "required": false, "description": "Idempotency key for duplicate request prevention.\nIf provided, duplicate requests with the same key will return the same decision.\n", "example": "idemp_123456789" } } }, "passport": { "type": "object", "required": false, "description": "**Local Mode**: Optional passport data for offline/local verification.\n\n**When provided:**\n- Endpoint uses this passport data directly (no registry lookup)\n- `agent_id` in context becomes optional (uses `passport.agent_id` if omitted)\n- Useful for offline/air-gapped scenarios, local-first deployments, or when you have a cached passport\n- Must contain `agent_id` and `owner_id` fields\n\n**When NOT provided (Cloud Mode):**\n- Endpoint fetches passport from registry using `context.agent_id`\n- `agent_id` in context becomes required\n\n**Validation:**\n- If both `context.agent_id` and `passport.agent_id` are provided, they must match\n- Passport must contain valid `agent_id` and `owner_id` fields\n", "$ref": "#/components/schemas/Passport", "example": { "agent_id": "ap_a2d10232c6534523812423eec8a1425c", "owner_id": "ap_org_123", "status": "active", "capabilities": [ { "id": "system.command.execute" } ], "limits": { "allowed_commands": [ "npm", "git", "node" ], "blocked_patterns": [ "rm -rf", "sudo" ] } } }, "policy": { "type": "object", "required": false, "description": "**Policy-in-body (pack_id = IN_BODY):** Full OAP policy pack object. **Required** when the path parameter `pack_id` is the literal `IN_BODY`; otherwise omit.\nUse for dynamic or generated policies (e.g. output from SHIELD→OAP adapter) so the verifier evaluates the supplied pack instead of loading from the registry.\nMust include at least:\n- `id` (string): Policy pack identifier (e.g. \"shield.system.command.execute.v1\")\n- `requires_capabilities` (array of strings): OAP capabilities this policy governs (e.g. [\"system.command.execute\"])\nOptional but typical: `evaluation_rules`, `limits_required`, `min_assurance`, `name`, `description`, `version`, `status`.\nWhen provided with IN_BODY, the generic evaluator runs against this policy and the request context; passport is still required (in body or via agent_id).\n", "additionalProperties": true, "properties": { "id": { "type": "string", "description": "Policy pack identifier", "example": "shield.system.command.execute.v1" }, "requires_capabilities": { "type": "array", "items": { "type": "string" }, "description": "OAP capabilities this policy governs", "example": [ "system.command.execute" ] }, "evaluation_rules": { "type": "array", "description": "OAP evaluation rules (expressions, custom_validators, etc.)" }, "limits_required": { "type": "array", "items": { "type": "string" }, "description": "Limit keys required in passport (e.g. allowed_commands, blocked_patterns)" } }, "example": { "id": "shield.system.command.execute.v1", "name": "System Command Execution (from SHIELD)", "requires_capabilities": [ "system.command.execute" ], "limits_required": [ "allowed_commands", "max_execution_time" ] } } } } } } }, "responses": { "200": { "description": "Policy verification successful", "headers": { "Server-Timing": { "description": "Performance timing information", "schema": { "type": "string", "example": "kv-read;dur=25, policy-eval;dur=15, total;dur=40" } } }, "content": { "application/json": { "schema": { "type": "object", "required": [ "success", "data", "requestId" ], "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "required": [ "decision" ], "properties": { "decision": { "type": "object", "required": [ "decision_id", "created_at", "allow", "reasons", "expires_in" ], "properties": { "decision_id": { "type": "string", "description": "Unique decision identifier", "example": "dec_123456789" }, "created_at": { "type": "string", "format": "date-time", "description": "Decision creation timestamp", "example": "2025-01-16T10:30:00Z" }, "allow": { "type": "boolean", "description": "Whether the action is allowed", "example": true }, "reasons": { "type": "array", "description": "Decision reasoning", "items": { "type": "object", "properties": { "code": { "type": "string", "example": "capability_verified" }, "message": { "type": "string", "example": "Agent has required refund capability" }, "severity": { "type": "string", "enum": [ "info", "warning", "error" ], "example": "info" } } } }, "expires_in": { "type": "number", "description": "Decision TTL in seconds", "example": 300 }, "assurance_level": { "type": "string", "description": "Required assurance level", "example": "L4KYC" }, "passport_digest": { "type": "string", "description": "Passport data digest for verification", "example": "sha256:abc123def456" }, "signature": { "type": "string", "description": "Ed25519 signature of the decision", "example": "ed25519:xyz789" }, "remaining_daily_cap": { "type": "object", "description": "Remaining daily limits by currency", "additionalProperties": { "type": "number" }, "example": { "USD": 45000 } }, "owner_id": { "type": "string", "description": "Passport owner ID", "example": "ap_org_456" }, "policy_id": { "type": "string", "description": "Policy pack identifier", "example": "finance.payment.refund.v1" }, "kid": { "type": "string", "description": "Key identifier for signature verification", "example": "key_123" }, "decision_token": { "type": "string", "description": "Compact JWT for sub-TTL caching", "example": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9..." } } }, "passport": { "$ref": "#/components/schemas/Passport" } } }, "requestId": { "type": "string", "description": "Unique request identifier", "example": "policy_123456789_abc123" }, "performance": { "type": "object", "description": "Performance metrics", "properties": { "total_time_ms": { "type": "number", "example": 40 }, "policy_eval_time_ms": { "type": "number", "example": 15 }, "kv_read_time_ms": { "type": "number", "example": 25 }, "cache_hit": { "type": "boolean", "example": true } } } } } } } }, "400": { "description": "Bad request - invalid policy or context", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "invalid_policy", "message": "Policy pack 'invalid.policy' not found" } } } }, "401": { "description": "Unauthorized - invalid or missing authentication", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "unauthorized", "message": "Valid authentication required" } } } }, "403": { "description": "Forbidden - policy evaluation denied", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "policy_denied", "message": "Agent lacks required capabilities for this policy" } } } }, "404": { "description": "Agent passport not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "passport_not_found", "message": "Passport with ID ap_a2d10232c6534523812423eec8a1425c not found" } } } }, "409": { "description": "Conflict - idempotency key already used", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "idempotency_conflict", "message": "Idempotency key already used for this policy" } } } }, "429": { "description": "Too many requests - rate limit exceeded", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "rate_limit_exceeded", "message": "Too many requests, please try again later" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "error": "internal_server_error", "message": "An unexpected error occurred" } } } } } } }, "/api/webhooks/{webhook_id}/rotate": { "post": { "summary": "Rotate webhook secret", "description": "Generate a new secret for a webhook", "operationId": "rotateWebhookSecret", "tags": [ "Webhooks" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "webhook_id", "in": "path", "required": true, "description": "The webhook ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Webhook secret rotated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookSecretRotateResponse" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Webhook not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/webhooks/{webhook_id}/test": { "post": { "summary": "Test a webhook", "description": "Send a test event to a webhook endpoint", "operationId": "testWebhook", "tags": [ "Webhooks" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "webhook_id", "in": "path", "required": true, "description": "The webhook ID", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookTestRequest" } } } }, "responses": { "200": { "description": "Webhook test completed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookTestResponse" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Webhook not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/webhooks/{webhook_id}": { "put": { "summary": "Update a webhook", "description": "Update an existing webhook configuration", "operationId": "updateWebhook", "tags": [ "Webhooks" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "webhook_id", "in": "path", "required": true, "description": "The webhook ID", "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateWebhookRequest" } } } }, "responses": { "200": { "description": "Webhook updated successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookConfig" } } } }, "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Webhook not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "summary": "Delete a webhook", "description": "Delete an existing webhook", "operationId": "deleteWebhook", "tags": [ "Webhooks" ], "security": [ { "BearerAuth": [] } ], "parameters": [ { "name": "webhook_id", "in": "path", "required": true, "description": "The webhook ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Webhook deleted successfully" }, "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Webhook not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/api/webhooks": { "post": { "summary": "Create a new webhook", "description": "Register a webhook endpoint for receiving notifications", "operationId": "createWebhook", "tags": [ "Webhooks" ], "security": [ { "BearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "target": { "type": "string", "enum": [ "user", "org", "agent" ], "description": "The type of entity this webhook is for" }, "target_id": { "type": "string", "description": "The ID of the target entity" }, "agent_id": { "type": "string", "description": "Optional agent ID for agent-level overrides" }, "url": { "type": "string", "format": "uri", "description": "The webhook endpoint URL" }, "secret": { "type": "string", "description": "Secret for signing webhook payloads" }, "events": { "type": "array", "items": { "type": "string", "enum": [ "status.changed", "passport.updated", "assurance.updated", "attestation.created", "attestation.verified", "instance.created", "instance.suspended" ] }, "description": "List of events to subscribe to" }, "active": { "type": "boolean", "default": true, "description": "Whether the webhook is active" }, "retry_attempts": { "type": "integer", "default": 3, "minimum": 1, "maximum": 10, "description": "Number of retry attempts" }, "timeout_ms": { "type": "integer", "default": 5000, "minimum": 1000, "maximum": 30000, "description": "Request timeout in milliseconds" } }, "required": [ "target", "target_id", "url", "secret", "events" ] } } } }, "responses": { "201": { "description": "Webhook created successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "message": { "type": "string" }, "webhook": { "$ref": "#/components/schemas/WebhookConfig" } } } } } }, "400": { "description": "Bad request" }, "401": { "description": "Unauthorized" }, "500": { "description": "Internal server error" } } }, "get": { "summary": "List webhooks", "description": "Get all webhooks for the authenticated user or organization", "operationId": "listWebhooks", "tags": [ "Webhooks" ], "parameters": [ { "name": "target", "in": "query", "required": false, "description": "Filter by target type", "schema": { "type": "string", "enum": [ "user", "org", "agent" ] } }, { "name": "target_id", "in": "query", "required": false, "description": "Filter by target ID", "schema": { "type": "string" } }, { "name": "agent_id", "in": "query", "required": false, "description": "Filter by agent ID", "schema": { "type": "string" } } ], "responses": { "200": { "description": "List of webhooks", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WebhookListResponse" } } } }, "401": { "description": "Unauthorized" }, "500": { "description": "Internal server error" } } } } }, "tags": [] }