Skip to main content

MCP Authorization Server

The MCP Authorization Server positions Mandaitor at the enforcement boundary where AI agents actually execute actions. When an agent attempts to use a tool via the Model Context Protocol (MCP), the authorization server verifies the agent's mandate before granting access, ensuring that every tool call is explicitly authorized.

How It Works

The MCP Authorization Server implements the OAuth 2.0 client_credentials grant with private_key_jwt authentication. An agent authenticates using its DID and key material from the Agent Identity Registry, receives a scoped access token, and then presents that token when requesting tool call authorization.

Server Metadata Discovery

The server publishes its metadata at the standard OAuth well-known endpoint:

GET /.well-known/oauth-authorization-server

This returns the token endpoint, supported grant types, authentication methods, and MCP-specific metadata such as supported tool namespaces and enforcement mode.

Token Exchange

Agents authenticate using their DID as the client_id and a signed JWT as the client_assertion:

const tokenResponse = await fetch("https://api.mandaitor.io/v1/mcp/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "client_credentials",
client_id: "did:mandaitor:tnt_abc:agt_01HXYZ",
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_assertion: signedJwt,
scope: "mandate:mdt_abc123",
}),
});

The response includes an access token scoped to the agent's bound mandates.

Tool Call Authorization

With a valid access token, the agent requests authorization for specific tool calls:

const authzResponse = await fetch("https://api.mandaitor.io/v1/mcp/authorize", {
method: "POST",
headers: {
"Authorization": `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
tool_name: "database_query",
parameters: {
query: "SELECT * FROM projects WHERE status = 'active'",
},
}),
});

The authorization server evaluates the tool call against all mandates in the session scope. If authorized, the response includes a lightweight Proof-of-Mandate token that the tool server can verify. The response also carries the mcp-runtime-trace/v2 evidence material used by the Runtime Assurance Loop.

Runtime Trace and Assurance Binding

Every authorization response is normalized as a runtime trace so downstream systems can prove that the tool call was bound to an active mandate, a Proof-of-Mandate artifact, and a Verifiable Intent L3 transaction trace. The authorization decision remains mandate-driven; runtime-assurance fields add observability and evidence, not a second enforcement path.

FieldMeaning
event_idStable authorization event identifier used by audit, Ops ingestion, and dashboard drill-down.
agent_id / agent_didAuthenticated autonomous actor that requested the tool call.
mandate_idActive mandate that authorized the mapped action and resource.
mapped_action / mapped_resourcePolicy-derived mandate scope evaluated for the tool call.
pom_boundIndicates that a Proof-of-Mandate artifact was issued or bound to the authorization decision.
vi_layer_typeRuntime transaction trace layer; Sprint 4 emits L3 material for tool authorization events.
verification_event_idEvent reference used to correlate the MCP authorization with verification and evidence pipelines.
drift_score / drift_detected / drift_thresholdAdvisory drift posture calculated over the active session window.
drift_dimensionsNormalized advisory component scores for semantic distance, sequence deviation, frequency anomaly, and scope expansion.
drift_session_id / drift_window_start / drift_window_end / drift_session_action_countSliding drift-window binding that proves which session state was used for the advisory score.
semantic_signalsStructured semantic signal payload returned for audit and Ops evidence ingestion when drift scoring succeeds.
vi_l3_claimsTransaction-level Verifiable Intent material, including claim type, mandate, verification event, decision, and L2 binding.

A typical successful response contains both the authorization decision and trace material:

{
"decision": "ALLOW",
"event_id": "evt_runtime_authorization_fixture",
"mandate_id": "mdt_runtime_fixture",
"pom_token": "eyJ...",
"runtime_trace": {
"contract_version": "mcp-runtime-trace/v2",
"agent_id": "agt_runtime_fixture",
"agent_did": "did:web:api.mandaitor.io:agents:agt_runtime_fixture",
"mapped_action": "authorization.execute",
"mapped_resource": "runtime:evidence/*",
"pom_bound": true,
"vi_layer_type": "L3A",
"verification_event_id": "evt_runtime_authorization_fixture",
"drift_score": 0.12,
"drift_detected": false,
"drift_threshold": 0.7,
"drift_dimensions": {
"semantic_distance": 0.08,
"sequence_deviation": 0.1,
"frequency_anomaly": 0.12,
"scope_expansion": 0.18
},
"drift_session_id": "TENANT#tnt_runtime_fixture#MDT#mdt_runtime_fixture",
"drift_window_start": "2026-05-08T15:00:00.000Z",
"drift_window_end": "2026-05-08T16:00:00.000Z",
"drift_session_action_count": 1,
"semantic_signals": {
"drift_score": {
"aggregate": 0.12,
"drift_detected": false
}
},
"vi_l3_claims": {
"vct": "urn:mandaitor:vi:l3",
"mandate_id": "mdt_runtime_fixture",
"verification_event_id": "evt_runtime_authorization_fixture",
"decision": "ALLOW",
"l2_binding": "mandate:mdt_runtime_fixture:session:sess_runtime_fixture"
}
}
}

Drift collection is fail-open at the runtime boundary. If a drift session cannot be read or scored, Mandaitor still returns the mandate authorization decision and marks the trace as missing advisory drift material. Ops publication is deliberately stricter: generated trust data is fail-closed when required runtime-trace fields are incomplete, malformed, inconsistent with the event ID or mandate ID, or outside the expected normalized score range.

Authorization Policy

The default policy maps tool calls to mandate actions using pattern matching. Tenants can configure custom policies to define granular mappings between MCP tool names and mandate scope:

FieldDescription
tool_patternGlob pattern matching tool names (e.g., database_*)
mandate_actionRequired mandate action (e.g., data.read)
mandate_resourceRequired mandate resource pattern
default_decisionDecision when no mapping matches (default: DENY)
drift_escalation_thresholdDrift score above which to escalate (default: 0.7)

Session Management

Each token exchange creates a session that tracks tool call history. Sessions can be inspected via:

GET /mcp/sessions/{id}

This returns the session metadata including the agent, bound mandates, tool call count, and creation timestamp.

info

The MCP Authorization Server is currently in Beta. The core token exchange and authorization flow is stable, while policy configuration and advisory drift scoring may evolve. Runtime-trace evidence follows mcp-runtime-trace/v2 and is documented in the Runtime Assurance Loop.