@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
@@ -14,8 +14,9 @@ import { Agent, KVNamespace } from './agents.js';
14
14
  */
15
15
  export interface TAPAgent extends Agent {
16
16
  public_key?: string;
17
- signature_algorithm?: 'ecdsa-p256-sha256' | 'rsa-pss-sha256';
17
+ signature_algorithm?: 'ecdsa-p256-sha256' | 'rsa-pss-sha256' | 'ed25519';
18
18
  key_created_at?: number;
19
+ key_expires_at?: number;
19
20
  capabilities?: TAPCapability[];
20
21
  trust_level?: 'basic' | 'verified' | 'enterprise';
21
22
  issuer?: string;
@@ -58,7 +59,7 @@ export declare function registerTAPAgent(agents: KVNamespace, appId: string, reg
58
59
  operator?: string;
59
60
  version?: string;
60
61
  public_key?: string;
61
- signature_algorithm?: 'ecdsa-p256-sha256' | 'rsa-pss-sha256';
62
+ signature_algorithm?: 'ecdsa-p256-sha256' | 'rsa-pss-sha256' | 'ed25519';
62
63
  capabilities?: TAPCapability[];
63
64
  trust_level?: 'basic' | 'verified' | 'enterprise';
64
65
  issuer?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"tap-agents.d.ts","sourceRoot":"","sources":["../src/tap-agents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tap-agents.d.ts","sourceRoot":"","sources":["../src/tap-agents.ts"],"names":[],"mappings":"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"}
@@ -42,8 +42,8 @@ export async function registerTAPAgent(agents, appId, registration) {
42
42
  return { success: false, error: 'signature_algorithm required when public_key provided' };
43
43
  }
44
44
  // Validate public key format
45
- if (!isValidPEMPublicKey(agent.public_key)) {
46
- return { success: false, error: 'Invalid PEM public key format' };
45
+ if (!isValidPublicKey(agent.public_key, agent.signature_algorithm)) {
46
+ return { success: false, error: 'Invalid public key format' };
47
47
  }
48
48
  }
49
49
  // Store agent
@@ -175,10 +175,23 @@ function generateSessionId() {
175
175
  .map(b => b.toString(16).padStart(2, '0'))
176
176
  .join('');
177
177
  }
178
- function isValidPEMPublicKey(pemKey) {
179
- return pemKey.includes('BEGIN PUBLIC KEY') &&
180
- pemKey.includes('END PUBLIC KEY') &&
181
- pemKey.length > 100; // Basic sanity check
178
+ function isValidPublicKey(key, algorithm) {
179
+ // PEM format
180
+ if (key.includes('BEGIN PUBLIC KEY') && key.includes('END PUBLIC KEY') && key.length > 100) {
181
+ return true;
182
+ }
183
+ // Raw Ed25519 key (32 bytes = ~44 base64 chars)
184
+ if (algorithm === 'ed25519') {
185
+ const stripped = key.replace(/[\s]/g, '');
186
+ try {
187
+ const decoded = atob(stripped.replace(/-/g, '+').replace(/_/g, '/'));
188
+ return decoded.length === 32;
189
+ }
190
+ catch {
191
+ return false;
192
+ }
193
+ }
194
+ return false;
182
195
  }
183
196
  async function updateAppAgentIndex(agents, appId, agentId, operation) {
184
197
  try {
@@ -0,0 +1,204 @@
1
+ /**
2
+ * TAP Capability Attestation API Routes
3
+ *
4
+ * Endpoints for issuing, retrieving, revoking, and verifying
5
+ * capability attestation tokens for TAP agents.
6
+ *
7
+ * Routes:
8
+ * POST /v1/attestations — Issue attestation token
9
+ * GET /v1/attestations/:id — Get attestation details
10
+ * GET /v1/attestations — List attestations for agent
11
+ * POST /v1/attestations/:id/revoke — Revoke attestation
12
+ * POST /v1/verify/attestation — Verify attestation + check capability
13
+ */
14
+ import type { Context } from 'hono';
15
+ /**
16
+ * POST /v1/attestations
17
+ * Issue a capability attestation token for an agent
18
+ */
19
+ export declare function issueAttestationRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
20
+ success: false;
21
+ error: string | undefined;
22
+ message: string;
23
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
24
+ success: false;
25
+ error: string;
26
+ message: string | undefined;
27
+ }, any, "json">) | (Response & import("hono").TypedResponse<{
28
+ success: true;
29
+ attestation_id: string;
30
+ agent_id: string;
31
+ app_id: string;
32
+ token: string;
33
+ can: string[];
34
+ cannot: string[];
35
+ restrictions: {
36
+ [x: string]: any;
37
+ max_amount?: number | undefined;
38
+ rate_limit?: number | undefined;
39
+ } | null;
40
+ delegation_id: string | null;
41
+ metadata: {
42
+ [x: string]: string;
43
+ } | null;
44
+ created_at: string;
45
+ expires_at: string;
46
+ }, 201, "json">)>;
47
+ /**
48
+ * GET /v1/attestations/:id
49
+ * Get attestation details
50
+ */
51
+ export declare function getAttestationRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
52
+ success: false;
53
+ error: string;
54
+ message: string;
55
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
56
+ success: false;
57
+ error: string;
58
+ message: string;
59
+ }, 404, "json">) | (Response & import("hono").TypedResponse<{
60
+ success: true;
61
+ attestation_id: string;
62
+ agent_id: string;
63
+ app_id: string;
64
+ can: string[];
65
+ cannot: string[];
66
+ restrictions: {
67
+ [x: string]: any;
68
+ max_amount?: number | undefined;
69
+ rate_limit?: number | undefined;
70
+ } | null;
71
+ delegation_id: string | null;
72
+ metadata: {
73
+ [x: string]: string;
74
+ } | null;
75
+ created_at: string;
76
+ expires_at: string;
77
+ revoked: boolean;
78
+ revoked_at: string | null;
79
+ revocation_reason: string | null;
80
+ time_remaining: number;
81
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
82
+ success: false;
83
+ error: string;
84
+ message: string;
85
+ }, 500, "json">)>;
86
+ /**
87
+ * GET /v1/attestations
88
+ * List attestations for an agent
89
+ *
90
+ * Query params:
91
+ * agent_id — required, the agent to list attestations for
92
+ */
93
+ export declare function listAttestationsRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
94
+ success: false;
95
+ error: string | undefined;
96
+ message: string;
97
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
98
+ success: false;
99
+ error: string;
100
+ message: string;
101
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
102
+ success: true;
103
+ attestations: any[];
104
+ count: number;
105
+ agent_id: string;
106
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
107
+ success: false;
108
+ error: string;
109
+ message: string;
110
+ }, 500, "json">)>;
111
+ /**
112
+ * POST /v1/attestations/:id/revoke
113
+ * Revoke an attestation
114
+ */
115
+ export declare function revokeAttestationRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
116
+ success: false;
117
+ error: string;
118
+ message: string;
119
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
120
+ success: false;
121
+ error: string | undefined;
122
+ message: string;
123
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
124
+ success: false;
125
+ error: string;
126
+ message: string;
127
+ }, 404, "json">) | (Response & import("hono").TypedResponse<{
128
+ success: false;
129
+ error: string;
130
+ message: string;
131
+ }, 403, "json">) | (Response & import("hono").TypedResponse<{
132
+ success: false;
133
+ error: string;
134
+ message: string | undefined;
135
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
136
+ success: true;
137
+ attestation_id: string;
138
+ revoked: true;
139
+ revoked_at: string | null;
140
+ revocation_reason: string | null;
141
+ message: string;
142
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
143
+ /**
144
+ * POST /v1/verify/attestation
145
+ * Verify an attestation token and optionally check a specific capability
146
+ *
147
+ * Body:
148
+ * token — required, the attestation JWT token
149
+ * action — optional, capability action to check (e.g. "read")
150
+ * resource — optional, capability resource to check (e.g. "invoices")
151
+ */
152
+ export declare function verifyAttestationRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
153
+ success: false;
154
+ error: string;
155
+ message: string;
156
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
157
+ success: false;
158
+ valid: false;
159
+ allowed: false;
160
+ agent_id: string | null;
161
+ error: string | undefined;
162
+ matched_rule: string | null;
163
+ checked_capability: any;
164
+ }, 401 | 403, "json">) | (Response & import("hono").TypedResponse<{
165
+ success: true;
166
+ valid: true;
167
+ allowed: true;
168
+ agent_id: string | undefined;
169
+ reason: string | undefined;
170
+ matched_rule: string | undefined;
171
+ checked_capability: any;
172
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
173
+ success: false;
174
+ valid: false;
175
+ error: string | undefined;
176
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
177
+ success: true;
178
+ valid: true;
179
+ agent_id: string;
180
+ issuer: string;
181
+ can: string[];
182
+ cannot: string[];
183
+ restrictions: {
184
+ [x: string]: any;
185
+ max_amount?: number | undefined;
186
+ rate_limit?: number | undefined;
187
+ } | null;
188
+ delegation_id: string | null;
189
+ issued_at: string;
190
+ expires_at: string;
191
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
192
+ success: false;
193
+ error: string;
194
+ message: string;
195
+ }, 500, "json">)>;
196
+ declare const _default: {
197
+ issueAttestationRoute: typeof issueAttestationRoute;
198
+ getAttestationRoute: typeof getAttestationRoute;
199
+ listAttestationsRoute: typeof listAttestationsRoute;
200
+ revokeAttestationRoute: typeof revokeAttestationRoute;
201
+ verifyAttestationRoute: typeof verifyAttestationRoute;
202
+ };
203
+ export default _default;
204
+ //# sourceMappingURL=tap-attestation-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-attestation-routes.d.ts","sourceRoot":"","sources":["../src/tap-attestation-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AA4CpC;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4GrD;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiDnD;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;kBA8DrD;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;oEAsEtD;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmFtD;;;;;;;;AAED,wBAME"}
@@ -0,0 +1,396 @@
1
+ /**
2
+ * TAP Capability Attestation API Routes
3
+ *
4
+ * Endpoints for issuing, retrieving, revoking, and verifying
5
+ * capability attestation tokens for TAP agents.
6
+ *
7
+ * Routes:
8
+ * POST /v1/attestations — Issue attestation token
9
+ * GET /v1/attestations/:id — Get attestation details
10
+ * GET /v1/attestations — List attestations for agent
11
+ * POST /v1/attestations/:id/revoke — Revoke attestation
12
+ * POST /v1/verify/attestation — Verify attestation + check capability
13
+ */
14
+ import { extractBearerToken, verifyToken } from './auth.js';
15
+ import { issueAttestation, getAttestation, revokeAttestation, verifyAttestationToken, verifyAndCheckCapability, isValidCapabilityPattern, } from './tap-attestation.js';
16
+ // ============ VALIDATION HELPERS ============
17
+ async function validateAppAccess(c, requireAuth = true) {
18
+ const queryAppId = c.req.query('app_id');
19
+ let jwtAppId;
20
+ const authHeader = c.req.header('authorization');
21
+ const token = extractBearerToken(authHeader);
22
+ if (token) {
23
+ const result = await verifyToken(token, c.env.JWT_SECRET, c.env);
24
+ if (result.valid && result.payload) {
25
+ jwtAppId = result.payload.app_id;
26
+ }
27
+ }
28
+ const appId = queryAppId || jwtAppId;
29
+ if (requireAuth && !appId) {
30
+ return { valid: false, error: 'MISSING_APP_ID', status: 401 };
31
+ }
32
+ return { valid: true, appId };
33
+ }
34
+ // ============ ROUTE HANDLERS ============
35
+ /**
36
+ * POST /v1/attestations
37
+ * Issue a capability attestation token for an agent
38
+ */
39
+ export async function issueAttestationRoute(c) {
40
+ try {
41
+ const appAccess = await validateAppAccess(c, true);
42
+ if (!appAccess.valid) {
43
+ return c.json({
44
+ success: false,
45
+ error: appAccess.error,
46
+ message: 'Authentication required'
47
+ }, (appAccess.status || 401));
48
+ }
49
+ const body = await c.req.json().catch(() => ({}));
50
+ // Validate required fields
51
+ if (!body.agent_id) {
52
+ return c.json({
53
+ success: false,
54
+ error: 'MISSING_AGENT_ID',
55
+ message: 'agent_id is required'
56
+ }, 400);
57
+ }
58
+ if (!body.can || !Array.isArray(body.can) || body.can.length === 0) {
59
+ return c.json({
60
+ success: false,
61
+ error: 'MISSING_CAPABILITIES',
62
+ message: 'At least one "can" rule is required (e.g. ["read:invoices", "browse:*"])'
63
+ }, 400);
64
+ }
65
+ // Validate capability patterns
66
+ for (const rule of body.can) {
67
+ if (!isValidCapabilityPattern(rule)) {
68
+ return c.json({
69
+ success: false,
70
+ error: 'INVALID_CAPABILITY_PATTERN',
71
+ message: `Invalid capability pattern in "can": ${rule}. Use "action:resource" format.`
72
+ }, 400);
73
+ }
74
+ }
75
+ if (body.cannot && Array.isArray(body.cannot)) {
76
+ for (const rule of body.cannot) {
77
+ if (!isValidCapabilityPattern(rule)) {
78
+ return c.json({
79
+ success: false,
80
+ error: 'INVALID_CAPABILITY_PATTERN',
81
+ message: `Invalid capability pattern in "cannot": ${rule}. Use "action:resource" format.`
82
+ }, 400);
83
+ }
84
+ }
85
+ }
86
+ const options = {
87
+ agent_id: body.agent_id,
88
+ can: body.can,
89
+ cannot: body.cannot,
90
+ restrictions: body.restrictions,
91
+ duration_seconds: body.duration_seconds,
92
+ delegation_id: body.delegation_id,
93
+ metadata: body.metadata,
94
+ };
95
+ const result = await issueAttestation(c.env.AGENTS, c.env.SESSIONS, appAccess.appId, c.env.JWT_SECRET, options);
96
+ if (!result.success) {
97
+ const status = result.error?.includes('not found') ? 404
98
+ : result.error?.includes('does not belong') ? 403
99
+ : result.error?.includes('Too many rules') ? 400
100
+ : 400;
101
+ return c.json({
102
+ success: false,
103
+ error: 'ATTESTATION_ISSUANCE_FAILED',
104
+ message: result.error
105
+ }, status);
106
+ }
107
+ const att = result.attestation;
108
+ return c.json({
109
+ success: true,
110
+ attestation_id: att.attestation_id,
111
+ agent_id: att.agent_id,
112
+ app_id: att.app_id,
113
+ token: att.token,
114
+ can: att.can,
115
+ cannot: att.cannot,
116
+ restrictions: att.restrictions || null,
117
+ delegation_id: att.delegation_id || null,
118
+ metadata: att.metadata || null,
119
+ created_at: new Date(att.created_at).toISOString(),
120
+ expires_at: new Date(att.expires_at).toISOString(),
121
+ }, 201);
122
+ }
123
+ catch (error) {
124
+ console.error('Attestation issuance error:', error);
125
+ return c.json({
126
+ success: false,
127
+ error: 'INTERNAL_ERROR',
128
+ message: 'Internal server error'
129
+ }, 500);
130
+ }
131
+ }
132
+ /**
133
+ * GET /v1/attestations/:id
134
+ * Get attestation details
135
+ */
136
+ export async function getAttestationRoute(c) {
137
+ try {
138
+ const attestationId = c.req.param('id');
139
+ if (!attestationId) {
140
+ return c.json({
141
+ success: false,
142
+ error: 'MISSING_ATTESTATION_ID',
143
+ message: 'Attestation ID is required'
144
+ }, 400);
145
+ }
146
+ const result = await getAttestation(c.env.SESSIONS, attestationId);
147
+ if (!result.success || !result.attestation) {
148
+ return c.json({
149
+ success: false,
150
+ error: 'ATTESTATION_NOT_FOUND',
151
+ message: result.error || 'Attestation not found or expired'
152
+ }, 404);
153
+ }
154
+ const att = result.attestation;
155
+ return c.json({
156
+ success: true,
157
+ attestation_id: att.attestation_id,
158
+ agent_id: att.agent_id,
159
+ app_id: att.app_id,
160
+ can: att.can,
161
+ cannot: att.cannot,
162
+ restrictions: att.restrictions || null,
163
+ delegation_id: att.delegation_id || null,
164
+ metadata: att.metadata || null,
165
+ created_at: new Date(att.created_at).toISOString(),
166
+ expires_at: new Date(att.expires_at).toISOString(),
167
+ revoked: att.revoked,
168
+ revoked_at: att.revoked_at ? new Date(att.revoked_at).toISOString() : null,
169
+ revocation_reason: att.revocation_reason || null,
170
+ time_remaining: Math.max(0, att.expires_at - Date.now()),
171
+ });
172
+ }
173
+ catch (error) {
174
+ console.error('Attestation retrieval error:', error);
175
+ return c.json({
176
+ success: false,
177
+ error: 'INTERNAL_ERROR',
178
+ message: 'Internal server error'
179
+ }, 500);
180
+ }
181
+ }
182
+ /**
183
+ * GET /v1/attestations
184
+ * List attestations for an agent
185
+ *
186
+ * Query params:
187
+ * agent_id — required, the agent to list attestations for
188
+ */
189
+ export async function listAttestationsRoute(c) {
190
+ try {
191
+ const appAccess = await validateAppAccess(c, true);
192
+ if (!appAccess.valid) {
193
+ return c.json({
194
+ success: false,
195
+ error: appAccess.error,
196
+ message: 'Authentication required'
197
+ }, (appAccess.status || 401));
198
+ }
199
+ const agentId = c.req.query('agent_id');
200
+ if (!agentId) {
201
+ return c.json({
202
+ success: false,
203
+ error: 'MISSING_AGENT_ID',
204
+ message: 'agent_id query parameter is required'
205
+ }, 400);
206
+ }
207
+ // Get the attestation index for this agent
208
+ const indexKey = `agent_attestations:${agentId}`;
209
+ const indexData = await c.env.SESSIONS.get(indexKey, 'text');
210
+ const attestationIds = indexData ? JSON.parse(indexData) : [];
211
+ // Fetch each attestation (filter out expired/missing)
212
+ const attestations = [];
213
+ for (const id of attestationIds) {
214
+ const result = await getAttestation(c.env.SESSIONS, id);
215
+ if (result.success && result.attestation) {
216
+ const att = result.attestation;
217
+ // Only include attestations for this app
218
+ if (att.app_id === appAccess.appId) {
219
+ attestations.push({
220
+ attestation_id: att.attestation_id,
221
+ agent_id: att.agent_id,
222
+ can: att.can,
223
+ cannot: att.cannot,
224
+ created_at: new Date(att.created_at).toISOString(),
225
+ expires_at: new Date(att.expires_at).toISOString(),
226
+ revoked: att.revoked,
227
+ delegation_id: att.delegation_id || null,
228
+ });
229
+ }
230
+ }
231
+ }
232
+ return c.json({
233
+ success: true,
234
+ attestations,
235
+ count: attestations.length,
236
+ agent_id: agentId,
237
+ });
238
+ }
239
+ catch (error) {
240
+ console.error('Attestation listing error:', error);
241
+ return c.json({
242
+ success: false,
243
+ error: 'INTERNAL_ERROR',
244
+ message: 'Internal server error'
245
+ }, 500);
246
+ }
247
+ }
248
+ /**
249
+ * POST /v1/attestations/:id/revoke
250
+ * Revoke an attestation
251
+ */
252
+ export async function revokeAttestationRoute(c) {
253
+ try {
254
+ const attestationId = c.req.param('id');
255
+ if (!attestationId) {
256
+ return c.json({
257
+ success: false,
258
+ error: 'MISSING_ATTESTATION_ID',
259
+ message: 'Attestation ID is required'
260
+ }, 400);
261
+ }
262
+ const appAccess = await validateAppAccess(c, true);
263
+ if (!appAccess.valid) {
264
+ return c.json({
265
+ success: false,
266
+ error: appAccess.error,
267
+ message: 'Authentication required'
268
+ }, (appAccess.status || 401));
269
+ }
270
+ // Verify attestation exists and belongs to this app
271
+ const existing = await getAttestation(c.env.SESSIONS, attestationId);
272
+ if (!existing.success || !existing.attestation) {
273
+ return c.json({
274
+ success: false,
275
+ error: 'ATTESTATION_NOT_FOUND',
276
+ message: 'Attestation not found or expired'
277
+ }, 404);
278
+ }
279
+ if (existing.attestation.app_id !== appAccess.appId) {
280
+ return c.json({
281
+ success: false,
282
+ error: 'UNAUTHORIZED',
283
+ message: 'Attestation does not belong to this app'
284
+ }, 403);
285
+ }
286
+ const body = await c.req.json().catch(() => ({}));
287
+ const reason = body.reason || undefined;
288
+ const result = await revokeAttestation(c.env.SESSIONS, attestationId, reason);
289
+ if (!result.success) {
290
+ return c.json({
291
+ success: false,
292
+ error: 'REVOCATION_FAILED',
293
+ message: result.error
294
+ }, 500);
295
+ }
296
+ const att = result.attestation;
297
+ return c.json({
298
+ success: true,
299
+ attestation_id: att.attestation_id,
300
+ revoked: true,
301
+ revoked_at: att.revoked_at ? new Date(att.revoked_at).toISOString() : null,
302
+ revocation_reason: att.revocation_reason || null,
303
+ message: 'Attestation revoked. Token will be rejected on verification.',
304
+ });
305
+ }
306
+ catch (error) {
307
+ console.error('Attestation revocation error:', error);
308
+ return c.json({
309
+ success: false,
310
+ error: 'INTERNAL_ERROR',
311
+ message: 'Internal server error'
312
+ }, 500);
313
+ }
314
+ }
315
+ /**
316
+ * POST /v1/verify/attestation
317
+ * Verify an attestation token and optionally check a specific capability
318
+ *
319
+ * Body:
320
+ * token — required, the attestation JWT token
321
+ * action — optional, capability action to check (e.g. "read")
322
+ * resource — optional, capability resource to check (e.g. "invoices")
323
+ */
324
+ export async function verifyAttestationRoute(c) {
325
+ try {
326
+ const body = await c.req.json().catch(() => ({}));
327
+ if (!body.token) {
328
+ return c.json({
329
+ success: false,
330
+ error: 'MISSING_TOKEN',
331
+ message: 'Attestation token is required'
332
+ }, 400);
333
+ }
334
+ // If action specified, do full verify+check
335
+ if (body.action) {
336
+ const result = await verifyAndCheckCapability(c.env.SESSIONS, body.token, c.env.JWT_SECRET, body.action, body.resource);
337
+ if (!result.allowed) {
338
+ return c.json({
339
+ success: false,
340
+ valid: false,
341
+ allowed: false,
342
+ agent_id: result.agent_id || null,
343
+ error: result.error || result.reason,
344
+ matched_rule: result.matched_rule || null,
345
+ checked_capability: body.resource ? `${body.action}:${body.resource}` : body.action,
346
+ }, result.error ? 401 : 403);
347
+ }
348
+ return c.json({
349
+ success: true,
350
+ valid: true,
351
+ allowed: true,
352
+ agent_id: result.agent_id,
353
+ reason: result.reason,
354
+ matched_rule: result.matched_rule,
355
+ checked_capability: body.resource ? `${body.action}:${body.resource}` : body.action,
356
+ });
357
+ }
358
+ // Otherwise just verify the token
359
+ const verification = await verifyAttestationToken(c.env.SESSIONS, body.token, c.env.JWT_SECRET);
360
+ if (!verification.valid || !verification.payload) {
361
+ return c.json({
362
+ success: false,
363
+ valid: false,
364
+ error: verification.error,
365
+ }, 401);
366
+ }
367
+ const payload = verification.payload;
368
+ return c.json({
369
+ success: true,
370
+ valid: true,
371
+ agent_id: payload.sub,
372
+ issuer: payload.iss,
373
+ can: payload.can,
374
+ cannot: payload.cannot,
375
+ restrictions: payload.restrictions || null,
376
+ delegation_id: payload.delegation_id || null,
377
+ issued_at: new Date(payload.iat * 1000).toISOString(),
378
+ expires_at: new Date(payload.exp * 1000).toISOString(),
379
+ });
380
+ }
381
+ catch (error) {
382
+ console.error('Attestation verification error:', error);
383
+ return c.json({
384
+ success: false,
385
+ error: 'INTERNAL_ERROR',
386
+ message: 'Internal server error'
387
+ }, 500);
388
+ }
389
+ }
390
+ export default {
391
+ issueAttestationRoute,
392
+ getAttestationRoute,
393
+ listAttestationsRoute,
394
+ revokeAttestationRoute,
395
+ verifyAttestationRoute,
396
+ };