@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.
Files changed (65) hide show
  1. package/dist/dashboard/landing.d.ts.map +1 -1
  2. package/dist/dashboard/landing.js +2 -9
  3. package/dist/dashboard/layout.d.ts +12 -0
  4. package/dist/dashboard/layout.d.ts.map +1 -1
  5. package/dist/dashboard/layout.js +12 -5
  6. package/dist/dashboard/showcase.d.ts +1 -0
  7. package/dist/dashboard/showcase.d.ts.map +1 -1
  8. package/dist/dashboard/showcase.js +3 -2
  9. package/dist/dashboard/whitepaper.d.ts +14 -0
  10. package/dist/dashboard/whitepaper.d.ts.map +1 -0
  11. package/dist/dashboard/whitepaper.js +418 -0
  12. package/dist/email.d.ts.map +1 -1
  13. package/dist/email.js +5 -1
  14. package/dist/index.d.ts +2 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +148 -18
  17. package/dist/og-image.d.ts +2 -0
  18. package/dist/og-image.d.ts.map +1 -0
  19. package/dist/og-image.js +2 -0
  20. package/dist/static.d.ts +871 -2
  21. package/dist/static.d.ts.map +1 -1
  22. package/dist/static.js +812 -4
  23. package/dist/tap-agents.d.ts +3 -2
  24. package/dist/tap-agents.d.ts.map +1 -1
  25. package/dist/tap-agents.js +19 -6
  26. package/dist/tap-attestation-routes.d.ts +204 -0
  27. package/dist/tap-attestation-routes.d.ts.map +1 -0
  28. package/dist/tap-attestation-routes.js +396 -0
  29. package/dist/tap-attestation.d.ts +178 -0
  30. package/dist/tap-attestation.d.ts.map +1 -0
  31. package/dist/tap-attestation.js +416 -0
  32. package/dist/tap-consumer.d.ts +151 -0
  33. package/dist/tap-consumer.d.ts.map +1 -0
  34. package/dist/tap-consumer.js +346 -0
  35. package/dist/tap-delegation-routes.d.ts +236 -0
  36. package/dist/tap-delegation-routes.d.ts.map +1 -0
  37. package/dist/tap-delegation-routes.js +378 -0
  38. package/dist/tap-delegation.d.ts +127 -0
  39. package/dist/tap-delegation.d.ts.map +1 -0
  40. package/dist/tap-delegation.js +490 -0
  41. package/dist/tap-edge.d.ts +106 -0
  42. package/dist/tap-edge.d.ts.map +1 -0
  43. package/dist/tap-edge.js +487 -0
  44. package/dist/tap-federation.d.ts +89 -0
  45. package/dist/tap-federation.d.ts.map +1 -0
  46. package/dist/tap-federation.js +237 -0
  47. package/dist/tap-jwks.d.ts +64 -0
  48. package/dist/tap-jwks.d.ts.map +1 -0
  49. package/dist/tap-jwks.js +279 -0
  50. package/dist/tap-payment.d.ts +172 -0
  51. package/dist/tap-payment.d.ts.map +1 -0
  52. package/dist/tap-payment.js +425 -0
  53. package/dist/tap-reputation-routes.d.ts +154 -0
  54. package/dist/tap-reputation-routes.d.ts.map +1 -0
  55. package/dist/tap-reputation-routes.js +341 -0
  56. package/dist/tap-reputation.d.ts +136 -0
  57. package/dist/tap-reputation.d.ts.map +1 -0
  58. package/dist/tap-reputation.js +346 -0
  59. package/dist/tap-routes.d.ts +239 -2
  60. package/dist/tap-routes.d.ts.map +1 -1
  61. package/dist/tap-routes.js +279 -4
  62. package/dist/tap-verify.d.ts +43 -1
  63. package/dist/tap-verify.d.ts.map +1 -1
  64. package/dist/tap-verify.js +215 -30
  65. 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: {