@dupecom/botcha-cloudflare 0.15.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard/landing.d.ts.map +1 -1
- package/dist/dashboard/landing.js +2 -9
- package/dist/dashboard/layout.d.ts +12 -0
- package/dist/dashboard/layout.d.ts.map +1 -1
- package/dist/dashboard/layout.js +12 -5
- package/dist/dashboard/showcase.d.ts +1 -0
- package/dist/dashboard/showcase.d.ts.map +1 -1
- package/dist/dashboard/showcase.js +3 -2
- package/dist/dashboard/whitepaper.d.ts +14 -0
- package/dist/dashboard/whitepaper.d.ts.map +1 -0
- package/dist/dashboard/whitepaper.js +418 -0
- package/dist/email.d.ts.map +1 -1
- package/dist/email.js +5 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +148 -18
- package/dist/og-image.d.ts +2 -0
- package/dist/og-image.d.ts.map +1 -0
- package/dist/og-image.js +2 -0
- package/dist/static.d.ts +871 -2
- package/dist/static.d.ts.map +1 -1
- package/dist/static.js +812 -4
- package/dist/tap-agents.d.ts +3 -2
- package/dist/tap-agents.d.ts.map +1 -1
- package/dist/tap-agents.js +19 -6
- package/dist/tap-attestation-routes.d.ts +204 -0
- package/dist/tap-attestation-routes.d.ts.map +1 -0
- package/dist/tap-attestation-routes.js +396 -0
- package/dist/tap-attestation.d.ts +178 -0
- package/dist/tap-attestation.d.ts.map +1 -0
- package/dist/tap-attestation.js +416 -0
- package/dist/tap-consumer.d.ts +151 -0
- package/dist/tap-consumer.d.ts.map +1 -0
- package/dist/tap-consumer.js +346 -0
- package/dist/tap-delegation-routes.d.ts +236 -0
- package/dist/tap-delegation-routes.d.ts.map +1 -0
- package/dist/tap-delegation-routes.js +378 -0
- package/dist/tap-delegation.d.ts +127 -0
- package/dist/tap-delegation.d.ts.map +1 -0
- package/dist/tap-delegation.js +490 -0
- package/dist/tap-edge.d.ts +106 -0
- package/dist/tap-edge.d.ts.map +1 -0
- package/dist/tap-edge.js +487 -0
- package/dist/tap-federation.d.ts +89 -0
- package/dist/tap-federation.d.ts.map +1 -0
- package/dist/tap-federation.js +237 -0
- package/dist/tap-jwks.d.ts +64 -0
- package/dist/tap-jwks.d.ts.map +1 -0
- package/dist/tap-jwks.js +279 -0
- package/dist/tap-payment.d.ts +172 -0
- package/dist/tap-payment.d.ts.map +1 -0
- package/dist/tap-payment.js +425 -0
- package/dist/tap-reputation-routes.d.ts +154 -0
- package/dist/tap-reputation-routes.d.ts.map +1 -0
- package/dist/tap-reputation-routes.js +341 -0
- package/dist/tap-reputation.d.ts +136 -0
- package/dist/tap-reputation.d.ts.map +1 -0
- package/dist/tap-reputation.js +346 -0
- package/dist/tap-routes.d.ts +239 -2
- package/dist/tap-routes.d.ts.map +1 -1
- package/dist/tap-routes.js +279 -4
- package/dist/tap-verify.d.ts +43 -1
- package/dist/tap-verify.d.ts.map +1 -1
- package/dist/tap-verify.js +215 -30
- package/package.json +1 -1
package/dist/static.js
CHANGED
|
@@ -87,6 +87,59 @@ curl https://botcha.ai/agent-only -H "Authorization: Bearer <token>"
|
|
|
87
87
|
| \`POST\` | \`/v1/sessions/tap\` | Create TAP session with intent validation |
|
|
88
88
|
| \`GET\` | \`/v1/sessions/:id/tap\` | Get TAP session info |
|
|
89
89
|
|
|
90
|
+
### TAP Full Spec — JWKS & Keys (v0.16.0)
|
|
91
|
+
|
|
92
|
+
| Method | Path | Description |
|
|
93
|
+
|--------|------|-------------|
|
|
94
|
+
| \`GET\` | \`/.well-known/jwks\` | JWK Set for app's TAP agents (Visa spec standard) |
|
|
95
|
+
| \`GET\` | \`/v1/keys\` | List keys (supports ?keyID= for Visa compat) |
|
|
96
|
+
| \`GET\` | \`/v1/keys/:keyId\` | Get specific key by ID |
|
|
97
|
+
| \`POST\` | \`/v1/agents/:id/tap/rotate-key\` | Rotate agent's key pair |
|
|
98
|
+
|
|
99
|
+
### TAP Full Spec — 402 Micropayments (v0.16.0)
|
|
100
|
+
|
|
101
|
+
| Method | Path | Description |
|
|
102
|
+
|--------|------|-------------|
|
|
103
|
+
| \`POST\` | \`/v1/invoices\` | Create invoice for gated content |
|
|
104
|
+
| \`GET\` | \`/v1/invoices/:id\` | Get invoice details |
|
|
105
|
+
| \`POST\` | \`/v1/invoices/:id/verify-iou\` | Verify Browsing IOU |
|
|
106
|
+
|
|
107
|
+
### TAP Full Spec — Verification (v0.16.0)
|
|
108
|
+
|
|
109
|
+
| Method | Path | Description |
|
|
110
|
+
|--------|------|-------------|
|
|
111
|
+
| \`POST\` | \`/v1/verify/consumer\` | Verify Agentic Consumer (Layer 2) |
|
|
112
|
+
| \`POST\` | \`/v1/verify/payment\` | Verify Agentic Payment Container (Layer 3) |
|
|
113
|
+
| \`POST\` | \`/v1/verify/delegation\` | Verify delegation chain validity |
|
|
114
|
+
| \`POST\` | \`/v1/verify/attestation\` | Verify attestation token + check capability |
|
|
115
|
+
|
|
116
|
+
### Delegation Chains
|
|
117
|
+
|
|
118
|
+
| Method | Path | Description |
|
|
119
|
+
|--------|------|-------------|
|
|
120
|
+
| \`POST\` | \`/v1/delegations\` | Create delegation (grantor→grantee) |
|
|
121
|
+
| \`GET\` | \`/v1/delegations/:id\` | Get delegation details |
|
|
122
|
+
| \`GET\` | \`/v1/delegations\` | List delegations for agent |
|
|
123
|
+
| \`POST\` | \`/v1/delegations/:id/revoke\` | Revoke delegation (cascades) |
|
|
124
|
+
|
|
125
|
+
### Capability Attestation
|
|
126
|
+
|
|
127
|
+
| Method | Path | Description |
|
|
128
|
+
|--------|------|-------------|
|
|
129
|
+
| \`POST\` | \`/v1/attestations\` | Issue attestation token (can/cannot rules) |
|
|
130
|
+
| \`GET\` | \`/v1/attestations/:id\` | Get attestation details |
|
|
131
|
+
| \`GET\` | \`/v1/attestations\` | List attestations for agent |
|
|
132
|
+
| \`POST\` | \`/v1/attestations/:id/revoke\` | Revoke attestation |
|
|
133
|
+
|
|
134
|
+
### Agent Reputation Scoring
|
|
135
|
+
|
|
136
|
+
| Method | Path | Description |
|
|
137
|
+
|--------|------|-------------|
|
|
138
|
+
| \`GET\` | \`/v1/reputation/:agent_id\` | Get agent reputation score |
|
|
139
|
+
| \`POST\` | \`/v1/reputation/events\` | Record a reputation event |
|
|
140
|
+
| \`GET\` | \`/v1/reputation/:agent_id/events\` | List reputation events |
|
|
141
|
+
| \`POST\` | \`/v1/reputation/:agent_id/reset\` | Reset reputation (admin) |
|
|
142
|
+
|
|
90
143
|
### Challenges
|
|
91
144
|
|
|
92
145
|
| Method | Path | Description |
|
|
@@ -262,8 +315,10 @@ API-Format: OpenAPI 3.1.0
|
|
|
262
315
|
|
|
263
316
|
# Documentation
|
|
264
317
|
Docs: https://botcha.ai
|
|
318
|
+
Docs: https://botcha.ai/whitepaper
|
|
265
319
|
Docs: https://github.com/dupe-com/botcha#readme
|
|
266
320
|
Docs: https://www.npmjs.com/package/@dupecom/botcha
|
|
321
|
+
Whitepaper: https://botcha.ai/whitepaper
|
|
267
322
|
|
|
268
323
|
# Verification Methods
|
|
269
324
|
Feature: Web Bot Auth (cryptographic signatures)
|
|
@@ -287,6 +342,7 @@ Feature: Trusted Agent Protocol (TAP) — cryptographic agent auth with HTTP Mes
|
|
|
287
342
|
Feature: TAP Capabilities (action + resource scoping for agent sessions)
|
|
288
343
|
Feature: TAP Trust Levels (basic, verified, enterprise)
|
|
289
344
|
Feature: TAP Showcase Homepage (botcha.ai — one of the first services to implement Visa's Trusted Agent Protocol)
|
|
345
|
+
Feature: TAP Full Spec v0.16.0 — Ed25519, RFC 9421 full compliance, JWKS infrastructure, Layer 2 Consumer Recognition, Layer 3 Payment Container, 402 micropayments, CDN edge verification, Visa key federation
|
|
290
346
|
|
|
291
347
|
# Endpoints
|
|
292
348
|
# Challenge Endpoints
|
|
@@ -341,6 +397,41 @@ Endpoint: GET https://botcha.ai/v1/agents/tap - List TAP-enabled agents for app
|
|
|
341
397
|
Endpoint: POST https://botcha.ai/v1/sessions/tap - Create TAP session with intent validation
|
|
342
398
|
Endpoint: GET https://botcha.ai/v1/sessions/:id/tap - Get TAP session info
|
|
343
399
|
|
|
400
|
+
# TAP Full Spec — JWKS & Key Management (v0.16.0)
|
|
401
|
+
Endpoint: GET https://botcha.ai/.well-known/jwks - JWK Set for app's TAP agents (Visa spec standard)
|
|
402
|
+
Endpoint: GET https://botcha.ai/v1/keys - List keys (supports ?keyID= query for Visa compatibility)
|
|
403
|
+
Endpoint: GET https://botcha.ai/v1/keys/:keyId - Get specific key by ID
|
|
404
|
+
Endpoint: POST https://botcha.ai/v1/agents/:id/tap/rotate-key - Rotate agent's key pair
|
|
405
|
+
|
|
406
|
+
# TAP Full Spec — 402 Micropayments (v0.16.0)
|
|
407
|
+
Endpoint: POST https://botcha.ai/v1/invoices - Create invoice for gated content (402 flow)
|
|
408
|
+
Endpoint: GET https://botcha.ai/v1/invoices/:id - Get invoice details
|
|
409
|
+
Endpoint: POST https://botcha.ai/v1/invoices/:id/verify-iou - Verify Browsing IOU against invoice
|
|
410
|
+
|
|
411
|
+
# TAP Full Spec — Consumer & Payment Verification (v0.16.0)
|
|
412
|
+
Endpoint: POST https://botcha.ai/v1/verify/consumer - Verify Agentic Consumer object (Layer 2)
|
|
413
|
+
Endpoint: POST https://botcha.ai/v1/verify/payment - Verify Agentic Payment Container (Layer 3)
|
|
414
|
+
|
|
415
|
+
# TAP Delegation Chains (v0.17.0)
|
|
416
|
+
Endpoint: POST https://botcha.ai/v1/delegations - Create delegation (grantor→grantee with capability subset)
|
|
417
|
+
Endpoint: GET https://botcha.ai/v1/delegations/:id - Get delegation details
|
|
418
|
+
Endpoint: GET https://botcha.ai/v1/delegations - List delegations for agent (?agent_id=&direction=in|out|both)
|
|
419
|
+
Endpoint: POST https://botcha.ai/v1/delegations/:id/revoke - Revoke delegation (cascades to sub-delegations)
|
|
420
|
+
Endpoint: POST https://botcha.ai/v1/verify/delegation - Verify entire delegation chain
|
|
421
|
+
|
|
422
|
+
# TAP Capability Attestation (v0.17.0)
|
|
423
|
+
Endpoint: POST https://botcha.ai/v1/attestations - Issue capability attestation token (can/cannot rules with action:resource patterns)
|
|
424
|
+
Endpoint: GET https://botcha.ai/v1/attestations/:id - Get attestation details
|
|
425
|
+
Endpoint: GET https://botcha.ai/v1/attestations - List attestations for agent (?agent_id=)
|
|
426
|
+
Endpoint: POST https://botcha.ai/v1/attestations/:id/revoke - Revoke attestation (token rejected on future verification)
|
|
427
|
+
Endpoint: POST https://botcha.ai/v1/verify/attestation - Verify attestation token + optionally check specific capability
|
|
428
|
+
|
|
429
|
+
# Agent Reputation Scoring (v0.18.0)
|
|
430
|
+
Endpoint: GET https://botcha.ai/v1/reputation/:agent_id - Get agent reputation score (0-1000, 5 tiers)
|
|
431
|
+
Endpoint: POST https://botcha.ai/v1/reputation/events - Record a reputation event (18 action types, 6 categories)
|
|
432
|
+
Endpoint: GET https://botcha.ai/v1/reputation/:agent_id/events - List reputation events (?category=&limit=)
|
|
433
|
+
Endpoint: POST https://botcha.ai/v1/reputation/:agent_id/reset - Reset reputation to default (admin action)
|
|
434
|
+
|
|
344
435
|
# Legacy Endpoints
|
|
345
436
|
Endpoint: GET https://botcha.ai/api/challenge - Generate standard challenge
|
|
346
437
|
Endpoint: POST https://botcha.ai/api/challenge - Verify standard challenge
|
|
@@ -411,7 +502,7 @@ Multi-Tenant-Token-Claim: Tokens include app_id claim when app_id provided
|
|
|
411
502
|
# TRUSTED AGENT PROTOCOL (TAP)
|
|
412
503
|
TAP-Description: Enterprise-grade cryptographic agent auth using HTTP Message Signatures (RFC 9421)
|
|
413
504
|
TAP-Register: POST /v1/agents/register/tap with {name, public_key, signature_algorithm, capabilities, trust_level}
|
|
414
|
-
TAP-Algorithms: ecdsa-p256-sha256, rsa-pss-sha256
|
|
505
|
+
TAP-Algorithms: ed25519 (Visa recommended), ecdsa-p256-sha256, rsa-pss-sha256
|
|
415
506
|
TAP-Trust-Levels: basic, verified, enterprise
|
|
416
507
|
TAP-Capabilities: Array of {action, resource, constraints} — scoped access control
|
|
417
508
|
TAP-Session-Create: POST /v1/sessions/tap with {agent_id, user_context, intent}
|
|
@@ -419,10 +510,26 @@ TAP-Session-Get: GET /v1/sessions/:id/tap — includes time_remaining
|
|
|
419
510
|
TAP-Get-Agent: GET /v1/agents/:id/tap — includes public_key for verification
|
|
420
511
|
TAP-List-Agents: GET /v1/agents/tap?app_id=...&tap_only=true
|
|
421
512
|
TAP-Middleware-Modes: tap, signature-only, challenge-only, flexible
|
|
422
|
-
TAP-SDK-TS: registerTAPAgent(options), getTAPAgent(agentId), listTAPAgents(tapOnly?), createTAPSession(options), getTAPSession(sessionId)
|
|
423
|
-
TAP-SDK-Python: register_tap_agent(name, ...), get_tap_agent(agent_id), list_tap_agents(tap_only?), create_tap_session(agent_id, user_context, intent), get_tap_session(session_id)
|
|
513
|
+
TAP-SDK-TS: registerTAPAgent(options), getTAPAgent(agentId), listTAPAgents(tapOnly?), createTAPSession(options), getTAPSession(sessionId), getJWKS(), getKeyById(keyId), rotateAgentKey(agentId), createInvoice(data), getInvoice(id), verifyBrowsingIOU(invoiceId, token), createDelegation(options), getDelegation(id), listDelegations(agentId, options?), revokeDelegation(id, reason?), verifyDelegationChain(id), issueAttestation(options), getAttestation(id), listAttestations(agentId), revokeAttestation(id, reason?), verifyAttestation(token, action?, resource?), getReputation(agentId), recordReputationEvent(options), listReputationEvents(agentId, options?), resetReputation(agentId)
|
|
514
|
+
TAP-SDK-Python: register_tap_agent(name, ...), get_tap_agent(agent_id), list_tap_agents(tap_only?), create_tap_session(agent_id, user_context, intent), get_tap_session(session_id), get_jwks(), get_key_by_id(key_id), rotate_agent_key(agent_id), create_invoice(data), get_invoice(id), verify_browsing_iou(invoice_id, token), create_delegation(grantor_id, grantee_id, capabilities, ...), get_delegation(id), list_delegations(agent_id, ...), revoke_delegation(id, reason?), verify_delegation_chain(id), issue_attestation(agent_id, can, cannot?, ...), get_attestation(id), list_attestations(agent_id), revoke_attestation(id, reason?), verify_attestation(token, action?, resource?), get_reputation(agent_id), record_reputation_event(agent_id, category, action, ...), list_reputation_events(agent_id, category?, limit?), reset_reputation(agent_id)
|
|
424
515
|
TAP-Middleware-Import: import { createTAPVerifyMiddleware } from '@dupecom/botcha/middleware'
|
|
425
516
|
|
|
517
|
+
# TAP FULL SPEC v0.16.0
|
|
518
|
+
TAP-RFC-9421: Full compliance — @authority, @path, expires, nonce, tag params
|
|
519
|
+
TAP-Nonce-Replay: 8-minute TTL nonce-based replay protection
|
|
520
|
+
TAP-Tags: agent-browser-auth (browsing), agent-payer-auth (payment)
|
|
521
|
+
TAP-Layer-2: Agentic Consumer Recognition — OIDC ID tokens, obfuscated identity, contextual data
|
|
522
|
+
TAP-Layer-3: Agentic Payment Container — card metadata, credential hash, encrypted payload, Browsing IOU
|
|
523
|
+
TAP-JWKS: GET /.well-known/jwks — JWK Set endpoint for key discovery
|
|
524
|
+
TAP-Key-Rotation: POST /v1/agents/:id/tap/rotate-key — rotate keys, invalidate old
|
|
525
|
+
TAP-402-Flow: POST /v1/invoices → GET /v1/invoices/:id → POST /v1/invoices/:id/verify-iou
|
|
526
|
+
TAP-Edge-Verify: createTAPEdgeMiddleware for Cloudflare Workers CDN edge verification
|
|
527
|
+
TAP-Visa-Federation: Trust keys from https://mcp.visa.com/.well-known/jwks (3-tier cache: memory → KV → HTTP)
|
|
528
|
+
TAP-Delegation: POST /v1/delegations → GET /v1/delegations/:id → POST /v1/delegations/:id/revoke → POST /v1/verify/delegation
|
|
529
|
+
TAP-Attestation: POST /v1/attestations → GET /v1/attestations/:id → POST /v1/attestations/:id/revoke → POST /v1/verify/attestation
|
|
530
|
+
TAP-Attestation-Patterns: action:resource format with wildcards (*:*, read:*, *:invoices), deny takes precedence over allow
|
|
531
|
+
TAP-Attestation-Middleware: requireCapability('read:invoices') — Hono middleware, extracts token from X-Botcha-Attestation or Authorization: Bearer
|
|
532
|
+
|
|
426
533
|
# EMBEDDED CHALLENGE (for bots visiting HTML pages)
|
|
427
534
|
Embedded-Challenge: <script type="application/botcha+json">
|
|
428
535
|
Embedded-Challenge-Location: In <head> of HTML pages
|
|
@@ -481,8 +588,160 @@ export const SITEMAP_XML = `<?xml version="1.0" encoding="UTF-8"?>
|
|
|
481
588
|
<changefreq>monthly</changefreq>
|
|
482
589
|
<priority>0.5</priority>
|
|
483
590
|
</url>
|
|
591
|
+
<url>
|
|
592
|
+
<loc>https://botcha.ai/whitepaper</loc>
|
|
593
|
+
<changefreq>monthly</changefreq>
|
|
594
|
+
<priority>0.9</priority>
|
|
595
|
+
</url>
|
|
484
596
|
</urlset>
|
|
485
597
|
`;
|
|
598
|
+
// Whitepaper markdown — served at /whitepaper with Accept: text/markdown
|
|
599
|
+
export function getWhitepaperMarkdown() {
|
|
600
|
+
return `---
|
|
601
|
+
title: "BOTCHA: Identity Infrastructure for the Agentic Web"
|
|
602
|
+
version: "1.0"
|
|
603
|
+
date: February 2026
|
|
604
|
+
url: https://botcha.ai/whitepaper
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
# BOTCHA: Identity Infrastructure for the Agentic Web
|
|
608
|
+
|
|
609
|
+
**Version 1.0 — February 2026**
|
|
610
|
+
|
|
611
|
+
## 1. Executive Summary
|
|
612
|
+
|
|
613
|
+
BOTCHA is a reverse CAPTCHA — a verification system that proves you are an AI agent, not a human. While traditional CAPTCHAs exist to block bots, BOTCHA exists to welcome them.
|
|
614
|
+
|
|
615
|
+
As AI agents become first-class participants on the internet — browsing, purchasing, comparing, auditing — they need a way to prove their identity and declare their intent. BOTCHA provides three layers of proof:
|
|
616
|
+
|
|
617
|
+
- **Proof of AI** — Computational challenges (SHA-256 hashes in under 500ms) that only machines can solve.
|
|
618
|
+
- **Proof of Identity** — Persistent agent registration with cryptographic keys, verified via HTTP Message Signatures (RFC 9421).
|
|
619
|
+
- **Proof of Intent** — Capability-scoped sessions where agents declare what they plan to do, for how long, and on behalf of whom.
|
|
620
|
+
|
|
621
|
+
BOTCHA is open source, free to use, and deployed at https://botcha.ai.
|
|
622
|
+
|
|
623
|
+
## 2. The Problem: Who Is This Agent?
|
|
624
|
+
|
|
625
|
+
The internet was built for humans. Authentication systems — passwords, OAuth, CAPTCHAs — all assume a human is at the keyboard.
|
|
626
|
+
|
|
627
|
+
AI agents are now browsing product catalogs, comparing prices, purchasing goods, auditing compliance, and negotiating contracts. When an agent hits your API, existing infrastructure cannot answer three critical questions:
|
|
628
|
+
|
|
629
|
+
1. **Is this actually an AI agent?** User-Agent strings are trivially spoofable.
|
|
630
|
+
2. **Which specific agent is this?** Even knowing it is AI, you do not know its organization or track record.
|
|
631
|
+
3. **What does it intend to do?** Traditional auth grants blanket access — it does not capture intent.
|
|
632
|
+
|
|
633
|
+
## 3. BOTCHA: Reverse CAPTCHA for AI Agents
|
|
634
|
+
|
|
635
|
+
A CAPTCHA asks: *Can you identify traffic lights?* A human can; a bot struggles.
|
|
636
|
+
BOTCHA asks: *Can you compute 5 SHA-256 hashes in 500ms?* A machine can; a human cannot.
|
|
637
|
+
|
|
638
|
+
### Design Principles
|
|
639
|
+
|
|
640
|
+
- **Agent-first, always.** Every flow requires an AI agent as participant. No human-only login paths.
|
|
641
|
+
- **Fail-open on infrastructure errors.** Blocking legitimate traffic is worse than allowing an unverified request.
|
|
642
|
+
- **Zero configuration to start.** Solve one challenge, get a token. No registration required.
|
|
643
|
+
|
|
644
|
+
## 4. The Challenge System
|
|
645
|
+
|
|
646
|
+
| Challenge | Tests | Time Limit | Best For |
|
|
647
|
+
|-----------|-------|------------|----------|
|
|
648
|
+
| Speed | SHA-256 computation | 500ms | Quick verification |
|
|
649
|
+
| Reasoning | Language understanding (6 categories, parameterized generators) | 30s | Proving AI comprehension |
|
|
650
|
+
| Hybrid | Speed + Reasoning combined | 35s | Default — strongest proof |
|
|
651
|
+
| Compute | Prime generation + hashing | 3-10s | High-value operations |
|
|
652
|
+
|
|
653
|
+
**RTT-aware fairness:** Time limits adjust for network latency (max 5s cap).
|
|
654
|
+
**Anti-replay:** Challenges deleted from storage on first verification attempt.
|
|
655
|
+
**Anti-gaming:** Parameterized question generators; no static question bank.
|
|
656
|
+
|
|
657
|
+
## 5. The Trusted Agent Protocol (TAP)
|
|
658
|
+
|
|
659
|
+
Solving a challenge proves you are *a bot*. TAP proves you are *a specific, trusted bot*.
|
|
660
|
+
|
|
661
|
+
Inspired by Visa's Trusted Agent Protocol (https://developer.visa.com/capabilities/trusted-agent-protocol/overview), BOTCHA's TAP provides:
|
|
662
|
+
|
|
663
|
+
- **Persistent agent identity** — unique ID, name, operator metadata
|
|
664
|
+
- **Cryptographic verification** — ECDSA P-256 / RSA-PSS public keys; HTTP Message Signatures (RFC 9421)
|
|
665
|
+
- **Capability-based access control** — browse, search, compare, purchase, audit
|
|
666
|
+
- **Intent-scoped sessions** — time-limited, validated against capabilities
|
|
667
|
+
- **Trust levels** — basic, verified, enterprise
|
|
668
|
+
|
|
669
|
+
### Verification Hierarchy
|
|
670
|
+
|
|
671
|
+
| Layer | Proves | Mechanism |
|
|
672
|
+
|-------|--------|-----------|
|
|
673
|
+
| Anonymous | "I am a bot" | Speed challenge <500ms |
|
|
674
|
+
| App-scoped | "I belong to this org" | Challenge + app_id |
|
|
675
|
+
| Agent identity | "I am this specific bot" | Registered ID + capabilities |
|
|
676
|
+
| Cryptographic | "I can prove it" | RFC 9421 signatures |
|
|
677
|
+
| Dual auth | "Verified + proven" | Challenge + signature |
|
|
678
|
+
| Intent-scoped | "I intend to do this now" | Validated session |
|
|
679
|
+
|
|
680
|
+
## 6. Architecture
|
|
681
|
+
|
|
682
|
+
- **Runtime:** Cloudflare Workers (300+ edge locations)
|
|
683
|
+
- **Storage:** Workers KV with TTLs
|
|
684
|
+
- **Tokens:** HMAC-SHA256 JWTs (5-min access, 1-hr refresh)
|
|
685
|
+
- **TAP Signatures:** ECDSA P-256 or RSA-PSS SHA-256
|
|
686
|
+
- **Rate Limits:** 100 challenges/hour/app (fail-open)
|
|
687
|
+
|
|
688
|
+
## 7. Integration
|
|
689
|
+
|
|
690
|
+
### Client SDKs
|
|
691
|
+
|
|
692
|
+
\`\`\`typescript
|
|
693
|
+
import { BotchaClient } from '@dupecom/botcha';
|
|
694
|
+
const client = new BotchaClient();
|
|
695
|
+
const response = await client.fetch('https://api.example.com/products');
|
|
696
|
+
\`\`\`
|
|
697
|
+
|
|
698
|
+
\`\`\`python
|
|
699
|
+
from botcha import BotchaClient
|
|
700
|
+
async with BotchaClient() as client:
|
|
701
|
+
response = await client.fetch("https://api.example.com/products")
|
|
702
|
+
\`\`\`
|
|
703
|
+
|
|
704
|
+
### Server-side Verification
|
|
705
|
+
|
|
706
|
+
Express: \`@botcha/verify\` · FastAPI/Django: \`botcha-verify\` · Hono middleware included.
|
|
707
|
+
|
|
708
|
+
### CLI
|
|
709
|
+
|
|
710
|
+
\`\`\`bash
|
|
711
|
+
npm install -g @dupecom/botcha-cli
|
|
712
|
+
botcha init --email you@company.com
|
|
713
|
+
botcha tap register --name "my-agent" --capabilities browse,search
|
|
714
|
+
botcha tap session --action browse --resource products --duration 1h
|
|
715
|
+
\`\`\`
|
|
716
|
+
|
|
717
|
+
## 8. The Agent Infrastructure Stack
|
|
718
|
+
|
|
719
|
+
\`\`\`
|
|
720
|
+
Layer 3: Identity TAP (BOTCHA) Who agents are
|
|
721
|
+
Layer 2: Communication A2A (Google) How agents talk
|
|
722
|
+
Layer 1: Tools MCP (Anthropic) What agents access
|
|
723
|
+
\`\`\`
|
|
724
|
+
|
|
725
|
+
MCP gives agents tools. A2A lets agents communicate. TAP proves identity and scopes authorization.
|
|
726
|
+
|
|
727
|
+
## 9. Use Cases
|
|
728
|
+
|
|
729
|
+
- **E-commerce:** Agents register capabilities, create scoped purchase sessions, full audit trail.
|
|
730
|
+
- **API access control:** Speed challenge gates endpoints; no API keys needed.
|
|
731
|
+
- **Multi-agent systems:** Coordinator delegates to capability-scoped sub-agents.
|
|
732
|
+
- **Compliance:** TAP audit logging records every agent interaction with intent and context.
|
|
733
|
+
|
|
734
|
+
## 10. Roadmap
|
|
735
|
+
|
|
736
|
+
**Shipped:** Challenge types, JWT tokens, multi-tenant apps, agent registry, TAP, dashboard, SDKs (TS/Python), CLI, LangChain, discovery standards.
|
|
737
|
+
|
|
738
|
+
**Planned:** Agent SSO (cross-service verification), IETF RFC contribution.
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
|
|
742
|
+
Website: https://botcha.ai · GitHub: https://github.com/dupe-com/botcha · npm: @dupecom/botcha · PyPI: botcha
|
|
743
|
+
`;
|
|
744
|
+
}
|
|
486
745
|
// OpenAPI spec - keeping this as a function to allow dynamic version
|
|
487
746
|
export function getOpenApiSpec(version) {
|
|
488
747
|
return {
|
|
@@ -1167,7 +1426,7 @@ export function getOpenApiSpec(version) {
|
|
|
1167
1426
|
"operator": { type: "string", description: "Operator/organization name" },
|
|
1168
1427
|
"version": { type: "string", description: "Agent version" },
|
|
1169
1428
|
"public_key": { type: "string", description: "PEM-encoded public key" },
|
|
1170
|
-
"signature_algorithm": { type: "string", enum: ["ecdsa-p256-sha256", "rsa-pss-sha256"], description: "Signature algorithm (required if public_key provided)" },
|
|
1429
|
+
"signature_algorithm": { type: "string", enum: ["ed25519", "ecdsa-p256-sha256", "rsa-pss-sha256"], description: "Signature algorithm (required if public_key provided)" },
|
|
1171
1430
|
"trust_level": { type: "string", enum: ["basic", "verified", "enterprise"], description: "Agent trust level (default: basic)" },
|
|
1172
1431
|
"capabilities": {
|
|
1173
1432
|
type: "array",
|
|
@@ -1294,6 +1553,555 @@ export function getOpenApiSpec(version) {
|
|
|
1294
1553
|
"404": { description: "Session not found or expired" }
|
|
1295
1554
|
}
|
|
1296
1555
|
}
|
|
1556
|
+
},
|
|
1557
|
+
"/.well-known/jwks": {
|
|
1558
|
+
get: {
|
|
1559
|
+
summary: "Get JWK Set (Visa TAP spec standard)",
|
|
1560
|
+
description: "Retrieve the JWK Set containing public keys for all TAP agents registered in your app. Follows Visa TAP specification standard.",
|
|
1561
|
+
operationId: "getJWKS",
|
|
1562
|
+
responses: {
|
|
1563
|
+
"200": {
|
|
1564
|
+
description: "JWK Set with array of keys",
|
|
1565
|
+
content: {
|
|
1566
|
+
"application/json": {
|
|
1567
|
+
schema: {
|
|
1568
|
+
type: "object",
|
|
1569
|
+
properties: {
|
|
1570
|
+
"keys": {
|
|
1571
|
+
type: "array",
|
|
1572
|
+
items: {
|
|
1573
|
+
type: "object",
|
|
1574
|
+
properties: {
|
|
1575
|
+
"kty": { type: "string", description: "Key type (EC, RSA, OKP)" },
|
|
1576
|
+
"kid": { type: "string", description: "Key ID" },
|
|
1577
|
+
"use": { type: "string", description: "Public key use (sig)" },
|
|
1578
|
+
"alg": { type: "string", description: "Algorithm (ES256, RS256, EdDSA)" }
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
},
|
|
1590
|
+
"/v1/keys": {
|
|
1591
|
+
get: {
|
|
1592
|
+
summary: "List keys or get key by ID",
|
|
1593
|
+
description: "List all keys or get a specific key using ?keyID= query parameter (Visa compatibility).",
|
|
1594
|
+
operationId: "getKeys",
|
|
1595
|
+
parameters: [
|
|
1596
|
+
{
|
|
1597
|
+
name: "keyID",
|
|
1598
|
+
in: "query",
|
|
1599
|
+
schema: { type: "string" },
|
|
1600
|
+
description: "Optional key ID for Visa TAP compatibility"
|
|
1601
|
+
}
|
|
1602
|
+
],
|
|
1603
|
+
responses: {
|
|
1604
|
+
"200": { description: "Key list or specific key" }
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
},
|
|
1608
|
+
"/v1/keys/{keyId}": {
|
|
1609
|
+
get: {
|
|
1610
|
+
summary: "Get key by ID",
|
|
1611
|
+
description: "Retrieve a specific public key by key ID.",
|
|
1612
|
+
operationId: "getKeyById",
|
|
1613
|
+
parameters: [
|
|
1614
|
+
{
|
|
1615
|
+
name: "keyId",
|
|
1616
|
+
in: "path",
|
|
1617
|
+
required: true,
|
|
1618
|
+
schema: { type: "string" }
|
|
1619
|
+
}
|
|
1620
|
+
],
|
|
1621
|
+
responses: {
|
|
1622
|
+
"200": { description: "Public key details" },
|
|
1623
|
+
"404": { description: "Key not found" }
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
},
|
|
1627
|
+
"/v1/agents/{id}/tap/rotate-key": {
|
|
1628
|
+
post: {
|
|
1629
|
+
summary: "Rotate agent key pair",
|
|
1630
|
+
description: "Generate a new key pair for the agent and invalidate the old one.",
|
|
1631
|
+
operationId: "rotateAgentKey",
|
|
1632
|
+
parameters: [
|
|
1633
|
+
{
|
|
1634
|
+
name: "id",
|
|
1635
|
+
in: "path",
|
|
1636
|
+
required: true,
|
|
1637
|
+
schema: { type: "string" }
|
|
1638
|
+
}
|
|
1639
|
+
],
|
|
1640
|
+
requestBody: {
|
|
1641
|
+
content: {
|
|
1642
|
+
"application/json": {
|
|
1643
|
+
schema: {
|
|
1644
|
+
type: "object",
|
|
1645
|
+
properties: {
|
|
1646
|
+
"algorithm": {
|
|
1647
|
+
type: "string",
|
|
1648
|
+
enum: ["ed25519", "ecdsa-p256-sha256", "rsa-pss-sha256"],
|
|
1649
|
+
description: "Algorithm for new key (default: ed25519)"
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
},
|
|
1656
|
+
responses: {
|
|
1657
|
+
"200": { description: "Key rotated successfully" }
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
},
|
|
1661
|
+
"/v1/invoices": {
|
|
1662
|
+
post: {
|
|
1663
|
+
summary: "Create invoice for 402 micropayment",
|
|
1664
|
+
description: "Create an invoice for gated content. Used with Browsing IOU flow.",
|
|
1665
|
+
operationId: "createInvoice",
|
|
1666
|
+
requestBody: {
|
|
1667
|
+
required: true,
|
|
1668
|
+
content: {
|
|
1669
|
+
"application/json": {
|
|
1670
|
+
schema: {
|
|
1671
|
+
type: "object",
|
|
1672
|
+
required: ["amount", "currency", "description"],
|
|
1673
|
+
properties: {
|
|
1674
|
+
"amount": { type: "integer", description: "Amount in cents" },
|
|
1675
|
+
"currency": { type: "string", description: "Currency code (USD, EUR, etc.)" },
|
|
1676
|
+
"description": { type: "string" },
|
|
1677
|
+
"metadata": { type: "object" }
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
},
|
|
1683
|
+
responses: {
|
|
1684
|
+
"201": { description: "Invoice created" }
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
},
|
|
1688
|
+
"/v1/invoices/{id}": {
|
|
1689
|
+
get: {
|
|
1690
|
+
summary: "Get invoice details",
|
|
1691
|
+
operationId: "getInvoice",
|
|
1692
|
+
parameters: [
|
|
1693
|
+
{
|
|
1694
|
+
name: "id",
|
|
1695
|
+
in: "path",
|
|
1696
|
+
required: true,
|
|
1697
|
+
schema: { type: "string" }
|
|
1698
|
+
}
|
|
1699
|
+
],
|
|
1700
|
+
responses: {
|
|
1701
|
+
"200": { description: "Invoice details" },
|
|
1702
|
+
"404": { description: "Invoice not found" }
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
},
|
|
1706
|
+
"/v1/invoices/{id}/verify-iou": {
|
|
1707
|
+
post: {
|
|
1708
|
+
summary: "Verify Browsing IOU",
|
|
1709
|
+
description: "Verify a Browsing IOU (payment intent token) against an invoice.",
|
|
1710
|
+
operationId: "verifyBrowsingIOU",
|
|
1711
|
+
parameters: [
|
|
1712
|
+
{
|
|
1713
|
+
name: "id",
|
|
1714
|
+
in: "path",
|
|
1715
|
+
required: true,
|
|
1716
|
+
schema: { type: "string" }
|
|
1717
|
+
}
|
|
1718
|
+
],
|
|
1719
|
+
requestBody: {
|
|
1720
|
+
required: true,
|
|
1721
|
+
content: {
|
|
1722
|
+
"application/json": {
|
|
1723
|
+
schema: {
|
|
1724
|
+
type: "object",
|
|
1725
|
+
required: ["iou_token"],
|
|
1726
|
+
properties: {
|
|
1727
|
+
"iou_token": { type: "string" }
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
},
|
|
1733
|
+
responses: {
|
|
1734
|
+
"200": { description: "IOU verified" },
|
|
1735
|
+
"400": { description: "Invalid IOU" }
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
},
|
|
1739
|
+
"/v1/verify/consumer": {
|
|
1740
|
+
post: {
|
|
1741
|
+
summary: "Verify Agentic Consumer object (Layer 2)",
|
|
1742
|
+
description: "Verify an agenticConsumer object including ID token, contextual data, and signature chain.",
|
|
1743
|
+
operationId: "verifyConsumer",
|
|
1744
|
+
requestBody: {
|
|
1745
|
+
required: true,
|
|
1746
|
+
content: {
|
|
1747
|
+
"application/json": {
|
|
1748
|
+
schema: {
|
|
1749
|
+
type: "object",
|
|
1750
|
+
required: ["agenticConsumer", "signature"],
|
|
1751
|
+
properties: {
|
|
1752
|
+
"agenticConsumer": {
|
|
1753
|
+
type: "object",
|
|
1754
|
+
properties: {
|
|
1755
|
+
"idToken": { type: "string", description: "OIDC ID token" },
|
|
1756
|
+
"country": { type: "string" },
|
|
1757
|
+
"postalCode": { type: "string" },
|
|
1758
|
+
"ipAddress": { type: "string" },
|
|
1759
|
+
"nonce": { type: "string" }
|
|
1760
|
+
}
|
|
1761
|
+
},
|
|
1762
|
+
"signature": { type: "string" }
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
},
|
|
1768
|
+
responses: {
|
|
1769
|
+
"200": { description: "Consumer verified" },
|
|
1770
|
+
"400": { description: "Invalid consumer object" }
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
},
|
|
1774
|
+
"/v1/verify/payment": {
|
|
1775
|
+
post: {
|
|
1776
|
+
summary: "Verify Agentic Payment Container (Layer 3)",
|
|
1777
|
+
description: "Verify an agenticPaymentContainer object including card metadata, credential hash, and encrypted payload.",
|
|
1778
|
+
operationId: "verifyPayment",
|
|
1779
|
+
requestBody: {
|
|
1780
|
+
required: true,
|
|
1781
|
+
content: {
|
|
1782
|
+
"application/json": {
|
|
1783
|
+
schema: {
|
|
1784
|
+
type: "object",
|
|
1785
|
+
required: ["agenticPaymentContainer", "signature"],
|
|
1786
|
+
properties: {
|
|
1787
|
+
"agenticPaymentContainer": {
|
|
1788
|
+
type: "object",
|
|
1789
|
+
properties: {
|
|
1790
|
+
"lastFour": { type: "string" },
|
|
1791
|
+
"par": { type: "string", description: "Payment Account Reference" },
|
|
1792
|
+
"credentialHash": { type: "string" },
|
|
1793
|
+
"encryptedPayload": { type: "string" },
|
|
1794
|
+
"nonce": { type: "string" }
|
|
1795
|
+
}
|
|
1796
|
+
},
|
|
1797
|
+
"signature": { type: "string" }
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
},
|
|
1803
|
+
responses: {
|
|
1804
|
+
"200": { description: "Payment verified" },
|
|
1805
|
+
"400": { description: "Invalid payment container" }
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
},
|
|
1809
|
+
"/v1/delegations": {
|
|
1810
|
+
post: {
|
|
1811
|
+
summary: "Create delegation",
|
|
1812
|
+
description: "Create a delegation from one agent to another. Grants a subset of the grantor's capabilities to the grantee.",
|
|
1813
|
+
operationId: "createDelegation",
|
|
1814
|
+
parameters: [{ name: "app_id", in: "query", required: true, schema: { type: "string" } }],
|
|
1815
|
+
requestBody: {
|
|
1816
|
+
required: true,
|
|
1817
|
+
content: {
|
|
1818
|
+
"application/json": {
|
|
1819
|
+
schema: {
|
|
1820
|
+
type: "object",
|
|
1821
|
+
required: ["grantor_id", "grantee_id", "capabilities"],
|
|
1822
|
+
properties: {
|
|
1823
|
+
"grantor_id": { type: "string", description: "Agent granting capabilities" },
|
|
1824
|
+
"grantee_id": { type: "string", description: "Agent receiving capabilities" },
|
|
1825
|
+
"capabilities": { type: "array", items: { type: "object" }, description: "Capabilities to delegate (subset of grantor's)" },
|
|
1826
|
+
"duration_seconds": { type: "integer", description: "Duration in seconds (default: 3600)" },
|
|
1827
|
+
"max_depth": { type: "integer", description: "Max sub-delegation depth (default: 3)" },
|
|
1828
|
+
"parent_delegation_id": { type: "string", description: "Parent delegation ID for sub-delegation" },
|
|
1829
|
+
"metadata": { type: "object", description: "Optional context metadata" }
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
},
|
|
1835
|
+
responses: {
|
|
1836
|
+
"201": { description: "Delegation created" },
|
|
1837
|
+
"400": { description: "Invalid request or capability escalation" },
|
|
1838
|
+
"403": { description: "Insufficient capabilities or depth limit" },
|
|
1839
|
+
"409": { description: "Cycle detected in chain" }
|
|
1840
|
+
}
|
|
1841
|
+
},
|
|
1842
|
+
get: {
|
|
1843
|
+
summary: "List delegations",
|
|
1844
|
+
description: "List delegations for an agent.",
|
|
1845
|
+
operationId: "listDelegations",
|
|
1846
|
+
parameters: [
|
|
1847
|
+
{ name: "app_id", in: "query", required: true, schema: { type: "string" } },
|
|
1848
|
+
{ name: "agent_id", in: "query", required: true, schema: { type: "string" } },
|
|
1849
|
+
{ name: "direction", in: "query", schema: { type: "string", enum: ["in", "out", "both"] } },
|
|
1850
|
+
{ name: "include_revoked", in: "query", schema: { type: "boolean" } },
|
|
1851
|
+
{ name: "include_expired", in: "query", schema: { type: "boolean" } }
|
|
1852
|
+
],
|
|
1853
|
+
responses: {
|
|
1854
|
+
"200": { description: "Delegation list" }
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
},
|
|
1858
|
+
"/v1/delegations/{id}": {
|
|
1859
|
+
get: {
|
|
1860
|
+
summary: "Get delegation details",
|
|
1861
|
+
operationId: "getDelegation",
|
|
1862
|
+
parameters: [{ name: "id", in: "path", required: true, schema: { type: "string" } }],
|
|
1863
|
+
responses: {
|
|
1864
|
+
"200": { description: "Delegation details" },
|
|
1865
|
+
"404": { description: "Delegation not found or expired" }
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
},
|
|
1869
|
+
"/v1/delegations/{id}/revoke": {
|
|
1870
|
+
post: {
|
|
1871
|
+
summary: "Revoke delegation",
|
|
1872
|
+
description: "Revoke a delegation and cascade to all sub-delegations.",
|
|
1873
|
+
operationId: "revokeDelegation",
|
|
1874
|
+
parameters: [
|
|
1875
|
+
{ name: "id", in: "path", required: true, schema: { type: "string" } },
|
|
1876
|
+
{ name: "app_id", in: "query", required: true, schema: { type: "string" } }
|
|
1877
|
+
],
|
|
1878
|
+
requestBody: {
|
|
1879
|
+
content: {
|
|
1880
|
+
"application/json": {
|
|
1881
|
+
schema: {
|
|
1882
|
+
type: "object",
|
|
1883
|
+
properties: {
|
|
1884
|
+
"reason": { type: "string", description: "Revocation reason" }
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
},
|
|
1890
|
+
responses: {
|
|
1891
|
+
"200": { description: "Delegation revoked" },
|
|
1892
|
+
"404": { description: "Delegation not found" }
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
},
|
|
1896
|
+
"/v1/verify/delegation": {
|
|
1897
|
+
post: {
|
|
1898
|
+
summary: "Verify delegation chain",
|
|
1899
|
+
description: "Verify an entire delegation chain is valid (not revoked, not expired, capabilities are valid subsets).",
|
|
1900
|
+
operationId: "verifyDelegationChain",
|
|
1901
|
+
requestBody: {
|
|
1902
|
+
required: true,
|
|
1903
|
+
content: {
|
|
1904
|
+
"application/json": {
|
|
1905
|
+
schema: {
|
|
1906
|
+
type: "object",
|
|
1907
|
+
required: ["delegation_id"],
|
|
1908
|
+
properties: {
|
|
1909
|
+
"delegation_id": { type: "string", description: "The leaf delegation to verify" }
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
},
|
|
1915
|
+
responses: {
|
|
1916
|
+
"200": { description: "Chain is valid — returns chain and effective capabilities" },
|
|
1917
|
+
"400": { description: "Chain is invalid — returns error reason" }
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
},
|
|
1921
|
+
"/v1/attestations": {
|
|
1922
|
+
post: {
|
|
1923
|
+
summary: "Issue attestation",
|
|
1924
|
+
description: "Issue a capability attestation token for an agent. Grants fine-grained action:resource permissions with explicit deny.",
|
|
1925
|
+
operationId: "issueAttestation",
|
|
1926
|
+
requestBody: {
|
|
1927
|
+
required: true,
|
|
1928
|
+
content: {
|
|
1929
|
+
"application/json": {
|
|
1930
|
+
schema: {
|
|
1931
|
+
type: "object",
|
|
1932
|
+
required: ["agent_id", "can"],
|
|
1933
|
+
properties: {
|
|
1934
|
+
"agent_id": { type: "string", description: "Agent to issue attestation for" },
|
|
1935
|
+
"can": { type: "array", items: { type: "string" }, description: "Allowed capability patterns (action:resource)" },
|
|
1936
|
+
"cannot": { type: "array", items: { type: "string" }, description: "Denied capability patterns (overrides can)" },
|
|
1937
|
+
"restrictions": { type: "object", description: "Optional restrictions (max_amount, rate_limit)" },
|
|
1938
|
+
"duration_seconds": { type: "integer", description: "Attestation lifetime (default: 3600)" },
|
|
1939
|
+
"delegation_id": { type: "string", description: "Optional link to delegation chain" },
|
|
1940
|
+
"metadata": { type: "object", description: "Optional context metadata" }
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
},
|
|
1946
|
+
responses: {
|
|
1947
|
+
"201": { description: "Attestation issued — includes signed JWT token" },
|
|
1948
|
+
"400": { description: "Invalid request" },
|
|
1949
|
+
"403": { description: "Agent does not belong to app" },
|
|
1950
|
+
"404": { description: "Agent not found" }
|
|
1951
|
+
}
|
|
1952
|
+
},
|
|
1953
|
+
get: {
|
|
1954
|
+
summary: "List attestations",
|
|
1955
|
+
description: "List attestations for an agent.",
|
|
1956
|
+
operationId: "listAttestations",
|
|
1957
|
+
parameters: [
|
|
1958
|
+
{ name: "app_id", in: "query", required: true, schema: { type: "string" } },
|
|
1959
|
+
{ name: "agent_id", in: "query", required: true, schema: { type: "string" } }
|
|
1960
|
+
],
|
|
1961
|
+
responses: {
|
|
1962
|
+
"200": { description: "Attestation list" }
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
},
|
|
1966
|
+
"/v1/attestations/{id}": {
|
|
1967
|
+
get: {
|
|
1968
|
+
summary: "Get attestation details",
|
|
1969
|
+
operationId: "getAttestation",
|
|
1970
|
+
parameters: [{ name: "id", in: "path", required: true, schema: { type: "string" } }],
|
|
1971
|
+
responses: {
|
|
1972
|
+
"200": { description: "Attestation details" },
|
|
1973
|
+
"404": { description: "Attestation not found or expired" }
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
},
|
|
1977
|
+
"/v1/attestations/{id}/revoke": {
|
|
1978
|
+
post: {
|
|
1979
|
+
summary: "Revoke attestation",
|
|
1980
|
+
description: "Revoke an attestation. Token will be rejected on future verification.",
|
|
1981
|
+
operationId: "revokeAttestation",
|
|
1982
|
+
parameters: [
|
|
1983
|
+
{ name: "id", in: "path", required: true, schema: { type: "string" } },
|
|
1984
|
+
{ name: "app_id", in: "query", required: true, schema: { type: "string" } }
|
|
1985
|
+
],
|
|
1986
|
+
requestBody: {
|
|
1987
|
+
content: {
|
|
1988
|
+
"application/json": {
|
|
1989
|
+
schema: {
|
|
1990
|
+
type: "object",
|
|
1991
|
+
properties: {
|
|
1992
|
+
"reason": { type: "string", description: "Revocation reason" }
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
},
|
|
1998
|
+
responses: {
|
|
1999
|
+
"200": { description: "Attestation revoked" },
|
|
2000
|
+
"404": { description: "Attestation not found" }
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
},
|
|
2004
|
+
"/v1/verify/attestation": {
|
|
2005
|
+
post: {
|
|
2006
|
+
summary: "Verify attestation token",
|
|
2007
|
+
description: "Verify an attestation JWT token and optionally check a specific capability.",
|
|
2008
|
+
operationId: "verifyAttestation",
|
|
2009
|
+
requestBody: {
|
|
2010
|
+
required: true,
|
|
2011
|
+
content: {
|
|
2012
|
+
"application/json": {
|
|
2013
|
+
schema: {
|
|
2014
|
+
type: "object",
|
|
2015
|
+
required: ["token"],
|
|
2016
|
+
properties: {
|
|
2017
|
+
"token": { type: "string", description: "Attestation JWT token" },
|
|
2018
|
+
"action": { type: "string", description: "Optional capability action to check (e.g. read)" },
|
|
2019
|
+
"resource": { type: "string", description: "Optional capability resource to check (e.g. invoices)" }
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
},
|
|
2025
|
+
responses: {
|
|
2026
|
+
"200": { description: "Token valid — returns payload or capability check result" },
|
|
2027
|
+
"401": { description: "Invalid or expired token" },
|
|
2028
|
+
"403": { description: "Capability denied" }
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
},
|
|
2032
|
+
"/v1/reputation/{agent_id}": {
|
|
2033
|
+
get: {
|
|
2034
|
+
summary: "Get agent reputation",
|
|
2035
|
+
description: "Get the reputation score for an agent. Returns score (0-1000), tier, event counts, and category breakdown.",
|
|
2036
|
+
operationId: "getReputation",
|
|
2037
|
+
parameters: [
|
|
2038
|
+
{ name: "agent_id", in: "path", required: true, schema: { type: "string" }, description: "Agent ID" },
|
|
2039
|
+
{ name: "app_id", in: "query", schema: { type: "string" }, description: "App ID for authentication" }
|
|
2040
|
+
],
|
|
2041
|
+
responses: {
|
|
2042
|
+
"200": { description: "Reputation score with tier and category breakdown" },
|
|
2043
|
+
"404": { description: "Agent not found" }
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
},
|
|
2047
|
+
"/v1/reputation/events": {
|
|
2048
|
+
post: {
|
|
2049
|
+
summary: "Record reputation event",
|
|
2050
|
+
description: "Record a behavioral event that affects an agent's reputation score. 18 action types across 6 categories.",
|
|
2051
|
+
operationId: "recordReputationEvent",
|
|
2052
|
+
requestBody: {
|
|
2053
|
+
required: true,
|
|
2054
|
+
content: {
|
|
2055
|
+
"application/json": {
|
|
2056
|
+
schema: {
|
|
2057
|
+
type: "object",
|
|
2058
|
+
required: ["agent_id", "category", "action"],
|
|
2059
|
+
properties: {
|
|
2060
|
+
"agent_id": { type: "string", description: "Agent to record event for" },
|
|
2061
|
+
"category": { type: "string", enum: ["verification", "attestation", "delegation", "session", "violation", "endorsement"], description: "Event category" },
|
|
2062
|
+
"action": { type: "string", description: "Event action (e.g. challenge_solved, abuse_detected)" },
|
|
2063
|
+
"source_agent_id": { type: "string", description: "Source agent for endorsements" },
|
|
2064
|
+
"metadata": { type: "object", additionalProperties: { type: "string" }, description: "Optional key/value metadata" }
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
},
|
|
2070
|
+
responses: {
|
|
2071
|
+
"201": { description: "Event recorded — returns event details and updated score" },
|
|
2072
|
+
"400": { description: "Invalid category/action or self-endorsement" },
|
|
2073
|
+
"404": { description: "Agent not found" }
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
},
|
|
2077
|
+
"/v1/reputation/{agent_id}/events": {
|
|
2078
|
+
get: {
|
|
2079
|
+
summary: "List reputation events",
|
|
2080
|
+
description: "List reputation events for an agent with optional category filter.",
|
|
2081
|
+
operationId: "listReputationEvents",
|
|
2082
|
+
parameters: [
|
|
2083
|
+
{ name: "agent_id", in: "path", required: true, schema: { type: "string" }, description: "Agent ID" },
|
|
2084
|
+
{ name: "category", in: "query", schema: { type: "string" }, description: "Filter by category" },
|
|
2085
|
+
{ name: "limit", in: "query", schema: { type: "integer", maximum: 100 }, description: "Max events (default: 50, max: 100)" }
|
|
2086
|
+
],
|
|
2087
|
+
responses: {
|
|
2088
|
+
"200": { description: "List of reputation events" }
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
},
|
|
2092
|
+
"/v1/reputation/{agent_id}/reset": {
|
|
2093
|
+
post: {
|
|
2094
|
+
summary: "Reset reputation",
|
|
2095
|
+
description: "Reset an agent's reputation to default (500 neutral). Admin action — clears all event history.",
|
|
2096
|
+
operationId: "resetReputation",
|
|
2097
|
+
parameters: [
|
|
2098
|
+
{ name: "agent_id", in: "path", required: true, schema: { type: "string" }, description: "Agent ID" }
|
|
2099
|
+
],
|
|
2100
|
+
responses: {
|
|
2101
|
+
"200": { description: "Reputation reset to default" },
|
|
2102
|
+
"404": { description: "Agent not found" }
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
1297
2105
|
}
|
|
1298
2106
|
},
|
|
1299
2107
|
components: {
|