Tutorial: Verify a Bundle
This tutorial builds on Issue Your First Delegation. You will wrap the delegation chain in a bundle, send it to drs-verify, and confirm it passes all six verification blocks.
Prerequisites
- Go 1.22+ with
drs-verifysource - The
rootDRandsubDRJWTs from Tutorial 1 @drs/sdkinstalled
Step 1: Start drs-verify
cd drs-verify
go run ./cmd/server
# drs-verify listening on :8080
Step 2: Issue an invocation receipt
import { issueInvocation, computeChainHash, buildBundle, serialiseBundle } from '@drs/sdk';
import { writeFileSync } from 'fs';
const agentKey = Uint8Array.from(Buffer.from('SUBAGENT_PRIVATE_KEY', 'base64url'));
const invocation = await issueInvocation({
signingKey: agentKey,
issuerDid: 'did:key:z6MkSUBAGENT...',
subjectDid: 'did:key:z6MkHUMAN...',
cmd: '/mcp/tools/call',
args: {
tool: 'web_search',
query: 'Monad TPS benchmarks',
estimated_cost_usd: 0.02,
},
drChain: [
computeChainHash(rootDR),
computeChainHash(subDR),
],
toolServer: 'did:key:z6MkTOOLSERVER...',
});
// Build and serialise the bundle
const bundle = buildBundle({
invocation,
receipts: [rootDR, subDR],
});
writeFileSync('bundle.json', serialiseBundle(bundle));
console.log('Bundle written to bundle.json');
Step 3: Verify via CLI
DRS_VERIFY_URL=http://localhost:8080 pnpm exec drs verify bundle.json
Expected output:
✓ Bundle verified
Chain depth: 2
Root principal: did:key:z6MkHUMAN...
Subject: did:key:z6MkHUMAN...
Command: /mcp/tools/call
Policy result: pass
Blocks: A✓ B✓ C✓ D✓ E✓ F✓
Step 4: Verify via HTTP API directly
curl -s -X POST http://localhost:8080/verify \
-H "Content-Type: application/json" \
-d @bundle.json | jq .
{
"valid": true,
"chain_depth": 2,
"root_principal": "did:key:z6MkHUMAN...",
"subject": "did:key:z6MkHUMAN...",
"command": "/mcp/tools/call",
"policy_result": "pass"
}
Step 5: Test a rejection
Tamper with the bundle — modify one character in rootDR:
# Create a tampered bundle
cat bundle.json | sed 's/"receipts":\["eyJ/\"receipts\":[\"fakeXXX/' > tampered.json
DRS_VERIFY_URL=http://localhost:8080 pnpm exec drs verify tampered.json
Expected:
✗ Verification failed
Block: B (structural integrity)
Error: CHAIN_HASH_MISMATCH — prev_dr_hash mismatch at chain index 1
Step 6: Print the full audit trail
pnpm exec drs audit bundle.json
This prints a human-readable breakdown of every receipt in the chain: issuers, audiences, policies, temporal bounds, and consent records.
Next steps
- End-to-End Trace — watch the full lifecycle including tool server execution
- MCP Middleware Integration — integrate this verification flow into a real MCP server