@dupecom/botcha-cloudflare 0.20.2 → 0.23.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/README.md +74 -9
- package/dist/agent-auth.d.ts +129 -0
- package/dist/agent-auth.d.ts.map +1 -0
- package/dist/agent-auth.js +210 -0
- package/dist/agents.d.ts +10 -0
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +51 -1
- package/dist/app-gate.d.ts +6 -0
- package/dist/app-gate.d.ts.map +1 -0
- package/dist/app-gate.js +69 -0
- package/dist/apps.d.ts +13 -4
- package/dist/apps.d.ts.map +1 -1
- package/dist/apps.js +30 -4
- package/dist/dashboard/account.d.ts +63 -0
- package/dist/dashboard/account.d.ts.map +1 -0
- package/dist/dashboard/account.js +488 -0
- package/dist/dashboard/api.js +15 -68
- package/dist/dashboard/auth.d.ts.map +1 -1
- package/dist/dashboard/auth.js +14 -14
- package/dist/dashboard/docs.d.ts.map +1 -1
- package/dist/dashboard/docs.js +146 -3
- package/dist/dashboard/layout.d.ts.map +1 -1
- package/dist/dashboard/layout.js +2 -2
- package/dist/dashboard/mcp-setup.d.ts +15 -0
- package/dist/dashboard/mcp-setup.d.ts.map +1 -0
- package/dist/dashboard/mcp-setup.js +391 -0
- package/dist/dashboard/showcase.d.ts +6 -10
- package/dist/dashboard/showcase.d.ts.map +1 -1
- package/dist/dashboard/showcase.js +67 -991
- package/dist/dashboard/whitepaper.d.ts.map +1 -1
- package/dist/dashboard/whitepaper.js +42 -4
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +660 -83
- package/dist/mcp.d.ts +20 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +1290 -0
- package/dist/oauth-agent.d.ts +130 -0
- package/dist/oauth-agent.d.ts.map +1 -0
- package/dist/oauth-agent.js +194 -0
- package/dist/static.d.ts +781 -5
- package/dist/static.d.ts.map +1 -1
- package/dist/static.js +790 -111
- package/dist/tap-a2a-routes.d.ts +355 -0
- package/dist/tap-a2a-routes.d.ts.map +1 -0
- package/dist/tap-a2a-routes.js +475 -0
- package/dist/tap-a2a.d.ts +199 -0
- package/dist/tap-a2a.d.ts.map +1 -0
- package/dist/tap-a2a.js +502 -0
- package/dist/tap-agents.d.ts +15 -0
- package/dist/tap-agents.d.ts.map +1 -1
- package/dist/tap-agents.js +31 -1
- package/dist/tap-ans-routes.d.ts +302 -0
- package/dist/tap-ans-routes.d.ts.map +1 -0
- package/dist/tap-ans-routes.js +535 -0
- package/dist/tap-ans.d.ts +241 -0
- package/dist/tap-ans.d.ts.map +1 -0
- package/dist/tap-ans.js +481 -0
- package/dist/tap-delegation-routes.d.ts.map +1 -1
- package/dist/tap-delegation-routes.js +11 -0
- package/dist/tap-did.d.ts +140 -0
- package/dist/tap-did.d.ts.map +1 -0
- package/dist/tap-did.js +262 -0
- package/dist/tap-oidca-routes.d.ts +383 -0
- package/dist/tap-oidca-routes.d.ts.map +1 -0
- package/dist/tap-oidca-routes.js +597 -0
- package/dist/tap-oidca.d.ts +288 -0
- package/dist/tap-oidca.d.ts.map +1 -0
- package/dist/tap-oidca.js +461 -0
- package/dist/tap-routes.d.ts +24 -8
- package/dist/tap-routes.d.ts.map +1 -1
- package/dist/tap-routes.js +169 -23
- package/dist/tap-vc-routes.d.ts +358 -0
- package/dist/tap-vc-routes.d.ts.map +1 -0
- package/dist/tap-vc-routes.js +367 -0
- package/dist/tap-vc.d.ts +125 -0
- package/dist/tap-vc.d.ts.map +1 -0
- package/dist/tap-vc.js +245 -0
- package/dist/tap-x402-routes.d.ts +89 -0
- package/dist/tap-x402-routes.d.ts.map +1 -0
- package/dist/tap-x402-routes.js +579 -0
- package/dist/tap-x402.d.ts +222 -0
- package/dist/tap-x402.d.ts.map +1 -0
- package/dist/tap-x402.js +546 -0
- package/dist/webhooks.d.ts +99 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +642 -0
- package/package.json +3 -1
package/dist/tap-did.js
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BOTCHA DID — W3C DID Core 1.0 + did:web Method
|
|
3
|
+
*
|
|
4
|
+
* Implements:
|
|
5
|
+
* - BOTCHA DID Document generation (did:web:botcha.ai)
|
|
6
|
+
* - Basic did:web resolver (fetch DID Documents from remote hosts)
|
|
7
|
+
* - DID parsing and validation utilities
|
|
8
|
+
* - Agent DID helpers (did:web:botcha.ai:agents:<agent_id>)
|
|
9
|
+
*
|
|
10
|
+
* Standards:
|
|
11
|
+
* - W3C DID Core 1.0: https://www.w3.org/TR/did-core/
|
|
12
|
+
* - did:web method: https://w3c-ccg.github.io/did-web/
|
|
13
|
+
*/
|
|
14
|
+
// ============ CONSTANTS ============
|
|
15
|
+
const BOTCHA_DID = 'did:web:botcha.ai';
|
|
16
|
+
const DID_CORE_CONTEXT = 'https://www.w3.org/ns/did/v1';
|
|
17
|
+
const JWS_2020_CONTEXT = 'https://w3id.org/security/suites/jws-2020/v1';
|
|
18
|
+
const DID_RESOLUTION_CONTEXT = 'https://w3id.org/did-resolution/v1';
|
|
19
|
+
// ============ DID DOCUMENT GENERATION ============
|
|
20
|
+
/**
|
|
21
|
+
* Generate the canonical BOTCHA DID Document for did:web:botcha.ai.
|
|
22
|
+
*
|
|
23
|
+
* The ES256 signing key from BOTCHA's JWKS is registered as the
|
|
24
|
+
* assertionMethod — meaning VCs signed by this key are cryptographically
|
|
25
|
+
* tied to the botcha.ai DID Document.
|
|
26
|
+
*
|
|
27
|
+
* If no signing key is available (e.g. HS256-only deployment), the
|
|
28
|
+
* verificationMethod array is empty and VCs cannot be verified offline.
|
|
29
|
+
*/
|
|
30
|
+
export function generateBotchaDIDDocument(baseUrl, signingPublicKeyJwk) {
|
|
31
|
+
const keyId = `${BOTCHA_DID}#key-1`;
|
|
32
|
+
const verificationMethods = [];
|
|
33
|
+
if (signingPublicKeyJwk) {
|
|
34
|
+
verificationMethods.push({
|
|
35
|
+
id: keyId,
|
|
36
|
+
type: 'JsonWebKey2020',
|
|
37
|
+
controller: BOTCHA_DID,
|
|
38
|
+
publicKeyJwk: {
|
|
39
|
+
kty: signingPublicKeyJwk.kty || 'EC',
|
|
40
|
+
crv: signingPublicKeyJwk.crv || 'P-256',
|
|
41
|
+
x: signingPublicKeyJwk.x || '',
|
|
42
|
+
y: signingPublicKeyJwk.y || '',
|
|
43
|
+
kid: signingPublicKeyJwk.kid || 'botcha-signing-1',
|
|
44
|
+
use: 'sig',
|
|
45
|
+
alg: 'ES256',
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const authAndAssert = verificationMethods.length > 0 ? [keyId] : [];
|
|
50
|
+
return {
|
|
51
|
+
'@context': [DID_CORE_CONTEXT, JWS_2020_CONTEXT],
|
|
52
|
+
id: BOTCHA_DID,
|
|
53
|
+
controller: BOTCHA_DID,
|
|
54
|
+
verificationMethod: verificationMethods,
|
|
55
|
+
authentication: authAndAssert,
|
|
56
|
+
assertionMethod: authAndAssert,
|
|
57
|
+
service: [
|
|
58
|
+
{
|
|
59
|
+
id: `${BOTCHA_DID}#botcha-api`,
|
|
60
|
+
type: 'LinkedDomains',
|
|
61
|
+
serviceEndpoint: baseUrl,
|
|
62
|
+
description: 'BOTCHA Verification API',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: `${BOTCHA_DID}#jwks`,
|
|
66
|
+
type: 'JwkSet',
|
|
67
|
+
serviceEndpoint: `${baseUrl}/.well-known/jwks`,
|
|
68
|
+
description: 'BOTCHA JSON Web Key Set',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: `${BOTCHA_DID}#vc-issuer`,
|
|
72
|
+
type: 'CredentialIssuanceService',
|
|
73
|
+
serviceEndpoint: `${baseUrl}/v1/credentials/issue`,
|
|
74
|
+
description: 'BOTCHA Verifiable Credential Issuance',
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// ============ DID PARSING ============
|
|
80
|
+
/**
|
|
81
|
+
* Parse and validate a DID string.
|
|
82
|
+
*
|
|
83
|
+
* Valid DID format: did:method:method-specific-id
|
|
84
|
+
* - must start with "did:"
|
|
85
|
+
* - method: lowercase alphanumeric
|
|
86
|
+
* - method-specific-id: non-empty
|
|
87
|
+
*/
|
|
88
|
+
export function parseDID(did) {
|
|
89
|
+
if (!did || typeof did !== 'string') {
|
|
90
|
+
return { valid: false, error: 'DID must be a non-empty string' };
|
|
91
|
+
}
|
|
92
|
+
if (!did.startsWith('did:')) {
|
|
93
|
+
return { valid: false, error: 'DID must start with "did:"' };
|
|
94
|
+
}
|
|
95
|
+
// Split into parts: ["did", "method", "method-specific-id", ...]
|
|
96
|
+
const parts = did.split(':');
|
|
97
|
+
if (parts.length < 3) {
|
|
98
|
+
return {
|
|
99
|
+
valid: false,
|
|
100
|
+
error: 'DID must have at least 3 colon-separated parts: did:method:id',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const method = parts[1];
|
|
104
|
+
const methodSpecificId = parts.slice(2).join(':');
|
|
105
|
+
if (!method || !/^[a-z0-9]+$/.test(method)) {
|
|
106
|
+
return { valid: false, error: 'DID method must be lowercase alphanumeric' };
|
|
107
|
+
}
|
|
108
|
+
if (!methodSpecificId) {
|
|
109
|
+
return { valid: false, error: 'DID method-specific ID is empty' };
|
|
110
|
+
}
|
|
111
|
+
return { valid: true, method, methodSpecificId };
|
|
112
|
+
}
|
|
113
|
+
// ============ DID:WEB URL RESOLUTION ============
|
|
114
|
+
/**
|
|
115
|
+
* Convert a did:web DID to an HTTPS URL for DID Document fetching.
|
|
116
|
+
*
|
|
117
|
+
* Spec rules (https://w3c-ccg.github.io/did-web/):
|
|
118
|
+
* did:web:example.com → https://example.com/.well-known/did.json
|
|
119
|
+
* did:web:example.com:user:alice → https://example.com/user/alice/did.json
|
|
120
|
+
* did:web:example.com%3A8080 → https://example.com:8080/.well-known/did.json
|
|
121
|
+
*
|
|
122
|
+
* Algorithm:
|
|
123
|
+
* 1. Split the method-specific-id on unencoded ':' characters.
|
|
124
|
+
* 2. The first segment is the host — percent-decode it (e.g. %3A → ':' for port).
|
|
125
|
+
* 3. Remaining segments are path components — join with '/'.
|
|
126
|
+
*
|
|
127
|
+
* Returns null if the DID cannot be converted to a valid URL.
|
|
128
|
+
*/
|
|
129
|
+
export function didWebToUrl(did) {
|
|
130
|
+
if (!did.startsWith('did:web:'))
|
|
131
|
+
return null;
|
|
132
|
+
const suffix = did.slice('did:web:'.length);
|
|
133
|
+
if (!suffix)
|
|
134
|
+
return null;
|
|
135
|
+
// Split on literal ':' FIRST (before any percent-decoding)
|
|
136
|
+
// This correctly separates path components from the host.
|
|
137
|
+
const parts = suffix.split(':');
|
|
138
|
+
// Decode only the first segment (the host/domain — may have %3A for port)
|
|
139
|
+
const host = decodeURIComponent(parts[0]);
|
|
140
|
+
if (!host)
|
|
141
|
+
return null;
|
|
142
|
+
if (parts.length === 1) {
|
|
143
|
+
// Simple domain (possibly with decoded port): did:web:example.com or did:web:example.com%3A8080
|
|
144
|
+
return `https://${host}/.well-known/did.json`;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// Path-based: did:web:example.com:path:to:resource
|
|
148
|
+
// → https://example.com/path/to/resource/did.json
|
|
149
|
+
const pathSegments = parts.slice(1).map(decodeURIComponent);
|
|
150
|
+
const path = pathSegments.join('/');
|
|
151
|
+
return `https://${host}/${path}/did.json`;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// ============ DID:WEB RESOLUTION ============
|
|
155
|
+
/**
|
|
156
|
+
* Resolve a did:web DID by fetching its DID Document from the network.
|
|
157
|
+
*
|
|
158
|
+
* Supports:
|
|
159
|
+
* - did:web:example.com (fetches /.well-known/did.json)
|
|
160
|
+
* - did:web:example.com:path:resource (fetches /path/resource/did.json)
|
|
161
|
+
*
|
|
162
|
+
* Note: Only did:web is supported. Other methods return methodNotSupported.
|
|
163
|
+
* Cloudflare Workers support outbound fetch, so this works in production.
|
|
164
|
+
*/
|
|
165
|
+
export async function resolveDIDWeb(did) {
|
|
166
|
+
const startTime = Date.now();
|
|
167
|
+
// Parse and validate
|
|
168
|
+
const parsed = parseDID(did);
|
|
169
|
+
if (!parsed.valid) {
|
|
170
|
+
return buildError('invalidDid', parsed.error || 'Invalid DID', startTime);
|
|
171
|
+
}
|
|
172
|
+
if (parsed.method !== 'web') {
|
|
173
|
+
return buildError('methodNotSupported', `Method "${parsed.method}" is not supported. Only did:web is implemented.`, startTime);
|
|
174
|
+
}
|
|
175
|
+
const url = didWebToUrl(did);
|
|
176
|
+
if (!url) {
|
|
177
|
+
return buildError('invalidDid', 'Cannot construct resolution URL from DID', startTime);
|
|
178
|
+
}
|
|
179
|
+
// Special case: self-resolution for did:web:botcha.ai
|
|
180
|
+
// The caller should handle this by providing the local DID document instead.
|
|
181
|
+
// We still attempt the fetch to allow staging/dev environments to work.
|
|
182
|
+
try {
|
|
183
|
+
const response = await fetch(url, {
|
|
184
|
+
headers: {
|
|
185
|
+
Accept: 'application/did+ld+json, application/json',
|
|
186
|
+
'User-Agent': 'BOTCHA-DID-Resolver/1.0 (+https://botcha.ai)',
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
if (!response.ok) {
|
|
190
|
+
return buildError('notFound', `HTTP ${response.status} fetching ${url}`, startTime);
|
|
191
|
+
}
|
|
192
|
+
const contentType = response.headers.get('content-type') || 'application/json';
|
|
193
|
+
const doc = (await response.json());
|
|
194
|
+
// Validate that the resolved document's `id` matches the requested DID
|
|
195
|
+
if (doc.id && doc.id !== did) {
|
|
196
|
+
return buildError('invalidDid', `DID Document id mismatch: expected "${did}", got "${doc.id}"`, startTime);
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
'@context': DID_RESOLUTION_CONTEXT,
|
|
200
|
+
didDocument: doc,
|
|
201
|
+
didResolutionMetadata: {
|
|
202
|
+
contentType: 'application/did+ld+json',
|
|
203
|
+
retrieved: new Date().toISOString(),
|
|
204
|
+
duration: Date.now() - startTime,
|
|
205
|
+
},
|
|
206
|
+
didDocumentMetadata: {},
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
return buildError('internalError', error instanceof Error ? error.message : 'Fetch failed', startTime);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// ============ AGENT DID HELPERS ============
|
|
214
|
+
/**
|
|
215
|
+
* Build a did:web DID for a BOTCHA-registered agent.
|
|
216
|
+
* agent_abc123 → did:web:botcha.ai:agents:agent_abc123
|
|
217
|
+
*/
|
|
218
|
+
export function buildAgentDID(agentId) {
|
|
219
|
+
return `did:web:botcha.ai:agents:${agentId}`;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Extract agent_id from a BOTCHA agent DID, if applicable.
|
|
223
|
+
* Returns null if the DID is not a BOTCHA agent DID.
|
|
224
|
+
*/
|
|
225
|
+
export function parseAgentDID(did) {
|
|
226
|
+
const prefix = 'did:web:botcha.ai:agents:';
|
|
227
|
+
if (!did.startsWith(prefix))
|
|
228
|
+
return null;
|
|
229
|
+
const agentId = did.slice(prefix.length);
|
|
230
|
+
return agentId || null;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Check if a DID is a valid did:web DID (basic format validation).
|
|
234
|
+
*/
|
|
235
|
+
export function isValidDIDWeb(did) {
|
|
236
|
+
const parsed = parseDID(did);
|
|
237
|
+
if (!parsed.valid || parsed.method !== 'web')
|
|
238
|
+
return false;
|
|
239
|
+
const url = didWebToUrl(did);
|
|
240
|
+
return url !== null;
|
|
241
|
+
}
|
|
242
|
+
// ============ UTILITIES ============
|
|
243
|
+
function buildError(errorCode, message, startTime) {
|
|
244
|
+
return {
|
|
245
|
+
'@context': DID_RESOLUTION_CONTEXT,
|
|
246
|
+
didDocument: null,
|
|
247
|
+
didResolutionMetadata: {
|
|
248
|
+
error: `${errorCode}: ${message}`,
|
|
249
|
+
duration: Date.now() - startTime,
|
|
250
|
+
},
|
|
251
|
+
didDocumentMetadata: {},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
export default {
|
|
255
|
+
generateBotchaDIDDocument,
|
|
256
|
+
parseDID,
|
|
257
|
+
didWebToUrl,
|
|
258
|
+
resolveDIDWeb,
|
|
259
|
+
buildAgentDID,
|
|
260
|
+
parseAgentDID,
|
|
261
|
+
isValidDIDWeb,
|
|
262
|
+
};
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OIDC-A Attestation API Routes
|
|
3
|
+
*
|
|
4
|
+
* Routes:
|
|
5
|
+
* POST /v1/attestation/eat — Issue EAT token (RFC 9334)
|
|
6
|
+
* POST /v1/attestation/oidc-agent-claims — Issue OIDC-A claims block
|
|
7
|
+
* GET /.well-known/oauth-authorization-server — OAuth AS metadata (RFC 8414)
|
|
8
|
+
* POST /v1/auth/agent-grant — Agent Authorization Grant
|
|
9
|
+
* GET /v1/auth/agent-grant/:id/status — Poll HITL grant status
|
|
10
|
+
* POST /v1/auth/agent-grant/:id/resolve — Approve/deny HITL grant (admin)
|
|
11
|
+
* GET /v1/oidc/userinfo — OIDC-A UserInfo endpoint
|
|
12
|
+
*/
|
|
13
|
+
import type { Context } from 'hono';
|
|
14
|
+
/**
|
|
15
|
+
* POST /v1/attestation/eat
|
|
16
|
+
*
|
|
17
|
+
* Issue an RFC 9334 / draft-ietf-rats-eat-25 Entity Attestation Token.
|
|
18
|
+
*
|
|
19
|
+
* Input:
|
|
20
|
+
* Authorization: Bearer <botcha_access_token>
|
|
21
|
+
* Body (optional): {
|
|
22
|
+
* nonce?: string // Client nonce for freshness binding
|
|
23
|
+
* agent_model?: string // AI model name
|
|
24
|
+
* ttl_seconds?: number // Token TTL (max 3600)
|
|
25
|
+
* verification_method?: string
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* Output: {
|
|
29
|
+
* eat_token: string // Signed EAT JWT
|
|
30
|
+
* eat_profile: string // Profile URI
|
|
31
|
+
* expires_in: number
|
|
32
|
+
* claims: { ... } // Decoded claims (for inspection)
|
|
33
|
+
* }
|
|
34
|
+
*/
|
|
35
|
+
export declare function issueEATRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
36
|
+
success: false;
|
|
37
|
+
error: string | undefined;
|
|
38
|
+
message: string;
|
|
39
|
+
}, 401, "json">) | (Response & import("hono").TypedResponse<{
|
|
40
|
+
success: false;
|
|
41
|
+
error: string;
|
|
42
|
+
message: string;
|
|
43
|
+
}, 503, "json">) | (Response & import("hono").TypedResponse<{
|
|
44
|
+
success: false;
|
|
45
|
+
error: string;
|
|
46
|
+
message: string;
|
|
47
|
+
}, 400, "json">) | (Response & import("hono").TypedResponse<{
|
|
48
|
+
success: true;
|
|
49
|
+
eat_token: string;
|
|
50
|
+
token_type: string;
|
|
51
|
+
eat_profile: string;
|
|
52
|
+
algorithm: string;
|
|
53
|
+
expires_in: number;
|
|
54
|
+
claims: {
|
|
55
|
+
iss: string;
|
|
56
|
+
sub: string;
|
|
57
|
+
iat: number;
|
|
58
|
+
exp: number;
|
|
59
|
+
eat_profile: string;
|
|
60
|
+
oemid: string;
|
|
61
|
+
swname: string;
|
|
62
|
+
dbgstat: string;
|
|
63
|
+
intuse: string;
|
|
64
|
+
botcha_verified: true;
|
|
65
|
+
botcha_solve_time_ms: number;
|
|
66
|
+
botcha_app_id: string | undefined;
|
|
67
|
+
};
|
|
68
|
+
usage: {
|
|
69
|
+
description: string;
|
|
70
|
+
embed_as: string;
|
|
71
|
+
verify_with: string;
|
|
72
|
+
oidca_claims: string;
|
|
73
|
+
};
|
|
74
|
+
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
75
|
+
success: false;
|
|
76
|
+
error: string;
|
|
77
|
+
message: string;
|
|
78
|
+
}, 500, "json">)>;
|
|
79
|
+
/**
|
|
80
|
+
* POST /v1/attestation/oidc-agent-claims
|
|
81
|
+
*
|
|
82
|
+
* Issue OIDC-A compatible agent claims block.
|
|
83
|
+
* Enterprise auth servers call this to enrich agent ID tokens.
|
|
84
|
+
*
|
|
85
|
+
* Input:
|
|
86
|
+
* Authorization: Bearer <botcha_access_token>
|
|
87
|
+
* Body (optional): {
|
|
88
|
+
* agent_model?: string
|
|
89
|
+
* agent_version?: string
|
|
90
|
+
* agent_capabilities?: string[]
|
|
91
|
+
* agent_operator?: string
|
|
92
|
+
* delegation_chain?: string[]
|
|
93
|
+
* human_oversight_required?: boolean
|
|
94
|
+
* oversight_contact?: string
|
|
95
|
+
* task_id?: string
|
|
96
|
+
* task_purpose?: string
|
|
97
|
+
* scope?: string
|
|
98
|
+
* nonce?: string
|
|
99
|
+
* }
|
|
100
|
+
*
|
|
101
|
+
* Output: {
|
|
102
|
+
* claims_jwt: string // Signed OIDC-A claims JWT (embed in ID token)
|
|
103
|
+
* claims: OIDCAgentClaims // Decoded claims object (for direct embedding)
|
|
104
|
+
* eat_token: string // The EAT token embedded within
|
|
105
|
+
* expires_in: number
|
|
106
|
+
* }
|
|
107
|
+
*/
|
|
108
|
+
export declare function issueOIDCAgentClaimsRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
109
|
+
success: false;
|
|
110
|
+
error: string | undefined;
|
|
111
|
+
message: string;
|
|
112
|
+
}, 401, "json">) | (Response & import("hono").TypedResponse<{
|
|
113
|
+
success: false;
|
|
114
|
+
error: string;
|
|
115
|
+
message: string;
|
|
116
|
+
}, 503, "json">) | (Response & import("hono").TypedResponse<{
|
|
117
|
+
success: true;
|
|
118
|
+
claims_jwt: string;
|
|
119
|
+
token_type: string;
|
|
120
|
+
algorithm: string;
|
|
121
|
+
expires_in: number;
|
|
122
|
+
claims: {
|
|
123
|
+
agent_model: string;
|
|
124
|
+
agent_version?: string | undefined;
|
|
125
|
+
agent_capabilities: string[];
|
|
126
|
+
agent_attestation: string;
|
|
127
|
+
delegation_chain: string[];
|
|
128
|
+
agent_id: string;
|
|
129
|
+
agent_operator?: string | undefined;
|
|
130
|
+
agent_verification: {
|
|
131
|
+
method: string;
|
|
132
|
+
solve_time_ms: number;
|
|
133
|
+
verified_at: string;
|
|
134
|
+
issuer: string;
|
|
135
|
+
challenge_id: string;
|
|
136
|
+
};
|
|
137
|
+
human_oversight_required: boolean;
|
|
138
|
+
oversight_contact?: string | undefined;
|
|
139
|
+
task_id?: string | undefined;
|
|
140
|
+
task_purpose?: string | undefined;
|
|
141
|
+
iat: number;
|
|
142
|
+
exp: number;
|
|
143
|
+
iss: string;
|
|
144
|
+
};
|
|
145
|
+
eat_token: string;
|
|
146
|
+
usage: {
|
|
147
|
+
description: string;
|
|
148
|
+
embed_method_1: string;
|
|
149
|
+
embed_method_2: string;
|
|
150
|
+
embed_method_3: string;
|
|
151
|
+
verify_with: string;
|
|
152
|
+
standard: string;
|
|
153
|
+
};
|
|
154
|
+
available_capabilities: string[];
|
|
155
|
+
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
156
|
+
success: false;
|
|
157
|
+
error: string;
|
|
158
|
+
message: string;
|
|
159
|
+
}, 500, "json">)>;
|
|
160
|
+
/**
|
|
161
|
+
* GET /.well-known/oauth-authorization-server
|
|
162
|
+
*
|
|
163
|
+
* OAuth 2.0 Authorization Server Metadata (RFC 8414).
|
|
164
|
+
* Extended with OIDC-A / agent-specific metadata.
|
|
165
|
+
*
|
|
166
|
+
* No authentication required — public discovery endpoint.
|
|
167
|
+
*/
|
|
168
|
+
export declare function oauthASMetadataRoute(c: Context): Promise<Response & import("hono").TypedResponse<never, 200, "json">>;
|
|
169
|
+
/**
|
|
170
|
+
* POST /v1/auth/agent-grant
|
|
171
|
+
*
|
|
172
|
+
* Agent Authorization Grant per draft-rosenberg-oauth-aauth.
|
|
173
|
+
*
|
|
174
|
+
* An agent presents its BOTCHA token and receives a scoped OAuth grant
|
|
175
|
+
* with embedded OIDC-A claims and an EAT attestation.
|
|
176
|
+
*
|
|
177
|
+
* Input:
|
|
178
|
+
* Authorization: Bearer <botcha_access_token>
|
|
179
|
+
* Body (optional): {
|
|
180
|
+
* scope?: string // Requested scopes (space-separated)
|
|
181
|
+
* human_oversight_required?: bool // Request HITL approval flow
|
|
182
|
+
* agent_model?: string
|
|
183
|
+
* agent_version?: string
|
|
184
|
+
* agent_capabilities?: string[]
|
|
185
|
+
* agent_operator?: string
|
|
186
|
+
* task_id?: string
|
|
187
|
+
* task_purpose?: string
|
|
188
|
+
* delegation_chain?: string[]
|
|
189
|
+
* constraints?: object
|
|
190
|
+
* }
|
|
191
|
+
*
|
|
192
|
+
* Output: AgentGrantResult
|
|
193
|
+
*/
|
|
194
|
+
export declare function agentGrantRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
195
|
+
success: false;
|
|
196
|
+
error: string | undefined;
|
|
197
|
+
message: string;
|
|
198
|
+
how_to_get_token: string;
|
|
199
|
+
}, 401, "json">) | (Response & import("hono").TypedResponse<{
|
|
200
|
+
success: false;
|
|
201
|
+
error: string;
|
|
202
|
+
message: string;
|
|
203
|
+
}, 503, "json">) | (Response & import("hono").TypedResponse<{
|
|
204
|
+
success: false;
|
|
205
|
+
error: string;
|
|
206
|
+
message: string;
|
|
207
|
+
}, 400, "json">) | (Response & import("hono").TypedResponse<{
|
|
208
|
+
standard: string;
|
|
209
|
+
issued_at: string;
|
|
210
|
+
grant_type: "urn:ietf:params:oauth:grant-type:agent_authorization";
|
|
211
|
+
access_token: string;
|
|
212
|
+
token_type: "Bearer";
|
|
213
|
+
expires_in: number;
|
|
214
|
+
scope: string;
|
|
215
|
+
agent_id: string;
|
|
216
|
+
app_id?: string | undefined;
|
|
217
|
+
human_oversight_required: boolean;
|
|
218
|
+
oversight_status: "none" | "pending" | "approved" | "denied";
|
|
219
|
+
oversight_polling_url?: string | undefined;
|
|
220
|
+
agent_claims: {
|
|
221
|
+
agent_model: string;
|
|
222
|
+
agent_version?: string | undefined;
|
|
223
|
+
agent_capabilities: string[];
|
|
224
|
+
agent_attestation: string;
|
|
225
|
+
delegation_chain: string[];
|
|
226
|
+
agent_id: string;
|
|
227
|
+
agent_operator?: string | undefined;
|
|
228
|
+
agent_verification: {
|
|
229
|
+
method: string;
|
|
230
|
+
solve_time_ms: number;
|
|
231
|
+
verified_at: string;
|
|
232
|
+
issuer: string;
|
|
233
|
+
challenge_id: string;
|
|
234
|
+
};
|
|
235
|
+
human_oversight_required: boolean;
|
|
236
|
+
oversight_contact?: string | undefined;
|
|
237
|
+
task_id?: string | undefined;
|
|
238
|
+
task_purpose?: string | undefined;
|
|
239
|
+
iat: number;
|
|
240
|
+
exp: number;
|
|
241
|
+
iss: string;
|
|
242
|
+
};
|
|
243
|
+
eat_token: string;
|
|
244
|
+
success: true;
|
|
245
|
+
}, 200, "json">) | (Response & import("hono").TypedResponse<{
|
|
246
|
+
success: false;
|
|
247
|
+
error: string;
|
|
248
|
+
message: string;
|
|
249
|
+
}, 500, "json">)>;
|
|
250
|
+
/**
|
|
251
|
+
* GET /v1/auth/agent-grant/:id/status
|
|
252
|
+
*
|
|
253
|
+
* Poll the status of a human-in-the-loop pending grant.
|
|
254
|
+
* Returns current status: pending | approved | denied
|
|
255
|
+
*/
|
|
256
|
+
export declare function agentGrantStatusRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
257
|
+
success: false;
|
|
258
|
+
error: string | undefined;
|
|
259
|
+
message: string;
|
|
260
|
+
}, 401 | 403, "json">) | (Response & import("hono").TypedResponse<{
|
|
261
|
+
success: false;
|
|
262
|
+
error: string;
|
|
263
|
+
}, 400, "json">) | (Response & import("hono").TypedResponse<{
|
|
264
|
+
success: false;
|
|
265
|
+
error: string;
|
|
266
|
+
message: string;
|
|
267
|
+
}, 404, "json">) | (Response & import("hono").TypedResponse<{
|
|
268
|
+
success: true;
|
|
269
|
+
grant_id: string;
|
|
270
|
+
agent_id: string;
|
|
271
|
+
scope: string;
|
|
272
|
+
status: "approved" | "denied" | "pending";
|
|
273
|
+
requested_at: string;
|
|
274
|
+
approved_at: string | null;
|
|
275
|
+
denied_at: string | null;
|
|
276
|
+
denial_reason: string | null;
|
|
277
|
+
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
278
|
+
success: false;
|
|
279
|
+
error: string;
|
|
280
|
+
}, 500, "json">)>;
|
|
281
|
+
/**
|
|
282
|
+
* POST /v1/auth/agent-grant/:id/resolve
|
|
283
|
+
*
|
|
284
|
+
* Approve or deny a pending HITL grant.
|
|
285
|
+
* Requires app_id authentication (the grant owner must resolve it).
|
|
286
|
+
*
|
|
287
|
+
* Body: {
|
|
288
|
+
* decision: 'approved' | 'denied'
|
|
289
|
+
* reason?: string // Required if denied
|
|
290
|
+
* }
|
|
291
|
+
*/
|
|
292
|
+
export declare function agentGrantResolveRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
293
|
+
success: false;
|
|
294
|
+
error: string | undefined;
|
|
295
|
+
message: string;
|
|
296
|
+
}, 401 | 403, "json">) | (Response & import("hono").TypedResponse<{
|
|
297
|
+
success: false;
|
|
298
|
+
error: string;
|
|
299
|
+
}, 400, "json">) | (Response & import("hono").TypedResponse<{
|
|
300
|
+
success: false;
|
|
301
|
+
error: string;
|
|
302
|
+
message: string;
|
|
303
|
+
}, 404, "json">) | (Response & import("hono").TypedResponse<{
|
|
304
|
+
success: true;
|
|
305
|
+
grant_id: string;
|
|
306
|
+
decision: "approved" | "denied";
|
|
307
|
+
grant: {
|
|
308
|
+
status: "approved" | "denied" | "pending";
|
|
309
|
+
approved_at: string | null;
|
|
310
|
+
denied_at: string | null;
|
|
311
|
+
denial_reason: string | null;
|
|
312
|
+
};
|
|
313
|
+
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
314
|
+
success: false;
|
|
315
|
+
error: string;
|
|
316
|
+
}, 500, "json">)>;
|
|
317
|
+
/**
|
|
318
|
+
* GET /v1/oidc/userinfo
|
|
319
|
+
*
|
|
320
|
+
* OIDC-A compliant UserInfo endpoint for verified agents.
|
|
321
|
+
*
|
|
322
|
+
* Returns agent identity claims + BOTCHA verification status.
|
|
323
|
+
* Accepts either a BOTCHA access_token or an EAT token as Bearer.
|
|
324
|
+
*
|
|
325
|
+
* Standard OIDC UserInfo response extended with agent claims.
|
|
326
|
+
*/
|
|
327
|
+
export declare function oidcUserInfoRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
328
|
+
error: string;
|
|
329
|
+
error_description: string;
|
|
330
|
+
}, 401, "json">) | (Response & import("hono").TypedResponse<{
|
|
331
|
+
sub: string;
|
|
332
|
+
iss: string;
|
|
333
|
+
iat: number;
|
|
334
|
+
exp: number;
|
|
335
|
+
agent_id: string;
|
|
336
|
+
agent_model: string;
|
|
337
|
+
agent_capabilities: string[];
|
|
338
|
+
botcha_verified: true;
|
|
339
|
+
botcha_app_id: string | null;
|
|
340
|
+
botcha_solve_time_ms: number;
|
|
341
|
+
botcha_challenge_id: string;
|
|
342
|
+
verification: {
|
|
343
|
+
method: string;
|
|
344
|
+
verified_at: string;
|
|
345
|
+
issuer: string;
|
|
346
|
+
solve_time_ms: number;
|
|
347
|
+
};
|
|
348
|
+
attestation_endpoints: {
|
|
349
|
+
eat: string;
|
|
350
|
+
oidc_agent_claims: string;
|
|
351
|
+
agent_grant: string;
|
|
352
|
+
};
|
|
353
|
+
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
354
|
+
sub: string;
|
|
355
|
+
iss: string;
|
|
356
|
+
iat: number;
|
|
357
|
+
exp: number;
|
|
358
|
+
agent_id: string;
|
|
359
|
+
agent_model: string;
|
|
360
|
+
agent_capabilities: string[];
|
|
361
|
+
eat_profile: string;
|
|
362
|
+
ueid: string;
|
|
363
|
+
oemid: string;
|
|
364
|
+
swname: string;
|
|
365
|
+
swversion: string;
|
|
366
|
+
dbgstat: import("./tap-oidca.js").EATDebugStatus;
|
|
367
|
+
botcha_verified: true;
|
|
368
|
+
botcha_app_id: string | null;
|
|
369
|
+
botcha_solve_time_ms: number;
|
|
370
|
+
}, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
|
|
371
|
+
error: string;
|
|
372
|
+
}, 500, "json">)>;
|
|
373
|
+
declare const _default: {
|
|
374
|
+
issueEATRoute: typeof issueEATRoute;
|
|
375
|
+
issueOIDCAgentClaimsRoute: typeof issueOIDCAgentClaimsRoute;
|
|
376
|
+
oauthASMetadataRoute: typeof oauthASMetadataRoute;
|
|
377
|
+
agentGrantRoute: typeof agentGrantRoute;
|
|
378
|
+
agentGrantStatusRoute: typeof agentGrantStatusRoute;
|
|
379
|
+
agentGrantResolveRoute: typeof agentGrantResolveRoute;
|
|
380
|
+
oidcUserInfoRoute: typeof oidcUserInfoRoute;
|
|
381
|
+
};
|
|
382
|
+
export default _default;
|
|
383
|
+
//# sourceMappingURL=tap-oidca-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tap-oidca-routes.d.ts","sourceRoot":"","sources":["../src/tap-oidca-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAuFnC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA0F7C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,yBAAyB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqFzD;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,EAAE,OAAO,wEASpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAuG/C;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;kBAuDrD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;kBAoFtD;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgHjD;;;;;;;;;;AAED,wBAQC"}
|