Skip to main content

Authorize API

POST /v1/authorize​

Asks the PDP: can this caller call this target, with this data class, at this hop? Presents the current hop token as the bearer.

Request body (AuthorizeRequest):

{
"session_id": "...",
"caller": "user:alice",
"target": "mcp://kb.internal/search",
"data_class": "kb.public",
"taint": "trusted_internal",
"enforced": true
}

Note what's absent: no hop_count field. Hop depth is always derived from the presented token's verified act chain, never accepted as a caller-supplied number — see Why authority narrows at every hop.

taint is recorded on the decision but does not (yet) affect the outcome — see The taint and provenance model for the design that will enforce it. enforced is reported by the caller (the enforcement point): whether it will act on a deny or is running in observe mode; it never affects the decision itself.

Response — 200 (AuthorizeDecision), always, whether allow or deny:

{
"outcome": "allow",
"hop": 1,
"policy_version": 1,
"session_id": "...",
"action_id": "...",
"acting_agent": "user:alice",
"recorded": true
}

On deny, reason is one of:

ReasonRecoverableCategory
SCOPE_NOT_CONSENTEDYesPolicy
OUT_OF_SCOPENoPolicy
HOP_BUDGET_EXCEEDEDNoPolicy
EDGE_NOT_IN_DAGNoPolicy
PDP_UNAVAILABLENoInfrastructure
TOKEN_SERVICE_UNAVAILABLENoInfrastructure
AUDIT_UNAVAILABLENoInfrastructure (returned, never itself stored)

recoverable is a property of the reason, not a per-call judgment — the PDP, the sidecar, and the SDK never disagree about it. Only SCOPE_NOT_CONSENTED is a step-up-consent candidate (designed, Phase 5).