Who this is for: MCP server implementers, platform security engineers, and compliance teams responsible for OAuth integration in AI tool ecosystems. Assumes familiarity with OAuth 2.0 flows and the Model Context Protocol.

The MCP OAuth crisis: Only 8.5% of MCP servers implement OAuth authentication. Over 30 CVEs were disclosed against MCP implementations in 60 days. The confused deputy problem (OWASP MCP-07) enables one-click account takeover through malicious proxy servers. SWT3 does not fix these vulnerabilities. It witnesses the authentication lifecycle so that when things go wrong, the evidence trail is already there.

Contents

1. The MCP OAuth Crisis 2. Eight Witnessable Events 3. Factor Semantics 4. Confused Deputy Prevention 5. Python Integration 6. TypeScript Integration 7. MCP Server Tool 8. Framework Coverage 9. Scope Governance

1. The MCP OAuth Crisis

The Model Context Protocol enables AI assistants to call external tools. These tools access databases, APIs, file systems, and cloud services on behalf of the user. Authentication is the foundation of this access. When it fails, the consequences cascade.

The current state of MCP authentication:

SWT3 does not prevent these attacks. Prevention is the responsibility of the OAuth implementation itself (audience validation, token binding, DPoP). What SWT3 does is produce an independent witness record of every OAuth lifecycle event, creating forensic evidence that persists regardless of whether the attack is detected in real time.

2. Eight Witnessable Events

The OAuth lifecycle in MCP has eight distinct events. Each event produces an AI-MCP.5 witness anchor with a specific event_type code.

Event Type Code What Is Attested Why It Matters
Discovery oauth_discovery Authorization server metadata URL, issuer, supported flows Proves which authorization server was selected and that discovery was not intercepted
Authorization Request oauth_authz_request Scopes requested, redirect URI, PKCE code challenge Records the exact permissions requested before user consent
Token Issuance oauth_token_issued Token hash (never the token itself), scopes granted, expiry, audience Proves what access was actually granted versus what was requested
Token Refresh oauth_token_refresh New token hash, previous token hash, scopes unchanged/changed Detects scope creep during refresh cycles
Token Use oauth_token_use Resource accessed, scope consumed, audience validated Links each API call to the token that authorized it
Audience Validation oauth_audience_check Expected audience, actual audience, match result The critical confused deputy defense. Proves the token was validated against the intended service.
Scope Reduction oauth_scope_reduce Original scopes, reduced scopes, reason for reduction Evidence of least-privilege enforcement when the server narrows granted scopes
Revocation oauth_revoke Token hash revoked, revocation reason, initiator Proves the token was explicitly invalidated and by whom

Important: SWT3 never records raw tokens, client secrets, or authorization codes. All token references are SHA-256 hashes. The witness layer records metadata about the OAuth lifecycle, not the credentials themselves.

3. Factor Semantics

Procedure Name Factor A Factor B Factor C
AI-MCP.5 OAuth Token Binding Event type code and MCP server identifier Token hash (SHA-256), scopes (comma-separated list), audience Scope count, validation result (pass/fail), expiry epoch

All eight event types use the same procedure (AI-MCP.5) with the event type encoded in Factor A. This keeps the procedure namespace clean while allowing fine-grained event differentiation in the ledger.

The fingerprint is computed as SHA256("WITNESS:{tenant}:{proc}:{fa}:{fb}:{fc}:{ts_ms}").hex()[:12]. This formula is locked across all seven SDK languages and produces identical fingerprints for identical inputs.

4. Confused Deputy Prevention

The confused deputy attack is the most dangerous OAuth vulnerability in MCP. Here is how it works and where witnessing provides evidence.

Attack Flow: Confused Deputy via Malicious MCP Proxy

1
User installs malicious MCP server that advertises useful tools (e.g., "GitHub Assistant")
2
MCP client initiates OAuth flow with the legitimate authorization server (e.g., GitHub)
3
User consents and the token is issued to the MCP client
4
Malicious server receives the token and forwards it to the real GitHub API, acting as the user
W1
AI-MCP.5 (oauth_audience_check) records the audience validation. If the token's audience does not match the MCP server's identity, the mismatch is permanently recorded in the witness ledger.
W2
AI-MCP.5 (oauth_token_use) records every API call made with the token, including the resource accessed and the server that initiated it. Forensic reconstruction shows the malicious server used the token against a service it does not own.

Witnessing does not block the confused deputy attack. Token audience validation (RFC 9068), DPoP (RFC 9449), and sender-constrained tokens are the preventive controls. What witnessing provides is an independent evidence trail that persists after the attack, enabling forensic reconstruction and proving whether audience validation was performed on every token use.

5. Python Integration

from swt3_ai import Witness
import hashlib

witness = Witness(
    endpoint="https://sovereign.tenova.io",
    api_key="axm_live_...",
    tenant_id="ACME_DEFENSE",
    agent_id="mcp-gateway-v2",
)

# Witness OAuth token issuance
token_hash = hashlib.sha256(access_token.encode()).hexdigest()[:16]

witness.witness_oauth_token_binding(
    event_type="oauth_token_issued",
    server_id="github-mcp-server",
    token_hash=token_hash,
    scopes="repo,read:org",
    audience="https://api.github.com",
    scope_count=2,
    expiry_epoch=1774900000,
)

# Witness audience validation on every token use
witness.witness_oauth_token_binding(
    event_type="oauth_audience_check",
    server_id="github-mcp-server",
    token_hash=token_hash,
    expected_audience="https://api.github.com",
    actual_audience="https://api.github.com",
    validation_result="pass",
)

# Witness token revocation
witness.witness_oauth_token_binding(
    event_type="oauth_revoke",
    server_id="github-mcp-server",
    token_hash=token_hash,
    reason="session_end",
    initiator="user",
)

6. TypeScript Integration

import { Witness } from "@tenova/swt3-ai";
import { createHash } from "crypto";

const witness = new Witness({
  endpoint: "https://sovereign.tenova.io",
  apiKey: "axm_live_...",
  tenantId: "ACME_DEFENSE",
  agentId: "mcp-gateway-v2",
});

const tokenHash = createHash("sha256")
  .update(accessToken).digest("hex").slice(0, 16);

// Witness OAuth token issuance
await witness.witnessOAuthTokenBinding({
  eventType: "oauth_token_issued",
  serverId: "github-mcp-server",
  tokenHash,
  scopes: "repo,read:org",
  audience: "https://api.github.com",
  scopeCount: 2,
  expiryEpoch: 1774900000,
});

// Witness audience validation
await witness.witnessOAuthTokenBinding({
  eventType: "oauth_audience_check",
  serverId: "github-mcp-server",
  tokenHash,
  expectedAudience: "https://api.github.com",
  actualAudience: "https://api.github.com",
  validationResult: "pass",
});

// Witness token revocation
await witness.witnessOAuthTokenBinding({
  eventType: "oauth_revoke",
  serverId: "github-mcp-server",
  tokenHash,
  reason: "session_end",
  initiator: "user",
});

7. MCP Server Tool

The SWT3 MCP server exposes witness_oauth_token_binding as a callable tool. Any MCP client can invoke it directly.

// MCP tool call
{
  "tool": "witness_oauth_token_binding",
  "arguments": {
    "event_type": "oauth_audience_check",
    "server_id": "github-mcp-server",
    "token_hash": "a1b2c3d4e5f6...",
    "expected_audience": "https://api.github.com",
    "actual_audience": "https://api.github.com",
    "validation_result": "pass"
  }
}
Parameter Type Description
event_type string (enum) One of the 8 event type codes listed in Section 2
server_id string Identifier of the MCP server involved in the OAuth flow
token_hash string SHA-256 hash of the token (first 16 hex chars). Never the raw token.
scopes string Comma-separated list of OAuth scopes (for issuance/refresh events)
audience string Intended audience URI for audience validation events
validation_result string pass or fail (for audience check events)

8. Framework Coverage

Framework Requirement Event Type Evidence Produced
OWASP MCP-07 Confused Deputy / Third-Party MCP Server Exploitation oauth_audience_check Audience validation result for every token use
NIST IA-9 Service Identification and Authentication oauth_discovery, oauth_token_issued Authorization server discovery and token issuance chain
NIST AC-6 Least Privilege oauth_scope_reduce Scope narrowing evidence with original and reduced scopes
EU AI Act Art. 15(3) Cybersecurity measures for high-risk AI oauth_token_issued, oauth_revoke Token lifecycle from issuance through revocation
Five Eyes FE-3 Authentication and access control for agent tooling oauth_audience_check, oauth_token_use Per-call token validation and resource access attribution
ISO 42001 A.10.5 Data management and access control oauth_scope_reduce, oauth_token_use Scope governance and per-resource access records
NIST AC-2 Account Management oauth_revoke Token lifecycle termination with initiator and reason

9. Scope Governance

OAuth scopes define what an MCP server can do on behalf of the user. Witnessing scope governance produces evidence of least-privilege enforcement that auditors can verify independently.

Scope Attestation Chain

The scope_count field in Factor C provides a numeric measure of privilege breadth. An assessor can query the ledger for anchors where scope_count exceeds a policy threshold, identifying MCP servers with excessive permissions.

Scope Drift Detection

By comparing oauth_token_issued anchors across refresh cycles, scope drift becomes visible. If a token refresh silently adds new scopes (a known attack vector), the anchors will show a scope_count increase that was not preceded by a new authorization request. This pattern is a finding.

AI-MCP.5

OAuth Token Binding

Witnesses the complete OAuth lifecycle for MCP server connections. Eight event types cover discovery through revocation. Each anchor records the event type, server identity, token hash, scope list, audience, and validation result without ever storing raw credentials.

Factors: Factor A = event type code and MCP server identifier. Factor B = token hash, scopes, and audience. Factor C = scope count, validation result, and expiry epoch.

Assessor Tip

Query AI-MCP.5 anchors filtered by oauth_audience_check event type. Every anchor should show validation_result=pass. Any fail result indicates a confused deputy attempt. Cross-reference the server_id with known-good MCP server registrations. Check scope_count trends across refresh cycles for scope creep.

This guide is provided for informational purposes only and does not constitute legal, regulatory, or compliance advice. Regulatory mappings and crosswalk interpretations reflect the publisher's analysis and may not address all obligations applicable to your organization. Consult qualified legal counsel before making compliance decisions based on this content.