Proof Verification
Verify MCP-I cryptographic proofs from AI agents
What Are MCP-I Proofs?
An MCP-I (Model Context Protocol with Identity) proof is a cryptographic assertion that an AI agent attaches to every request. It proves:
- Identity — The agent is who it claims to be (verified via DID)
- Authorization — The agent has a valid delegation for the requested action
- Freshness — The proof was recently created and hasn't been replayed
Proofs are signed with the agent's private key and verified by Checkpoint's infrastructure.
Proof Structure
An MCP-I proof consists of three parts (JWS Compact Serialization):
{
"protected": {
"alg": "EdDSA",
"typ": "JWT"
},
"payload": {
"sub": "did:key:z6Mk...",
"aud": "https://api.example.com",
"iat": 1706745600,
"exp": 1706749200,
"nonce": "random-unique-nonce",
"delegationRef": "del_abc123",
"scopeId": "files:write"
},
"signature": "<ed25519-signature>"
}| Field | Description |
|---|---|
sub | Agent DID (Decentralized Identifier) |
aud | Target API audience |
iat | Issued-at timestamp |
exp | Expiration timestamp |
nonce | Unique value to prevent replay attacks |
delegationRef | Reference to the authorizing delegation |
scopeId | Specific scope being exercised |
Server-Side Verification
Using the Middleware
The recommended approach is @kya-os/bouncer-middleware, which handles proof extraction and verification automatically:
import express from 'express';
import { createBouncerMiddleware } from '@kya-os/bouncer-middleware';
const app = express();
app.use(express.json());
// Protect an endpoint — proofs are verified automatically
app.post(
'/api/files',
createBouncerMiddleware({
apiKey: process.env.CHECKPOINT_API_KEY!,
projectId: process.env.CHECKPOINT_PROJECT_ID!,
requiredScopes: ['files:write'],
reputationThreshold: 60,
}),
(req, res) => {
// Verified agent data is available on req.bouncer
const { agentDid, scopes, reputation, delegation } = req.bouncer;
console.log(`Agent ${agentDid} with reputation ${reputation}`);
console.log(`Granted scopes: ${scopes.join(', ')}`);
res.json({ message: 'File created', agent: agentDid });
}
);The middleware performs these steps:
- Extracts the proof from the
X-MCP-Proofheader - Verifies the Ed25519 cryptographic signature
- Checks the proof hasn't expired
- Validates the referenced delegation with Checkpoint
- Enforces required scopes
- Checks agent reputation against the threshold
- Validates any delegation constraints (IP, origin, time)
- Attaches verified data to
req.bouncer
Verified Request Data
After successful verification, req.bouncer contains:
interface BouncerRequest extends Request {
bouncer: {
/** Verified MCP-I proof payload */
proof: MCPIProofPayload;
/** Agent DID (Decentralized Identifier) */
agentDid: string;
/** Delegation information */
delegation?: Delegation;
/** Agent reputation score 0-100 */
reputation?: number;
/** Granted scopes from delegation */
scopes: string[];
};
}How Agents Send Proofs
AI agents attach proofs via the X-MCP-Proof header:
curl -X POST https://api.example.com/api/files \
-H "Content-Type: application/json" \
-H "X-MCP-Proof: <base64url-encoded-proof>" \
-d '{"filename": "report.txt", "content": "..."}'Error Handling
When proof verification fails, the middleware returns a structured error:
{
"error": {
"code": "INSUFFICIENT_SCOPES",
"message": "Required scopes: files:write. Granted: files:read",
"details": {
"required": ["files:write"],
"granted": ["files:read"]
}
}
}Error Codes
| Code | HTTP Status | Description |
|---|---|---|
MISSING_PROOF | 401 | No X-MCP-Proof header provided |
INVALID_PROOF | 400 | Malformed proof structure |
EXPIRED_PROOF | 401 | Proof has passed its expiration time |
INVALID_SIGNATURE | 401 | Ed25519 signature verification failed |
DELEGATION_NOT_FOUND | 404 | Referenced delegation does not exist |
DELEGATION_EXPIRED | 403 | Delegation has passed its expiration |
DELEGATION_REVOKED | 403 | Delegation was explicitly revoked |
INSUFFICIENT_SCOPES | 403 | Agent lacks required scopes |
REPUTATION_TOO_LOW | 403 | Agent reputation below threshold |
CONSTRAINT_VIOLATION | 403 | Delegation constraint not satisfied |
All proof verification errors are logged to the Checkpoint dashboard under Project → Proofs for audit purposes.
Proof Lifecycle
1. Agent requests delegation (via OAuth or API)
2. Agent creates proof for a specific request
3. Proof is sent with the request (X-MCP-Proof header)
4. Middleware extracts and sends proof to Checkpoint
5. Checkpoint verifies signature, delegation, scopes, constraints
6. Result is returned to middleware
7. Request proceeds or is rejected
8. Verification event logged to dashboardProof Expiration
Proofs have a short TTL (typically 5 minutes) to prevent replay attacks. The iat and exp timestamps in the proof payload define the validity window. Each proof should include a unique nonce.
Monitoring Proofs
View proof verification activity in the Checkpoint dashboard:
- Navigate to Project → Proofs
- See recent verification attempts (success and failure)
- Filter by agent DID, error code, or time range
- Drill into individual verification events for debugging
Next Steps
- Managing Delegations — Create the authorization grants that proofs reference
- OAuth Integration — Automated delegation creation
- Tool Protection — Map proofs to specific tool permissions