@kya-os/contracts 1.5.3-canary.21 → 1.5.3-canary.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/consent/schemas.d.ts +149 -77
- package/dist/consent/schemas.js +29 -2
- package/package.json +23 -1
- package/.turbo/turbo-build.log +0 -17
- package/.turbo/turbo-test$colon$coverage.log +0 -85
- package/.turbo/turbo-test.log +0 -32
- package/coverage/coverage-final.json +0 -38
- package/schemas/cli/register-output/v1.0.0.json +0 -69
- package/schemas/identity/v1.0.0.json +0 -46
- package/schemas/proof/v1.0.0.json +0 -80
- package/schemas/registry/receipt-v1.0.0.json +0 -60
- package/schemas/verifier/verify-page/v1.0.0.json +0 -94
- package/schemas/well-known/agent/v1.0.0.json +0 -67
- package/schemas/well-known/did/v1.0.0.json +0 -174
- package/scripts/emit-schemas.js +0 -11
- package/src/agentshield-api/admin-schemas.ts +0 -31
- package/src/agentshield-api/admin-types.ts +0 -47
- package/src/agentshield-api/endpoints.ts +0 -60
- package/src/agentshield-api/index.ts +0 -70
- package/src/agentshield-api/schemas.ts +0 -304
- package/src/agentshield-api/types.ts +0 -317
- package/src/audit/index.ts +0 -128
- package/src/cli.ts +0 -156
- package/src/config/base.ts +0 -107
- package/src/config/builder.ts +0 -97
- package/src/config/delegation.ts +0 -232
- package/src/config/identity.ts +0 -252
- package/src/config/index.ts +0 -78
- package/src/config/proofing.ts +0 -138
- package/src/config/tool-context.ts +0 -41
- package/src/config/tool-protection.ts +0 -174
- package/src/consent/index.ts +0 -32
- package/src/consent/schemas.ts +0 -334
- package/src/consent/types.ts +0 -199
- package/src/dashboard-config/default-config.json +0 -86
- package/src/dashboard-config/default-config.ts +0 -266
- package/src/dashboard-config/index.ts +0 -48
- package/src/dashboard-config/schemas.ts +0 -286
- package/src/dashboard-config/types.ts +0 -404
- package/src/delegation/constraints.ts +0 -267
- package/src/delegation/index.ts +0 -8
- package/src/delegation/schemas.ts +0 -595
- package/src/did/index.ts +0 -9
- package/src/did/resolve-contract.ts +0 -255
- package/src/did/schemas.ts +0 -190
- package/src/did/types.ts +0 -224
- package/src/env/constants.ts +0 -70
- package/src/env/index.ts +0 -5
- package/src/handshake.ts +0 -125
- package/src/index.ts +0 -45
- package/src/proof/index.ts +0 -31
- package/src/proof/proof-record.ts +0 -163
- package/src/proof/signing-spec.ts +0 -146
- package/src/proof.ts +0 -99
- package/src/registry.ts +0 -146
- package/src/runtime/errors.ts +0 -153
- package/src/runtime/headers.ts +0 -136
- package/src/runtime/index.ts +0 -6
- package/src/test.ts +0 -143
- package/src/tlkrc/index.ts +0 -5
- package/src/tlkrc/rotation.ts +0 -153
- package/src/tool-protection/index.ts +0 -406
- package/src/utils/validation.ts +0 -93
- package/src/vc/index.ts +0 -8
- package/src/vc/schemas.ts +0 -277
- package/src/vc/statuslist.ts +0 -279
- package/src/verifier/index.ts +0 -2
- package/src/verifier.ts +0 -92
- package/src/well-known/index.ts +0 -237
|
@@ -1,404 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dashboard Configuration Types
|
|
3
|
-
*
|
|
4
|
-
* Type definitions for AgentShield dashboard server configuration management API.
|
|
5
|
-
* These types ensure parity between xmcp-i and AgentShield dashboard implementations.
|
|
6
|
-
*
|
|
7
|
-
* @package @kya-os/contracts/dashboard-config
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import type { ToolProtectionMap } from '../tool-protection/index.js';
|
|
11
|
-
import type { ProofDestination } from '../config/proofing.js';
|
|
12
|
-
import type { DelegationVerifierType } from '../config/delegation.js';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* MCP-I Server Configuration (Dashboard View Model)
|
|
16
|
-
*
|
|
17
|
-
* This is a flattened, UI-friendly representation of server configuration
|
|
18
|
-
* used by the AgentShield dashboard for configuration management.
|
|
19
|
-
*
|
|
20
|
-
* This type differs from MCPIConfig in that it:
|
|
21
|
-
* - Includes platform-specific details
|
|
22
|
-
* - Includes read-only metadata
|
|
23
|
-
* - Flattens nested structures for easier UI rendering
|
|
24
|
-
* - Includes deployment status information
|
|
25
|
-
*/
|
|
26
|
-
export interface MCPIServerConfig {
|
|
27
|
-
// ============================================
|
|
28
|
-
// 1. IDENTITY CONFIGURATION
|
|
29
|
-
// ============================================
|
|
30
|
-
identity: {
|
|
31
|
-
/**
|
|
32
|
-
* MCP-I Server DID (public identifier)
|
|
33
|
-
* Identifies this server instance
|
|
34
|
-
* @deprecated Use serverDid instead. Will be removed in v2.0
|
|
35
|
-
*/
|
|
36
|
-
agentDid?: string;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* MCP-I Server DID (public identifier)
|
|
40
|
-
* Identifies this server instance
|
|
41
|
-
* Read-only, displayed for reference
|
|
42
|
-
*/
|
|
43
|
-
serverDid: string;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Environment mode
|
|
47
|
-
* Controls identity source: 'development' | 'production'
|
|
48
|
-
*/
|
|
49
|
-
environment: 'development' | 'production';
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Identity storage location (read-only)
|
|
53
|
-
* Shows where identity is stored based on platform
|
|
54
|
-
*/
|
|
55
|
-
storageLocation: 'cloudflare-kv' | 'file-system' | 'env-vars';
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// ============================================
|
|
59
|
-
// 2. PROOFING CONFIGURATION
|
|
60
|
-
// ============================================
|
|
61
|
-
proofing: {
|
|
62
|
-
/**
|
|
63
|
-
* Enable proof submission
|
|
64
|
-
*/
|
|
65
|
-
enabled: boolean;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Proof destinations
|
|
69
|
-
* Where proofs are sent (AgentShield, KTA, etc.)
|
|
70
|
-
*/
|
|
71
|
-
destinations: Array<{
|
|
72
|
-
type: 'agentshield' | 'kta' | 'custom';
|
|
73
|
-
apiUrl: string;
|
|
74
|
-
apiKey?: string; // Masked, only show if user has permission
|
|
75
|
-
}>;
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Batch queue settings
|
|
79
|
-
*/
|
|
80
|
-
batchQueue: {
|
|
81
|
-
maxBatchSize: number; // Default: 10
|
|
82
|
-
flushIntervalMs: number; // Default: 5000
|
|
83
|
-
maxRetries: number; // Default: 3
|
|
84
|
-
};
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// ============================================
|
|
88
|
-
// 3. DELEGATION CONFIGURATION
|
|
89
|
-
// ============================================
|
|
90
|
-
delegation: {
|
|
91
|
-
/**
|
|
92
|
-
* Enable delegation enforcement
|
|
93
|
-
*/
|
|
94
|
-
enabled: boolean;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Strict enforcement mode
|
|
98
|
-
* When true, blocks tools without delegation
|
|
99
|
-
* When false, logs warnings but allows execution
|
|
100
|
-
*/
|
|
101
|
-
enforceStrictly: boolean;
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Delegation verifier settings
|
|
105
|
-
*/
|
|
106
|
-
verifier: {
|
|
107
|
-
type: DelegationVerifierType;
|
|
108
|
-
apiUrl?: string;
|
|
109
|
-
cacheTtl?: number; // Default: 300000 (5 minutes)
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Authorization flow settings
|
|
114
|
-
*/
|
|
115
|
-
authorization: {
|
|
116
|
-
authorizationUrl?: string;
|
|
117
|
-
minReputationScore?: number; // 0-100, default: 80
|
|
118
|
-
resumeTokenTtl?: number; // milliseconds, default: 3600000
|
|
119
|
-
requireAuthForUnknown?: boolean;
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
// ============================================
|
|
124
|
-
// 4. TOOL PROTECTION CONFIGURATION
|
|
125
|
-
// ============================================
|
|
126
|
-
toolProtection: {
|
|
127
|
-
/**
|
|
128
|
-
* Source of tool protection config
|
|
129
|
-
* 'agentshield' = Fetched from AgentShield API (dashboard-controlled)
|
|
130
|
-
* 'inline' = Defined in code/config file
|
|
131
|
-
* 'file' = Loaded from external file
|
|
132
|
-
*/
|
|
133
|
-
source: 'agentshield' | 'inline' | 'file';
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* AgentShield API settings (if source is 'agentshield')
|
|
137
|
-
*/
|
|
138
|
-
agentShield?: {
|
|
139
|
-
apiUrl: string; // Default: 'https://kya.vouched.id'
|
|
140
|
-
cacheTtl: number; // Default: 300000 (5 minutes)
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Fallback configuration
|
|
145
|
-
* Used when API is unavailable
|
|
146
|
-
* Displayed as read-only (managed via /tools page)
|
|
147
|
-
*/
|
|
148
|
-
fallback?: ToolProtectionMap;
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// ============================================
|
|
152
|
-
// 5. AUDIT & LOGGING
|
|
153
|
-
// ============================================
|
|
154
|
-
audit: {
|
|
155
|
-
/**
|
|
156
|
-
* Enable audit logging
|
|
157
|
-
*/
|
|
158
|
-
enabled: boolean;
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Include proof hashes in logs
|
|
162
|
-
*/
|
|
163
|
-
includeProofHashes: boolean;
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Include full payloads in logs
|
|
167
|
-
* WARNING: May include sensitive data
|
|
168
|
-
*/
|
|
169
|
-
includePayloads: boolean;
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
// ============================================
|
|
173
|
-
// 6. SESSION CONFIGURATION
|
|
174
|
-
// ============================================
|
|
175
|
-
session: {
|
|
176
|
-
/**
|
|
177
|
-
* Maximum time skew allowed (seconds)
|
|
178
|
-
* Default: 120
|
|
179
|
-
*/
|
|
180
|
-
timestampSkewSeconds: number;
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Session TTL (minutes)
|
|
184
|
-
* Default: 30
|
|
185
|
-
*/
|
|
186
|
-
ttlMinutes: number;
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Absolute session lifetime (minutes)
|
|
190
|
-
* Optional, max lifetime regardless of activity
|
|
191
|
-
*/
|
|
192
|
-
absoluteLifetime?: number;
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
// ============================================
|
|
196
|
-
// 7. PLATFORM-SPECIFIC CONFIGURATION
|
|
197
|
-
// ============================================
|
|
198
|
-
platform: {
|
|
199
|
-
/**
|
|
200
|
-
* Platform type
|
|
201
|
-
*/
|
|
202
|
-
type: 'cloudflare' | 'node' | 'vercel';
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Cloudflare-specific settings
|
|
206
|
-
*/
|
|
207
|
-
cloudflare?: {
|
|
208
|
-
/**
|
|
209
|
-
* Workers runtime settings
|
|
210
|
-
*/
|
|
211
|
-
workers: {
|
|
212
|
-
cpuMs: number; // Default: 50
|
|
213
|
-
memoryMb: number; // Default: 128
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* KV namespace bindings (read-only)
|
|
218
|
-
* Shows which KV namespaces are configured
|
|
219
|
-
*/
|
|
220
|
-
kvNamespaces: Array<{
|
|
221
|
-
name: string;
|
|
222
|
-
purpose: 'sessions' | 'delegations' | 'cache' | 'general';
|
|
223
|
-
}>;
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Environment variables (masked)
|
|
227
|
-
*/
|
|
228
|
-
environmentVariables: Array<{
|
|
229
|
-
name: string;
|
|
230
|
-
value: string; // Masked (e.g., "sk_***")
|
|
231
|
-
source: 'wrangler.toml' | 'secrets' | '.dev.vars';
|
|
232
|
-
}>;
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Node.js-specific settings
|
|
237
|
-
*/
|
|
238
|
-
node?: {
|
|
239
|
-
/**
|
|
240
|
-
* Server configuration
|
|
241
|
-
*/
|
|
242
|
-
server: {
|
|
243
|
-
port: number; // Default: 3000
|
|
244
|
-
host: string; // Default: '0.0.0.0'
|
|
245
|
-
cors: boolean; // Default: true
|
|
246
|
-
timeout: number; // Default: 30000
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Storage configuration
|
|
251
|
-
*/
|
|
252
|
-
storage: {
|
|
253
|
-
type: 'memory' | 'redis' | 'postgres' | 'mongodb';
|
|
254
|
-
connection?: {
|
|
255
|
-
host?: string;
|
|
256
|
-
port?: number;
|
|
257
|
-
database?: string;
|
|
258
|
-
};
|
|
259
|
-
};
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Vercel-specific settings
|
|
264
|
-
*/
|
|
265
|
-
vercel?: {
|
|
266
|
-
/**
|
|
267
|
-
* Environment variables (masked)
|
|
268
|
-
*/
|
|
269
|
-
environmentVariables: Array<{
|
|
270
|
-
name: string;
|
|
271
|
-
value: string; // Masked
|
|
272
|
-
source: 'vercel-dashboard' | '.env.local';
|
|
273
|
-
}>;
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Edge runtime configuration
|
|
277
|
-
*/
|
|
278
|
-
edgeRuntime?: {
|
|
279
|
-
maxDuration?: number;
|
|
280
|
-
regions?: string[];
|
|
281
|
-
};
|
|
282
|
-
};
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
// ============================================
|
|
286
|
-
// 8. METADATA
|
|
287
|
-
// ============================================
|
|
288
|
-
metadata: {
|
|
289
|
-
/**
|
|
290
|
-
* Configuration version
|
|
291
|
-
*/
|
|
292
|
-
version: string;
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Last updated timestamp
|
|
296
|
-
*/
|
|
297
|
-
lastUpdated: string;
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Configuration source
|
|
301
|
-
* 'dashboard' = Managed via AgentShield dashboard
|
|
302
|
-
* 'code' = Defined in code (mcpi-runtime-config.ts)
|
|
303
|
-
* 'mixed' = Partially managed via dashboard
|
|
304
|
-
*/
|
|
305
|
-
source: 'dashboard' | 'code' | 'mixed';
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Server deployment URL
|
|
309
|
-
*/
|
|
310
|
-
serverUrl?: string;
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Server deployment status
|
|
314
|
-
*/
|
|
315
|
-
deploymentStatus?: 'active' | 'inactive' | 'error';
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* API Request/Response types for dashboard config endpoints
|
|
321
|
-
*/
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Request to get server configuration
|
|
325
|
-
* GET /api/v1/bouncer/projects/{projectId}/config
|
|
326
|
-
*/
|
|
327
|
-
export interface GetServerConfigRequest {
|
|
328
|
-
projectId: string;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Response from get server configuration endpoint
|
|
333
|
-
*/
|
|
334
|
-
export interface GetServerConfigResponse {
|
|
335
|
-
success: boolean;
|
|
336
|
-
data: {
|
|
337
|
-
config: MCPIServerConfig;
|
|
338
|
-
};
|
|
339
|
-
metadata?: {
|
|
340
|
-
requestId?: string;
|
|
341
|
-
timestamp?: string;
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Request to update server configuration
|
|
347
|
-
* PUT /api/v1/bouncer/projects/{projectId}/config
|
|
348
|
-
*/
|
|
349
|
-
export interface UpdateServerConfigRequest {
|
|
350
|
-
projectId: string;
|
|
351
|
-
config: Partial<MCPIServerConfig>;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Response from update server configuration endpoint
|
|
356
|
-
*/
|
|
357
|
-
export interface UpdateServerConfigResponse {
|
|
358
|
-
success: boolean;
|
|
359
|
-
data: {
|
|
360
|
-
config: MCPIServerConfig;
|
|
361
|
-
changes: Array<{
|
|
362
|
-
path: string;
|
|
363
|
-
oldValue: unknown;
|
|
364
|
-
newValue: unknown;
|
|
365
|
-
}>;
|
|
366
|
-
};
|
|
367
|
-
metadata?: {
|
|
368
|
-
requestId?: string;
|
|
369
|
-
timestamp?: string;
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Request to validate server configuration without saving
|
|
375
|
-
* POST /api/v1/bouncer/projects/{projectId}/config/validate
|
|
376
|
-
*/
|
|
377
|
-
export interface ValidateServerConfigRequest {
|
|
378
|
-
projectId: string;
|
|
379
|
-
config: Partial<MCPIServerConfig>;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Response from validate server configuration endpoint
|
|
384
|
-
*/
|
|
385
|
-
export interface ValidateServerConfigResponse {
|
|
386
|
-
success: boolean;
|
|
387
|
-
data: {
|
|
388
|
-
valid: boolean;
|
|
389
|
-
errors?: Array<{
|
|
390
|
-
path: string;
|
|
391
|
-
message: string;
|
|
392
|
-
code: string;
|
|
393
|
-
}>;
|
|
394
|
-
warnings?: Array<{
|
|
395
|
-
path: string;
|
|
396
|
-
message: string;
|
|
397
|
-
}>;
|
|
398
|
-
};
|
|
399
|
-
metadata?: {
|
|
400
|
-
requestId?: string;
|
|
401
|
-
timestamp?: string;
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
|
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CRISP Delegation Constraints
|
|
3
|
-
*
|
|
4
|
-
* Types and schemas for CRISP (Constrained Resource Intent Specification Protocol)
|
|
5
|
-
* constraints on delegations. CRISP enables fine-grained authorization control.
|
|
6
|
-
*
|
|
7
|
-
* Related Spec: MCP-I §4.2
|
|
8
|
-
* Python Reference: Delegation-Documentation.md
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { z } from 'zod';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Currency types for CRISP budgets
|
|
15
|
-
*/
|
|
16
|
-
export const CurrencySchema = z.enum(['USD', 'ops', 'points']);
|
|
17
|
-
export type Currency = z.infer<typeof CurrencySchema>;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Window kind for budget enforcement
|
|
21
|
-
*/
|
|
22
|
-
export const WindowKindSchema = z.enum(['rolling', 'fixed']);
|
|
23
|
-
export type WindowKind = z.infer<typeof WindowKindSchema>;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Budget Window Schema
|
|
27
|
-
*
|
|
28
|
-
* Defines the time window for budget enforcement
|
|
29
|
-
*/
|
|
30
|
-
export const BudgetWindowSchema = z.object({
|
|
31
|
-
/** Type of window (rolling or fixed) */
|
|
32
|
-
kind: WindowKindSchema,
|
|
33
|
-
|
|
34
|
-
/** Duration in seconds */
|
|
35
|
-
durationSec: z.number().int().positive(),
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
export type BudgetWindow = z.infer<typeof BudgetWindowSchema>;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* CRISP Budget Schema
|
|
42
|
-
*
|
|
43
|
-
* Defines spending/usage limits for a delegation
|
|
44
|
-
*/
|
|
45
|
-
export const CrispBudgetSchema = z.object({
|
|
46
|
-
/** Unit of the budget */
|
|
47
|
-
unit: CurrencySchema,
|
|
48
|
-
|
|
49
|
-
/** Cap/limit for the budget */
|
|
50
|
-
cap: z.number().nonnegative(),
|
|
51
|
-
|
|
52
|
-
/** Optional time window for the budget */
|
|
53
|
-
window: BudgetWindowSchema.optional(),
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
export type CrispBudget = z.infer<typeof CrispBudgetSchema>;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Scope matcher types
|
|
60
|
-
*/
|
|
61
|
-
export const ScopeMatcherSchema = z.enum(['exact', 'prefix', 'regex']);
|
|
62
|
-
export type ScopeMatcher = z.infer<typeof ScopeMatcherSchema>;
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* CRISP Scope Schema
|
|
66
|
-
*
|
|
67
|
-
* Defines what resources/actions are allowed in a delegation
|
|
68
|
-
*/
|
|
69
|
-
export const CrispScopeSchema = z.object({
|
|
70
|
-
/** Resource identifier (e.g., "api:users", "data:emails") */
|
|
71
|
-
resource: z.string().min(1),
|
|
72
|
-
|
|
73
|
-
/** How to match the resource */
|
|
74
|
-
matcher: ScopeMatcherSchema,
|
|
75
|
-
|
|
76
|
-
/** Optional additional constraints on this scope */
|
|
77
|
-
constraints: z.record(z.any()).optional(),
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
export type CrispScope = z.infer<typeof CrispScopeSchema>;
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Delegation Constraints Schema (CRISP)
|
|
84
|
-
*
|
|
85
|
-
* Complete constraint specification for a delegation
|
|
86
|
-
*/
|
|
87
|
-
export const DelegationConstraintsSchema = z.object({
|
|
88
|
-
/** Not valid before (Unix timestamp in seconds) */
|
|
89
|
-
notBefore: z.number().int().optional(),
|
|
90
|
-
|
|
91
|
-
/** Not valid after (Unix timestamp in seconds) */
|
|
92
|
-
notAfter: z.number().int().optional(),
|
|
93
|
-
|
|
94
|
-
/** Simple scopes array (for Phase 1 bouncer - simplified model) */
|
|
95
|
-
scopes: z.array(z.string()).optional(),
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Optional target server DID(s) for this delegation
|
|
99
|
-
* If omitted, delegation is valid on any server accepting the scopes
|
|
100
|
-
* If specified, delegation is only valid on the specified server(s)
|
|
101
|
-
*/
|
|
102
|
-
audience: z.union([
|
|
103
|
-
z.string().startsWith("did:"),
|
|
104
|
-
z.array(z.string().startsWith("did:"))
|
|
105
|
-
]).optional(),
|
|
106
|
-
|
|
107
|
-
/** CRISP-specific constraints (full model) */
|
|
108
|
-
crisp: z.object({
|
|
109
|
-
/** Optional budget constraint */
|
|
110
|
-
budget: CrispBudgetSchema.optional(),
|
|
111
|
-
|
|
112
|
-
/** Required: at least one scope */
|
|
113
|
-
scopes: z.array(CrispScopeSchema).min(1),
|
|
114
|
-
|
|
115
|
-
/** Optional additional CRISP fields */
|
|
116
|
-
}).passthrough().optional(),
|
|
117
|
-
}).passthrough(); // Allow extensibility
|
|
118
|
-
|
|
119
|
-
export type DelegationConstraints = z.infer<typeof DelegationConstraintsSchema>;
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Validation Helpers
|
|
123
|
-
*/
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Validate delegation constraints
|
|
127
|
-
*
|
|
128
|
-
* @param constraints - The constraints to validate
|
|
129
|
-
* @returns Validation result
|
|
130
|
-
*/
|
|
131
|
-
export function validateDelegationConstraints(constraints: unknown) {
|
|
132
|
-
return DelegationConstraintsSchema.safeParse(constraints);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Check if constraints have a valid time range
|
|
137
|
-
*
|
|
138
|
-
* @param constraints - The constraints to check
|
|
139
|
-
* @returns true if time range is valid or no time range specified
|
|
140
|
-
*/
|
|
141
|
-
export function hasValidTimeRange(constraints: DelegationConstraints): boolean {
|
|
142
|
-
if (constraints.notBefore === undefined && constraints.notAfter === undefined) {
|
|
143
|
-
return true;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (constraints.notBefore !== undefined && constraints.notAfter !== undefined) {
|
|
147
|
-
return constraints.notBefore < constraints.notAfter;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Check if child constraints are within parent constraints
|
|
155
|
-
*
|
|
156
|
-
* This performs basic structural checks. Full chain validation
|
|
157
|
-
* requires runtime implementation.
|
|
158
|
-
*
|
|
159
|
-
* @param parent - Parent delegation constraints
|
|
160
|
-
* @param child - Child delegation constraints
|
|
161
|
-
* @returns true if child is within parent bounds
|
|
162
|
-
*/
|
|
163
|
-
export function areChildConstraintsValid(
|
|
164
|
-
parent: DelegationConstraints,
|
|
165
|
-
child: DelegationConstraints
|
|
166
|
-
): boolean {
|
|
167
|
-
// Time bounds: child must be within parent
|
|
168
|
-
if (parent.notBefore !== undefined && child.notBefore !== undefined) {
|
|
169
|
-
if (child.notBefore < parent.notBefore) {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (parent.notAfter !== undefined && child.notAfter !== undefined) {
|
|
175
|
-
if (child.notAfter > parent.notAfter) {
|
|
176
|
-
return false;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Budget: child must be ≤ parent (if same unit)
|
|
181
|
-
if (
|
|
182
|
-
parent.crisp?.budget &&
|
|
183
|
-
child.crisp?.budget &&
|
|
184
|
-
parent.crisp.budget.unit === child.crisp.budget.unit
|
|
185
|
-
) {
|
|
186
|
-
if (child.crisp.budget.cap > parent.crisp.budget.cap) {
|
|
187
|
-
return false;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Scopes: child scopes must be subset of parent scopes
|
|
192
|
-
// This is a simplified check - full validation is complex
|
|
193
|
-
if (parent.crisp && child.crisp) {
|
|
194
|
-
const parentResources = new Set(
|
|
195
|
-
parent.crisp.scopes.map((s) => s.resource)
|
|
196
|
-
);
|
|
197
|
-
const allChildResourcesInParent = child.crisp.scopes.every((childScope) => {
|
|
198
|
-
// Check if child resource matches any parent resource
|
|
199
|
-
return parent.crisp!.scopes.some((parentScope) => {
|
|
200
|
-
if (parentScope.matcher === 'exact') {
|
|
201
|
-
return parentScope.resource === childScope.resource;
|
|
202
|
-
}
|
|
203
|
-
if (parentScope.matcher === 'prefix') {
|
|
204
|
-
return childScope.resource.startsWith(parentScope.resource);
|
|
205
|
-
}
|
|
206
|
-
// regex matching would require runtime regex evaluation
|
|
207
|
-
return true; // Can't validate regex at type level
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
return allChildResourcesInParent;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return true; // Can't validate if crisp is not present
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Check if a resource matches a scope
|
|
219
|
-
*
|
|
220
|
-
* @param resource - The resource to check
|
|
221
|
-
* @param scope - The scope to match against
|
|
222
|
-
* @returns true if resource matches scope
|
|
223
|
-
*/
|
|
224
|
-
export function doesResourceMatchScope(
|
|
225
|
-
resource: string,
|
|
226
|
-
scope: CrispScope
|
|
227
|
-
): boolean {
|
|
228
|
-
switch (scope.matcher) {
|
|
229
|
-
case 'exact':
|
|
230
|
-
return resource === scope.resource;
|
|
231
|
-
case 'prefix':
|
|
232
|
-
return resource.startsWith(scope.resource);
|
|
233
|
-
case 'regex':
|
|
234
|
-
try {
|
|
235
|
-
const regex = new RegExp(scope.resource);
|
|
236
|
-
return regex.test(resource);
|
|
237
|
-
} catch {
|
|
238
|
-
return false;
|
|
239
|
-
}
|
|
240
|
-
default:
|
|
241
|
-
return false;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Constants
|
|
247
|
-
*/
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Supported currency types
|
|
251
|
-
*/
|
|
252
|
-
export const SUPPORTED_CURRENCIES: Currency[] = ['USD', 'ops', 'points'];
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Supported scope matchers
|
|
256
|
-
*/
|
|
257
|
-
export const SUPPORTED_MATCHERS: ScopeMatcher[] = ['exact', 'prefix', 'regex'];
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Maximum reasonable budget cap (for validation)
|
|
261
|
-
*/
|
|
262
|
-
export const MAX_BUDGET_CAP = Number.MAX_SAFE_INTEGER;
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Maximum reasonable window duration (10 years in seconds)
|
|
266
|
-
*/
|
|
267
|
-
export const MAX_WINDOW_DURATION_SEC = 10 * 365 * 24 * 60 * 60;
|