The Admin Server provides full CRUD operations for managing:
The Agentic Identity Broker uses a dual-port HTTP server architecture:
All endpoints require authentication via reverse proxy (oauth2-proxy, nginx, etc.).
The proxy validates user credentials and sets the principal identifier in the
X-Remote-User header (configurable via auth.principal_header).
"REDACTED"Services can be configured with automatic endpoint discovery:
{issuer_uri}/.well-known/oauth-authorization-servertoken_endpoint and authorize_endpoint configurationBy default, every HTTP response from this API includes the additive W3C
traceresponse response header.
<trace-id> field is the request correlation identifier operators can use to find matching logs.request_context.trace.response_enabled.All error responses follow a consistent format with appropriate HTTP status codes. See the ErrorResponse schema for details.
Returns the current health status of the HTTP server. Each server (end-user and admin) has its own independent health endpoint that reports only that server's status.
This endpoint is public and does not require authentication.
Status Codes:
200 OK: Server is healthy and accepting requests503 Service Unavailable: Server is starting, shutting down, or unhealthyHealth States:
healthy: Server is operational and processing requests normallystarting: Server is initializing (binding to port, setting up routes)shutting_down: Graceful shutdown in progress, completing in-flight requestsunhealthy: Server encountered an error and requires restart{- "status": "healthy",
- "timestamp": "2025-12-19T10:30:00Z",
- "uptime_seconds": 3600
}Retrieve a list of all registered agents in the system.
Returns a direct array of agent objects (no envelope). Agents are returned in no guaranteed order.
| Prefer | string Example: reference-id=canonical Request canonical rendering of nested service and permission-set references. The default
representation uses UUIDs. May be combined with other Prefer preferences (e.g.
|
[- {
- "id": "550e8400-e29b-41d4-a716-446655440000",
- "client_id": "agent-research-assistant",
- "display_name": "Research Assistant",
- "description": "AI assistant that helps with academic research",
- "permission_sets": [
- {
- "permission_set_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
- "requirement_type": "mandatory"
}
], - "created_at": "2025-12-01T10:00:00Z",
- "updated_at": "2025-12-01T10:00:00Z"
}, - {
- "id": "660e8400-e29b-41d4-a716-446655440001",
- "client_id": "agent-data-analyst",
- "external_id": "gov-sys-12345",
- "display_name": "Data Analyst",
- "description": "Analyzes datasets and generates insights",
- "permission_sets": [
- {
- "permission_set_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
- "requirement_type": "mandatory"
}
], - "created_at": "2025-12-05T14:30:00Z",
- "updated_at": "2025-12-10T09:15:00Z"
}
]Register a new AI agent in the identity broker system.
The client_id field is the upstream OAuth2 client ID used when proxying
authorization requests to the upstream server.
client_id uniqueness depends on configuration:
multi_agent_client.enabled = false (default): client_id must be unique
across all agents. Returns 409 Conflict if a duplicate client_id is detected.multi_agent_client.enabled = true: Multiple agents may share the same
client_id. No uniqueness validation is performed.Validation Rules:
client_id: Optional; when provided must be non-empty; unique across all agents when multi_agent_client.enabled = falsedisplay_name: Required, max 255 charactersdescription: Required, max 1000 charactersID Generation: System generates a UUID for the agent ID. client_id is not auto-generated — omit it for agents that do not need one.
| canonical_id | string or null [ 1 .. 128 ] characters ^[A-Za-z0-9._-]+$ |
| client_id | string <= 255 characters OAuth2 client_id for this agent. Optional — omit for agents resolved via client_uris (CIMD) or agents that do not need an upstream client_id. When provided, must be non-empty. |
| external_id | string or null <= 255 characters Optional external governance system identifier |
| display_name required | string [ 1 .. 255 ] characters Human-readable name for the agent |
| description required | string [ 1 .. 1000 ] characters Detailed description of the agent's purpose and capabilities |
| governance_url | string or null <uri> URL to governance and compliance information (must be HTTP/HTTPS) |
| user_documentation_url | string or null <uri> URL to user-facing documentation (must be HTTP/HTTPS) |
| agent_interface_url | string or null <uri> URL where users can interact with the agent (must be HTTP/HTTPS) |
Array of objects or null (ServiceRequirementRequest) List of third-party OAuth2 services that the agent requires access to. Referential integrity is validated: service_id must exist and supplied required_scopes must match the service definition. Omit or provide an empty list for scope-less services. | |
required | Array of objects (AgentPermissionSetEntry) non-empty List of permission set declarations for this agent (FR-006). Must contain at least one entry — an empty list or omitted field is a 400 error. All referenced permission_set_id values must exist. |
| redirect_uris | Array of strings or null <uri> [ items <uri > ] List of allowed redirect URIs for OAuth2 authorization code flow. When the broker acts as an OAuth2 server, only these URIs are accepted as valid redirect targets for this agent. |
| allowed_scopes | Array of strings or null List of OAuth2 scopes that this agent is permitted to request when the broker acts as an OAuth2 authorization server. |
| client_uris | Array of strings or null <uri> [ items <uri > ] Pre-registered Client ID Metadata Document URLs for this agent.
Each entry must be a globally unique HTTPS URL. A |
{- "client_id": "agent-simple-assistant",
- "display_name": "Simple Assistant",
- "description": "A basic AI assistant for general tasks",
- "permission_sets": [
- {
- "permission_set_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
- "requirement_type": "mandatory"
}
]
}{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "client_id": "agent-research-assistant",
- "external_id": "gov-sys-12345",
- "display_name": "Research Assistant",
- "description": "AI assistant that helps with academic research",
- "permission_sets": [
- {
- "permission_set_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
- "requirement_type": "mandatory"
}
], - "created_at": "2025-12-19T10:30:00Z",
- "updated_at": "2025-12-19T10:30:00Z"
}Retrieve detailed information about a specific agent.
Returns the complete agent configuration including all optional fields.
| agent-id required | string Examples:
UUID or canonical identifier of the agent |
| Prefer | string Example: reference-id=canonical Request canonical rendering of nested service and permission-set references. The default
representation uses UUIDs. May be combined with other Prefer preferences (e.g.
|
{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "client_id": "agent-research-assistant",
- "display_name": "Research Assistant",
- "description": "AI assistant that helps with academic research",
- "permission_sets": [
- {
- "permission_set_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
- "requirement_type": "mandatory"
}
], - "created_at": "2025-12-19T10:30:00Z",
- "updated_at": "2025-12-19T10:30:00Z"
}Update configuration for an existing agent.
Update Semantics:
created_at timestamp is preservedupdated_at timestamp is set to current timeclient_id uniqueness depends on configuration:
multi_agent_client.enabled = false (default): client_id must be unique
across all agents (excluding the current agent). Returns 409 Conflict if a
duplicate client_id is detected on another agent.multi_agent_client.enabled = true: Multiple agents may share the same
client_id. No uniqueness validation is performed.Validation:
client_id: Three-state — omitted preserves existing value, explicit null clears it, string value updates it (must be non-empty); unique across all agents (excluding the current agent) when multi_agent_client.enabled = false| agent-id required | string Examples:
UUID or canonical identifier of the agent |
| canonical_id | string or null [ 1 .. 128 ] characters ^[A-Za-z0-9._-]+$ Omitted preserves the current canonical ID; null removes it; a string replaces it. |
| client_id | string or null <= 255 characters OAuth2 client_id for this agent. Three-state semantics:
Agents without a client_id cannot participate in proxy-mode OAuth2 flows. |
| external_id | string or null <= 255 characters Optional external governance system identifier |
| display_name required | string [ 1 .. 255 ] characters Human-readable name for the agent |
| description required | string [ 1 .. 1000 ] characters Detailed description of the agent's purpose and capabilities |
| governance_url | string or null <uri> URL to governance and compliance information (must be HTTP/HTTPS) |
| user_documentation_url | string or null <uri> URL to user-facing documentation (must be HTTP/HTTPS) |
| agent_interface_url | string or null <uri> URL where users can interact with the agent (must be HTTP/HTTPS) |
Array of objects or null (ServiceRequirementRequest) List of third-party OAuth2 services that the agent requires access to. Referential integrity is validated: service_id must exist and supplied required_scopes must match the service definition. Omit or provide an empty list for scope-less services. | |
required | Array of objects (AgentPermissionSetEntry) non-empty List of permission set declarations for this agent (FR-006). Must contain at least one entry — an empty list or omitted field is a 400 error. All referenced permission_set_id values must exist. |
| redirect_uris | Array of strings or null <uri> [ items <uri > ] List of allowed redirect URIs for OAuth2 authorization code flow. When the broker acts as an OAuth2 server, only these URIs are accepted as valid redirect targets for this agent. |
| allowed_scopes | Array of strings or null List of OAuth2 scopes that this agent is permitted to request when the broker acts as an OAuth2 authorization server. |
| client_uris | Array of strings or null <uri> [ items <uri > ] Pre-registered Client ID Metadata Document URLs for this agent.
Replaces the previous list on PUT (full replacement semantics).
Each entry must be a globally unique HTTPS URL. A |
{- "client_id": "agent-research-assistant",
- "display_name": "Advanced Research Assistant",
- "description": "AI assistant that helps with academic research",
- "permission_sets": [
- {
- "permission_set_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
- "requirement_type": "mandatory"
}
]
}{- "id": "550e8400-e29b-41d4-a716-446655440000",
- "client_id": "agent-research-assistant",
- "display_name": "Advanced Research Assistant",
- "description": "AI assistant that helps with academic research",
- "permission_sets": [
- {
- "permission_set_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
- "requirement_type": "mandatory"
}
], - "created_at": "2025-12-19T10:30:00Z",
- "updated_at": "2025-12-19T15:45:00Z"
}Remove an agent from the system.
Cascade Behavior:
Irreversible: This operation cannot be undone
| agent-id required | string Examples:
UUID or canonical identifier of the agent |
{- "error": "agent ID is required"
}Retrieve a list of all configured third-party OAuth2 services.
Returns a direct array of service objects (no envelope).
Security: All client_secret fields are redacted as "REDACTED" for confidential services; the property is omitted for public services, which hold no credential
| Prefer | string Example: reference-id=canonical Request canonical rendering of nested service and permission-set references. The default
representation uses UUIDs. May be combined with other Prefer preferences (e.g.
|
[- {
- "id": "770e8400-e29b-41d4-a716-446655440002",
- "display_name": "GitHub Production",
- "client_id": "Iv1.1234567890abcdef",
- "client_secret": "REDACTED",
- "token_endpoint_auth_method": null,
- "discovery": {
- "enable_discovery": true
}, - "endpoints": {
}, - "scopes": [
- {
- "scope_value": "repo",
- "description": "Full control of private repositories"
}, - {
- "scope_value": "read:org",
- "description": "Read organization membership"
}
], - "created_at": "2025-12-01T09:00:00Z",
- "updated_at": "2025-12-15T14:30:00Z"
}, - {
- "id": "880e8400-e29b-41d4-a716-446655440003",
- "display_name": "Google Cloud",
- "client_id": "123456789-abcdef.apps.googleusercontent.com",
- "client_secret": "REDACTED",
- "token_endpoint_auth_method": null,
- "discovery": {
- "enable_discovery": true
}, - "endpoints": {
}, - "scopes": [
- {
- "description": "View and download Google Drive files"
}
], - "created_at": "2025-12-05T11:20:00Z",
- "updated_at": "2025-12-05T11:20:00Z"
}
]Configure a new third-party OAuth2 service provider.
Validation Rules:
display_name: Required, max 255 charactersclient_id: Required, unique across all servicesclient_secret: Required unless token_endpoint_auth_method is none (encrypted at rest, never returned)issuer_uri: Required, must be HTTPS URLscopes: Optional. Omit it or provide an empty array when the provider does not use OAuth2 scopes.Discovery Modes:
Automatic Discovery (enable_discovery: true):
{issuer_uri}/.well-known/oauth-authorization-servermetadata_url can override default discovery locationendpoints if discovery failsManual Configuration (enable_discovery: false):
endpoints.token_endpoint and endpoints.authorize_endpointSecurity: client_secret is encrypted with AES-256-GCM before storage
| canonical_id | string or null [ 1 .. 128 ] characters ^[A-Za-z0-9._-]+$ |
| display_name required | string [ 1 .. 255 ] characters Human-readable name for the service |
| oauth2_flavor | string Default: "standard" Enum: "standard" "google" "github" OAuth2 authentication variant. Defaults to
|
| client_id | string non-empty OAuth2 client_id for this service. Required when |
| client_secret | string or null Authentication credential for this service. The content depends on
SECURITY: Encrypted at rest using AES-256-GCM. Never returned in API responses (always "REDACTED"). Conditionally required: If If |
| token_endpoint_auth_method | string or null Enum: "none" null Declares that the upstream token endpoint expects no client authentication, making
this service a public client (RFC 6749 §2.1, RFC 7591 Omit this property, or send When
|
| issuer_uri | string <uri> OAuth2 issuer URI. Required when |
required | object (DiscoveryConfigRequest) |
object (OAuth2EndpointsRequest) OAuth2 endpoints configuration. Required when Each supplied | |
Array of objects (OAuth2ScopeRequest) Optional OAuth2 scopes for this service. Omit or provide an empty array when the provider does not use scopes. | |
| protected_resources | Array of strings <uri> [ items <uri > ] List of protected resource URIs for RFC 8693 token exchange (optional). These URIs identify which resources this service can provide tokens for. URIs are normalized (trailing slashes removed) for consistent matching. |
object Static provider authorization parameters. Broker-owned OAuth2 names are rejected. |
{- "display_name": "GitHub Production",
- "client_id": "Iv1.1234567890abcdef",
- "client_secret": "ghp_secretkey1234567890abcdef",
- "discovery": {
- "enable_discovery": true
}, - "scopes": [
- {
- "scope_value": "repo",
- "description": "Full control of private repositories"
}, - {
- "scope_value": "read:org",
- "description": "Read organization membership"
}, - {
- "scope_value": "user:email",
- "description": "Read user email addresses"
}
]
}{- "id": "770e8400-e29b-41d4-a716-446655440002",
- "display_name": "GitHub Production",
- "client_id": "Iv1.1234567890abcdef",
- "client_secret": "REDACTED",
- "token_endpoint_auth_method": null,
- "discovery": {
- "enable_discovery": true
}, - "endpoints": {
}, - "scopes": [
- {
- "scope_value": "repo",
- "description": "Full control of private repositories"
}, - {
- "scope_value": "read:org",
- "description": "Read organization membership"
}
], - "created_at": "2025-12-19T10:30:00Z",
- "updated_at": "2025-12-19T10:30:00Z"
}Retrieve detailed configuration for a specific OAuth2 service.
Security: All client_secret fields are redacted as "REDACTED" for confidential services; the property is omitted for public services, which hold no credential
| service-id required | string Examples:
UUID or canonical identifier of the OAuth2 service |
| Prefer | string Example: reference-id=canonical Request canonical rendering of nested service and permission-set references. The default
representation uses UUIDs. May be combined with other Prefer preferences (e.g.
|
{- "id": "770e8400-e29b-41d4-a716-446655440002",
- "display_name": "GitHub Production",
- "client_id": "Iv1.1234567890abcdef",
- "client_secret": "REDACTED",
- "token_endpoint_auth_method": null,
- "discovery": {
- "enable_discovery": true
}, - "endpoints": {
}, - "scopes": [
- {
- "scope_value": "repo",
- "description": "Full control of private repositories"
}
], - "created_at": "2025-12-19T10:30:00Z",
- "updated_at": "2025-12-19T10:30:00Z"
}Update configuration for an existing OAuth2 service.
Update Semantics:
token_endpoint_auth_method is evaluated from the request alone. Omit it or set it to null to make the service confidential, regardless of its stored value; a client_secret is then required.token_endpoint_auth_method: none removes the stored credential.created_at timestamp is preservedupdated_at timestamp is set to current timeSecret Rotation:
client_secret to rotate credentialsDiscovery Re-run:
enable_discovery: true, endpoints are re-fetchedSecurity: client_secret is redacted in response
protected_resources omitted or null: preserves the current protected-resource setprotected_resources present (including []): replaces the entire set and requires If-Match| service-id required | string Examples:
UUID or canonical identifier of the OAuth2 service |
| If-Match | string Required when a service update request includes |
| canonical_id | string or null [ 1 .. 128 ] characters ^[A-Za-z0-9._-]+$ Omitted preserves the current canonical ID; null removes it; a string replaces it. |
| display_name required | string [ 1 .. 255 ] characters Human-readable name for the service |
| oauth2_flavor | string Default: "standard" Enum: "standard" "google" "github" OAuth2 authentication variant. Defaults to
|
| client_id | string non-empty OAuth2 client_id for this service. Required when |
| client_secret | string or null Authentication credential for this service (provide new value to rotate). The content depends on
SECURITY: Encrypted at rest, never returned in responses. Conditionally required: If If |
| token_endpoint_auth_method | string or null Enum: "none" null Declares that the upstream token endpoint expects no client authentication, making
this service a public client (RFC 6749 §2.1, RFC 7591 Omit this property, or send When
Full replacement: this request replaces the service representation in full. The
method is evaluated from the request alone — omitting it, or sending |
| issuer_uri | string <uri> OAuth2 issuer URI. Required when |
required | object (DiscoveryConfigRequest) |
object (OAuth2EndpointsRequest) OAuth2 endpoints configuration. Required when Each supplied | |
Array of objects (OAuth2ScopeRequest) Optional OAuth2 scopes for this service. Omit or provide an empty array when the provider does not use scopes. | |
| protected_resources | Array of strings or null <uri> [ items <uri > ] Optional protected resource URIs for RFC 8693 token exchange. Omit or set to |
object Static provider authorization parameters. Omission preserves the current map; an empty object clears it. |
{- "display_name": "GitHub Production",
- "client_id": "Iv1.1234567890abcdef",
- "client_secret": "ghp_newsecretkey9876543210zyxwvu",
- "discovery": {
- "enable_discovery": true
}, - "scopes": [
- {
- "scope_value": "repo",
- "description": "Full control of private repositories"
}, - {
- "scope_value": "read:org",
- "description": "Read organization membership"
}
]
}{- "id": "770e8400-e29b-41d4-a716-446655440002",
- "display_name": "GitHub Production",
- "client_id": "Iv1.1234567890abcdef",
- "client_secret": "REDACTED",
- "token_endpoint_auth_method": null,
- "discovery": {
- "enable_discovery": true
}, - "endpoints": {
}, - "scopes": [
- {
- "scope_value": "repo",
- "description": "Full control of private repositories"
}, - {
- "scope_value": "read:org",
- "description": "Read organization membership"
}, - {
- "scope_value": "workflow",
- "description": "Update GitHub Actions workflows"
}
], - "created_at": "2025-12-19T10:30:00Z",
- "updated_at": "2025-12-19T16:00:00Z"
}Remove an OAuth2 service from the system.
Referential Integrity Check:
Irreversible: This operation cannot be undone
| service-id required | string Examples:
UUID or canonical identifier of the OAuth2 service |
{- "error": "client ID is required"
}Adds the body resource_uri after server-side validation and normalization. A newly added URI
returns 201. A URI already owned by this service returns 200 with the set unchanged; a URI owned
by another service returns 409 Conflict.
| service-id required | string Examples:
UUID or canonical identifier of the OAuth2 service |
| resource_uri required | string <uri> Absolute resource URI (scheme and host required), normalized by trailing-slash trim. |
{
}{
}Idempotently adds the resource URI identified by the fully percent-encoded final path segment. The server decodes the segment exactly once, then validates and normalizes it. Adding a URI this service already owns returns 200 with the set unchanged; a URI owned by another service returns 409.
| service-id required | string Examples:
UUID or canonical identifier of the OAuth2 service |
| resource required | string Example: https%3A%2F%2Fapi.example.com%2Fv2 Normalized protected resource URI, fully RFC 3986 percent-encoded as one path segment ( |
{
}Atomically changes the percent-encoded source URI in {resource} to the target URI in the body.
A source equal to the normalized target succeeds as a no-op. A target already owned by any service
returns 409; a source not owned by this service returns 404.
| service-id required | string Examples:
UUID or canonical identifier of the OAuth2 service |
| resource required | string Example: https%3A%2F%2Fapi.example.com%2Fv2 Normalized protected resource URI, fully RFC 3986 percent-encoded as one path segment ( |
| to required | string <uri> Absolute target URI (scheme and host required), normalized by trailing-slash trim. |
{
}{
}Removes the resource identified by the fully percent-encoded path segment after decoding exactly once and normalizing it. A resource not owned by this service returns 404.
| service-id required | string Examples:
UUID or canonical identifier of the OAuth2 service |
| resource required | string Example: https%3A%2F%2Fapi.example.com%2Fv2 Normalized protected resource URI, fully RFC 3986 percent-encoded as one path segment ( |
{
}Creates a new named permission set grouping OAuth2 scopes across one or more third-party services.
Validation rules:
name must be unique (409 Conflict if duplicate)service_scopes must contain at least one entry (400)service_id in service_scopes must reference an existing service (400)scopes list may be empty for a scope-less service; supplied values
must be non-empty (400)| canonical_id | string or null [ 1 .. 128 ] characters ^[A-Za-z0-9._-]+$ |
| name required | string <= 255 characters Unique human-readable name for the permission set |
| description required | string Human-readable explanation of what capabilities this set grants |
required | Array of objects (ServiceScope) non-empty One or more service/scope entries covered by this permission set |
{- "canonical_id": "github-read",
- "name": "GitHub Read Access",
- "description": "Read repository contents and user profile from GitHub",
- "service_scopes": [
- {
- "service_id": "string",
- "scopes": [
- "repo:read",
- "user:email"
], - "requirement_type": "mandatory"
}
]
}{- "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
- "canonical_id": "github-read",
- "name": "GitHub Read Access",
- "description": "Read repository contents and user profile from GitHub",
- "service_scopes": [
- {
- "service_id": "string",
- "scopes": [
- "repo:read",
- "user:email"
], - "requirement_type": "mandatory"
}
], - "created_at": "2026-03-25T12:00:00Z",
- "updated_at": "2026-03-25T12:00:00Z"
}Returns all permission sets. Optionally filter by service ID to find all permission sets that include scopes for a specific third-party service.
| service_id | string UUID or canonical identifier of the service used to filter permission sets |
| Prefer | string Example: reference-id=canonical Request canonical rendering of nested service and permission-set references. The default
representation uses UUIDs. May be combined with other Prefer preferences (e.g.
|
{- "items": [
- {
- "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
- "canonical_id": "github-read",
- "name": "GitHub Read Access",
- "description": "Read repository contents and user profile from GitHub",
- "service_scopes": [
- {
- "service_id": "string",
- "scopes": [
- "repo:read",
- "user:email"
], - "requirement_type": "mandatory"
}
], - "created_at": "2026-03-25T12:00:00Z",
- "updated_at": "2026-03-25T12:00:00Z"
}
]
}| permission-set-id required | string Examples:
UUID or canonical identifier of the permission set |
| Prefer | string Example: reference-id=canonical Request canonical rendering of nested service and permission-set references. The default
representation uses UUIDs. May be combined with other Prefer preferences (e.g.
|
{- "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
- "canonical_id": "github-read",
- "name": "GitHub Read Access",
- "description": "Read repository contents and user profile from GitHub",
- "service_scopes": [
- {
- "service_id": "string",
- "scopes": [
- "repo:read",
- "user:email"
], - "requirement_type": "mandatory"
}
], - "created_at": "2026-03-25T12:00:00Z",
- "updated_at": "2026-03-25T12:00:00Z"
}Fully replaces a permission set's name, description, and service_scopes. All fields are required (PUT semantics — full replacement).
Note: Changing service_scopes takes effect immediately; the next token exchange
for any grant referencing this set will use the updated scopes (cache TTL ≤ 60s delay).
| permission-set-id required | string Examples:
UUID or canonical identifier of the permission set |
| canonical_id | string or null [ 1 .. 128 ] characters ^[A-Za-z0-9._-]+$ |
| name required | string <= 255 characters Unique human-readable name for the permission set |
| description required | string Human-readable explanation of what capabilities this set grants |
required | Array of objects (ServiceScope) non-empty One or more service/scope entries covered by this permission set |
{- "canonical_id": "github-read",
- "name": "GitHub Read Access",
- "description": "Read repository contents and user profile from GitHub",
- "service_scopes": [
- {
- "service_id": "string",
- "scopes": [
- "repo:read",
- "user:email"
], - "requirement_type": "mandatory"
}
]
}{- "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
- "canonical_id": "github-read",
- "name": "GitHub Read Access",
- "description": "Read repository contents and user profile from GitHub",
- "service_scopes": [
- {
- "service_id": "string",
- "scopes": [
- "repo:read",
- "user:email"
], - "requirement_type": "mandatory"
}
], - "created_at": "2026-03-25T12:00:00Z",
- "updated_at": "2026-03-25T12:00:00Z"
}Deletes a permission set by ID.
Rejected with 409 Conflict if any agent's permission_sets list references this ID,
or if any active user grant references this permission set.
Admins must remove the permission set from all agents and revoke all active grants
referencing it before deletion.
Irreversible: This operation cannot be undone.
| permission-set-id required | string Examples:
UUID or canonical identifier of the permission set |
{- "error": "validation failed",
- "message": "display_name exceeds 255 characters (got 300)"
}Generate new broker-issued client credentials for an agent, or rotate existing credentials. This allows the broker to act as an OAuth2 authorization server and authenticate agents directly.
Runtime usage: Agents use the client_id returned here as client_id at
the /oauth2/token endpoint. The value is the agent's UUID.
First Generation (no existing credentials):
201 Created with new client_id (metadata) and client_secretclient_secret is only returned in this response — store it securelyRotation (existing credentials):
200 OK with new credentials and previous_invalidated_at timestamp| agent-id required | string Examples:
UUID or canonical identifier of the agent |
{- "client_id": "550e8400-e29b-41d4-a716-446655440000",
- "client_secret": "brk_sec_q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2",
- "created_at": "2025-12-19T15:45:00Z",
- "previous_invalidated_at": "2025-12-19T15:45:00Z"
}Retrieve metadata about an agent's broker-issued client credentials.
Security: The client_secret is never returned by this endpoint.
Only the client_id and timestamps are returned.
Returns 404 Not Found if no credentials have been generated for the agent.
| agent-id required | string Examples:
UUID or canonical identifier of the agent |
{- "client_id": "550e8400-e29b-41d4-a716-446655440000",
- "created_at": "2025-12-19T10:30:00Z",
- "rotated_at": "2025-12-19T15:45:00Z"
}Revoke an agent's broker-issued client credentials.
After revocation, the agent can no longer authenticate using these credentials. Active tokens issued with these credentials remain valid until expiry.
Irreversible: New credentials must be generated via POST after revocation.
| agent-id required | string Examples:
UUID or canonical identifier of the agent |
{- "error": "invalid request",
- "message": "agent ID must be a valid UUID"
}Generate a new signing key for the broker's OAuth2 server.
The new key is marked as is_current: true but does not start signing tokens
until activates_at has passed (grace period = 2 × JWKS Cache-Control: max-age
value, currently 600 s). During this window the key is already present in the JWKS
response, so every client cache will have learned about it before the first token
signed with it appears.
Algorithm Support:
ES256: ECDSA using P-256 curve and SHA-256 (default, only supported algorithm)Key Lifecycle:
GET /oauth2/jwks.jsonactivates_at (now + 600 s)| algorithm | string Default: "ES256" Value: "ES256" Signing algorithm for the new key.
|
{ }{- "kid": "key-2025-12-19-001",
- "algorithm": "ES256",
- "is_current": true,
- "activates_at": "2025-12-19T10:40:00Z",
- "created_at": "2025-12-19T10:30:00Z"
}Retrieve all active signing keys for the broker's OAuth2 server.
Security: Private key material is never included in the response. Only public metadata (kid, algorithm, status, timestamps) is returned.
Keys are returned in creation order (newest first).
{- "items": [
- {
- "kid": "key-2025-12-19-001",
- "algorithm": "ES256",
- "is_current": true,
- "activates_at": "2025-12-19T10:40:00Z",
- "created_at": "2025-12-19T10:30:00Z"
}, - {
- "kid": "key-2025-12-01-001",
- "algorithm": "ES256",
- "is_current": false,
- "activates_at": "2025-12-01T09:00:00Z",
- "created_at": "2025-12-01T09:00:00Z"
}
]
}Promote an existing signing key to be the current signing key. The current key is used for signing new tokens.
Behavior:
is_current: trueis_current: false| kid required | string Example: key-2025-12-19-001 Key identifier of the signing key |
{- "kid": "key-2025-12-01-001",
- "algorithm": "ES256",
- "is_current": true,
- "created_at": "2025-12-01T09:00:00Z"
}Remove a signing key from the active key set.
Soft Delete: The key is deactivated but retained for audit purposes. Tokens previously signed with this key can no longer be verified.
Constraints:
409 Conflict)| kid required | string Example: key-2025-12-19-001 Key identifier of the signing key |
{- "error": "not found",
- "message": "Signing key with kid 'key-unknown' does not exist"
}