@kya-os/contracts 1.5.3-canary.2 → 1.5.3-canary.20

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 (90) hide show
  1. package/.turbo/turbo-build.log +17 -0
  2. package/.turbo/turbo-test$colon$coverage.log +85 -0
  3. package/.turbo/turbo-test.log +32 -0
  4. package/coverage/coverage-final.json +38 -0
  5. package/dist/agentshield-api/admin-schemas.d.ts +2 -2
  6. package/dist/agentshield-api/index.d.ts +1 -1
  7. package/dist/agentshield-api/schemas.d.ts +150 -48
  8. package/dist/agentshield-api/schemas.js +32 -4
  9. package/dist/agentshield-api/types.d.ts +31 -4
  10. package/dist/audit/index.d.ts +193 -0
  11. package/dist/audit/index.js +100 -0
  12. package/dist/config/identity.d.ts +205 -2
  13. package/dist/config/identity.js +28 -0
  14. package/dist/config/index.d.ts +2 -1
  15. package/dist/config/tool-context.d.ts +34 -0
  16. package/dist/config/tool-context.js +13 -0
  17. package/dist/consent/schemas.d.ts +119 -93
  18. package/dist/consent/schemas.js +111 -64
  19. package/dist/dashboard-config/schemas.d.ts +1949 -693
  20. package/dist/handshake.d.ts +14 -14
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.js +2 -0
  23. package/dist/tool-protection/index.d.ts +430 -2
  24. package/dist/tool-protection/index.js +62 -2
  25. package/dist/verifier/index.d.ts +1 -0
  26. package/dist/verifier/index.js +18 -0
  27. package/dist/well-known/index.d.ts +2 -2
  28. package/package.json +43 -122
  29. package/schemas/cli/register-output/v1.0.0.json +69 -0
  30. package/schemas/identity/v1.0.0.json +46 -0
  31. package/schemas/proof/v1.0.0.json +80 -0
  32. package/schemas/registry/receipt-v1.0.0.json +60 -0
  33. package/schemas/verifier/verify-page/v1.0.0.json +94 -0
  34. package/schemas/well-known/agent/v1.0.0.json +67 -0
  35. package/schemas/well-known/did/v1.0.0.json +174 -0
  36. package/scripts/emit-schemas.js +11 -0
  37. package/src/agentshield-api/admin-schemas.ts +31 -0
  38. package/src/agentshield-api/admin-types.ts +47 -0
  39. package/src/agentshield-api/endpoints.ts +60 -0
  40. package/src/agentshield-api/index.ts +70 -0
  41. package/src/agentshield-api/schemas.ts +304 -0
  42. package/src/agentshield-api/types.ts +317 -0
  43. package/src/audit/index.ts +128 -0
  44. package/src/cli.ts +156 -0
  45. package/src/config/base.ts +107 -0
  46. package/src/config/builder.ts +97 -0
  47. package/src/config/delegation.ts +232 -0
  48. package/src/config/identity.ts +252 -0
  49. package/src/config/index.ts +78 -0
  50. package/src/config/proofing.ts +138 -0
  51. package/src/config/tool-context.ts +41 -0
  52. package/src/config/tool-protection.ts +174 -0
  53. package/src/consent/index.ts +32 -0
  54. package/src/consent/schemas.ts +334 -0
  55. package/src/consent/types.ts +199 -0
  56. package/src/dashboard-config/default-config.json +86 -0
  57. package/src/dashboard-config/default-config.ts +266 -0
  58. package/src/dashboard-config/index.ts +48 -0
  59. package/src/dashboard-config/schemas.ts +286 -0
  60. package/src/dashboard-config/types.ts +404 -0
  61. package/src/delegation/constraints.ts +267 -0
  62. package/src/delegation/index.ts +8 -0
  63. package/src/delegation/schemas.ts +595 -0
  64. package/src/did/index.ts +9 -0
  65. package/src/did/resolve-contract.ts +255 -0
  66. package/src/did/schemas.ts +190 -0
  67. package/src/did/types.ts +224 -0
  68. package/src/env/constants.ts +70 -0
  69. package/src/env/index.ts +5 -0
  70. package/src/handshake.ts +125 -0
  71. package/src/index.ts +45 -0
  72. package/src/proof/index.ts +31 -0
  73. package/src/proof/proof-record.ts +163 -0
  74. package/src/proof/signing-spec.ts +146 -0
  75. package/src/proof.ts +99 -0
  76. package/src/registry.ts +146 -0
  77. package/src/runtime/errors.ts +153 -0
  78. package/src/runtime/headers.ts +136 -0
  79. package/src/runtime/index.ts +6 -0
  80. package/src/test.ts +143 -0
  81. package/src/tlkrc/index.ts +5 -0
  82. package/src/tlkrc/rotation.ts +153 -0
  83. package/src/tool-protection/index.ts +343 -0
  84. package/src/utils/validation.ts +93 -0
  85. package/src/vc/index.ts +8 -0
  86. package/src/vc/schemas.ts +277 -0
  87. package/src/vc/statuslist.ts +279 -0
  88. package/src/verifier/index.ts +2 -0
  89. package/src/verifier.ts +92 -0
  90. package/src/well-known/index.ts +237 -0
@@ -0,0 +1,153 @@
1
+ /**
2
+ * TLKRC (Transparent Log Key Rotation Contract)
3
+ *
4
+ * Types for key rotation events in a transparent, auditable manner
5
+ *
6
+ * Related Spec: MCP-I Core
7
+ * Python Reference: Core-Documentation.md
8
+ */
9
+
10
+ import { z } from 'zod';
11
+
12
+ /**
13
+ * Rotation Event Schema
14
+ *
15
+ * Represents a key rotation event in a transparent log.
16
+ * Events form a hash-linked chain for auditability.
17
+ *
18
+ * **Dual-Key Grace Window:**
19
+ * During rotation, both `prevKeyId` and `nextKeyId` are valid
20
+ * from `effectiveAt` until `effectiveAt + grace period`.
21
+ */
22
+ export const RotationEventSchema = z.object({
23
+ /** DID of the issuer performing the rotation */
24
+ issuerDid: z.string().min(1),
25
+
26
+ /** Previous key ID being rotated out */
27
+ prevKeyId: z.string().min(1),
28
+
29
+ /** New key ID being rotated in */
30
+ nextKeyId: z.string().min(1),
31
+
32
+ /** Timestamp when new key becomes effective (Unix seconds) */
33
+ effectiveAt: z.number().int().positive(),
34
+
35
+ /** Timestamp when event was issued (Unix seconds) */
36
+ issuedAt: z.number().int().positive(),
37
+
38
+ /** Sequence number (monotonically increasing) */
39
+ seq: z.number().int().nonnegative(),
40
+
41
+ /** Hash of previous rotation event (null for first rotation) */
42
+ prevEventHash: z.string().optional(),
43
+
44
+ /** Signature over the event (using prevKeyId) */
45
+ signature: z.string().min(1),
46
+
47
+ /** Optional metadata */
48
+ metadata: z.record(z.any()).optional(),
49
+ }).refine(
50
+ (event) => event.effectiveAt >= event.issuedAt,
51
+ {
52
+ message: 'effectiveAt must be >= issuedAt',
53
+ }
54
+ );
55
+
56
+ export type RotationEvent = z.infer<typeof RotationEventSchema>;
57
+
58
+ /**
59
+ * Rotation Chain
60
+ *
61
+ * Represents a chain of rotation events
62
+ */
63
+ export const RotationChainSchema = z.object({
64
+ /** Issuer DID */
65
+ issuerDid: z.string().min(1),
66
+
67
+ /** All rotation events in order */
68
+ events: z.array(RotationEventSchema).min(1),
69
+
70
+ /** Current active key ID */
71
+ currentKeyId: z.string().min(1),
72
+
73
+ /** Whether chain is valid */
74
+ valid: z.boolean(),
75
+
76
+ /** Optional validation errors */
77
+ errors: z.array(z.string()).optional(),
78
+ });
79
+
80
+ export type RotationChain = z.infer<typeof RotationChainSchema>;
81
+
82
+ /**
83
+ * Validation Helpers
84
+ */
85
+
86
+ /**
87
+ * Validate a rotation event
88
+ *
89
+ * @param event - The event to validate
90
+ * @returns Validation result
91
+ */
92
+ export function validateRotationEvent(event: unknown) {
93
+ return RotationEventSchema.safeParse(event);
94
+ }
95
+
96
+ /**
97
+ * Validate rotation chain integrity
98
+ *
99
+ * @param chain - The chain to validate
100
+ * @returns true if chain is valid
101
+ */
102
+ export function isRotationChainValid(chain: RotationChain): boolean {
103
+ if (chain.events.length === 0) {
104
+ return false;
105
+ }
106
+
107
+ // Check sequence numbers are monotonic
108
+ for (let i = 1; i < chain.events.length; i++) {
109
+ if (chain.events[i].seq <= chain.events[i - 1].seq) {
110
+ return false;
111
+ }
112
+ }
113
+
114
+ return chain.valid;
115
+ }
116
+
117
+ /**
118
+ * Get active key at a specific timestamp
119
+ *
120
+ * @param chain - The rotation chain
121
+ * @param timestamp - Timestamp in seconds
122
+ * @returns Active key ID at that time, or null if none
123
+ */
124
+ export function getActiveKeyAt(chain: RotationChain, timestamp: number): string | null {
125
+ if (chain.events.length === 0) {
126
+ return null;
127
+ }
128
+
129
+ // Find the most recent event that's effective at the timestamp
130
+ for (let i = chain.events.length - 1; i >= 0; i--) {
131
+ const event = chain.events[i];
132
+ if (event.effectiveAt <= timestamp) {
133
+ return event.nextKeyId;
134
+ }
135
+ }
136
+
137
+ // If no event is effective yet, use the initial key
138
+ return chain.events[0].prevKeyId;
139
+ }
140
+
141
+ /**
142
+ * Constants
143
+ */
144
+
145
+ /**
146
+ * Default grace period for dual-key validity (24 hours)
147
+ */
148
+ export const DEFAULT_GRACE_PERIOD_SEC = 24 * 60 * 60;
149
+
150
+ /**
151
+ * Maximum reasonable grace period (30 days)
152
+ */
153
+ export const MAX_GRACE_PERIOD_SEC = 30 * 24 * 60 * 60;
@@ -0,0 +1,343 @@
1
+ /**
2
+ * MCP-I Tool Protection Specification
3
+ *
4
+ * This module defines the core tool protection types as specified in the
5
+ * MCP-I protocol. These are pure specification types that define how tools
6
+ * can be protected with delegation requirements and scopes.
7
+ *
8
+ * @module @kya-os/contracts/tool-protection
9
+ */
10
+
11
+ import { z } from 'zod';
12
+
13
+ /**
14
+ * Authorization Requirement (Discriminated Union)
15
+ *
16
+ * Defines the type of authorization required for a tool.
17
+ * Extensible design to support OAuth, MDL, IDV, credentials, etc.
18
+ */
19
+ export type AuthorizationRequirement =
20
+ | {
21
+ type: 'oauth';
22
+ provider: string; // "github", "google", etc.
23
+ requiredScopes?: string[]; // Provider-specific scopes
24
+ }
25
+ | {
26
+ type: 'mdl';
27
+ issuer: string; // MDL issuer DID or identifier
28
+ credentialType?: string; // Specific MDL credential type
29
+ }
30
+ | {
31
+ type: 'idv';
32
+ provider: string; // IDV provider name
33
+ verificationLevel?: 'basic' | 'enhanced' | 'loa3';
34
+ }
35
+ | {
36
+ type: 'credential';
37
+ credentialType: string; // Generic credential type
38
+ issuer?: string; // Optional issuer constraint
39
+ }
40
+ | {
41
+ type: 'none'; // Just consent checkbox, no external auth
42
+ };
43
+
44
+ /**
45
+ * Tool Protection Definition
46
+ *
47
+ * Defines the protection requirements for a tool as per MCP-I spec.
48
+ * This is the canonical definition that all implementations must follow.
49
+ */
50
+ export interface ToolProtection {
51
+ /**
52
+ * Whether this tool requires explicit delegation from the user
53
+ */
54
+ requiresDelegation: boolean;
55
+
56
+ /**
57
+ * The scopes required to execute this tool
58
+ * Format: "resource:action" (e.g., "files:read", "payment:send")
59
+ */
60
+ requiredScopes: string[];
61
+
62
+ /**
63
+ * Risk level classification for the tool
64
+ * Used to determine appropriate authorization flows
65
+ */
66
+ riskLevel?: 'low' | 'medium' | 'high' | 'critical';
67
+
68
+ /**
69
+ * OAuth provider name for this tool (Phase 2+)
70
+ * If specified, this tool will use the specified OAuth provider.
71
+ * If not specified, provider will be resolved via fallback strategies.
72
+ * @example "github", "google", "microsoft"
73
+ * @deprecated Use `authorization` field instead. Will be removed in Phase 3.
74
+ */
75
+ oauthProvider?: string;
76
+
77
+ /**
78
+ * Authorization requirement for this tool
79
+ * If requiresDelegation=true, authorization must be specified (or inferred from legacy fields)
80
+ */
81
+ authorization?: AuthorizationRequirement;
82
+ }
83
+
84
+ /**
85
+ * Tool Protection Map
86
+ *
87
+ * A mapping of tool names to their protection configurations.
88
+ * This is how tool protections are typically stored and transmitted.
89
+ */
90
+ export type ToolProtectionMap = Record<string, ToolProtection>;
91
+
92
+ /**
93
+ * Tool Protection Response
94
+ *
95
+ * The response format when querying for tool protections.
96
+ * Used by tool protection services and APIs.
97
+ */
98
+ export interface ToolProtectionResponse {
99
+ /**
100
+ * The tool protections keyed by tool name
101
+ */
102
+ toolProtections: ToolProtectionMap;
103
+
104
+ /**
105
+ * Optional metadata about the response
106
+ */
107
+ metadata?: {
108
+ /**
109
+ * When this configuration was last updated
110
+ */
111
+ lastUpdated?: string;
112
+
113
+ /**
114
+ * Version of the configuration
115
+ */
116
+ version?: string;
117
+
118
+ /**
119
+ * Source of the configuration
120
+ */
121
+ source?: string;
122
+ };
123
+ }
124
+
125
+ /**
126
+ * Delegation Required Error Data
127
+ *
128
+ * The standardized error data returned when a tool requires delegation
129
+ * but none was provided. This is part of the MCP-I error protocol.
130
+ */
131
+ export interface DelegationRequiredErrorData {
132
+ /**
133
+ * The name of the tool that requires delegation
134
+ */
135
+ toolName: string;
136
+
137
+ /**
138
+ * The scopes required for this tool
139
+ */
140
+ requiredScopes: string[];
141
+
142
+ /**
143
+ * URL where the user can provide consent/delegation
144
+ */
145
+ consentUrl?: string;
146
+
147
+ /**
148
+ * Alternative field for consent URL (for compatibility)
149
+ */
150
+ authorizationUrl?: string;
151
+
152
+ /**
153
+ * Additional context about why delegation is required
154
+ */
155
+ reason?: string;
156
+ }
157
+
158
+ /**
159
+ * Zod Schemas for Validation
160
+ */
161
+
162
+ export const AuthorizationRequirementSchema = z.discriminatedUnion('type', [
163
+ z.object({
164
+ type: z.literal('oauth'),
165
+ provider: z.string(),
166
+ requiredScopes: z.array(z.string()).optional(),
167
+ }),
168
+ z.object({
169
+ type: z.literal('mdl'),
170
+ issuer: z.string(),
171
+ credentialType: z.string().optional(),
172
+ }),
173
+ z.object({
174
+ type: z.literal('idv'),
175
+ provider: z.string(),
176
+ verificationLevel: z.enum(['basic', 'enhanced', 'loa3']).optional(),
177
+ }),
178
+ z.object({
179
+ type: z.literal('credential'),
180
+ credentialType: z.string(),
181
+ issuer: z.string().optional(),
182
+ }),
183
+ z.object({
184
+ type: z.literal('none'),
185
+ }),
186
+ ]);
187
+
188
+ export const ToolProtectionSchema = z.object({
189
+ requiresDelegation: z.boolean(),
190
+ requiredScopes: z.array(z.string()),
191
+ riskLevel: z.enum(['low', 'medium', 'high', 'critical']).optional(),
192
+ oauthProvider: z.string().optional(), // Phase 2: Tool-specific OAuth provider
193
+ authorization: AuthorizationRequirementSchema.optional(),
194
+ });
195
+
196
+ export const ToolProtectionMapSchema = z.record(z.string(), ToolProtectionSchema);
197
+
198
+ export const ToolProtectionResponseSchema = z.object({
199
+ toolProtections: ToolProtectionMapSchema,
200
+ metadata: z.object({
201
+ lastUpdated: z.string().optional(),
202
+ version: z.string().optional(),
203
+ source: z.string().optional()
204
+ }).optional()
205
+ });
206
+
207
+ export const DelegationRequiredErrorDataSchema = z.object({
208
+ toolName: z.string(),
209
+ requiredScopes: z.array(z.string()),
210
+ consentUrl: z.string().optional(),
211
+ authorizationUrl: z.string().optional(),
212
+ reason: z.string().optional()
213
+ });
214
+
215
+ /**
216
+ * Type Guards
217
+ */
218
+
219
+ export function isToolProtection(obj: any): obj is ToolProtection {
220
+ return ToolProtectionSchema.safeParse(obj).success;
221
+ }
222
+
223
+ export function isToolProtectionMap(obj: any): obj is ToolProtectionMap {
224
+ return ToolProtectionMapSchema.safeParse(obj).success;
225
+ }
226
+
227
+ export function isToolProtectionResponse(obj: any): obj is ToolProtectionResponse {
228
+ return ToolProtectionResponseSchema.safeParse(obj).success;
229
+ }
230
+
231
+ export function isDelegationRequiredErrorData(obj: any): obj is DelegationRequiredErrorData {
232
+ return DelegationRequiredErrorDataSchema.safeParse(obj).success;
233
+ }
234
+
235
+ /**
236
+ * Validation Functions
237
+ */
238
+
239
+ export function validateToolProtection(obj: any): ToolProtection {
240
+ return ToolProtectionSchema.parse(obj);
241
+ }
242
+
243
+ export function validateToolProtectionMap(obj: any): ToolProtectionMap {
244
+ return ToolProtectionMapSchema.parse(obj);
245
+ }
246
+
247
+ export function validateToolProtectionResponse(obj: any): ToolProtectionResponse {
248
+ return ToolProtectionResponseSchema.parse(obj);
249
+ }
250
+
251
+ export function validateDelegationRequiredErrorData(obj: any): DelegationRequiredErrorData {
252
+ return DelegationRequiredErrorDataSchema.parse(obj);
253
+ }
254
+
255
+ /**
256
+ * Utility Functions
257
+ */
258
+
259
+ /**
260
+ * Check if a tool requires delegation
261
+ */
262
+ export function toolRequiresDelegation(
263
+ toolName: string,
264
+ protections: ToolProtectionMap
265
+ ): boolean {
266
+ const protection = protections[toolName];
267
+ return protection?.requiresDelegation ?? false;
268
+ }
269
+
270
+ /**
271
+ * Get required scopes for a tool
272
+ */
273
+ export function getToolRequiredScopes(
274
+ toolName: string,
275
+ protections: ToolProtectionMap
276
+ ): string[] {
277
+ const protection = protections[toolName];
278
+ return protection?.requiredScopes ?? [];
279
+ }
280
+
281
+ /**
282
+ * Get risk level for a tool
283
+ */
284
+ export function getToolRiskLevel(
285
+ toolName: string,
286
+ protections: ToolProtectionMap
287
+ ): ToolProtection['riskLevel'] | undefined {
288
+ return protections[toolName]?.riskLevel;
289
+ }
290
+
291
+ /**
292
+ * Create a delegation required error
293
+ */
294
+ export function createDelegationRequiredError(
295
+ toolName: string,
296
+ requiredScopes: string[],
297
+ consentUrl?: string
298
+ ): DelegationRequiredErrorData {
299
+ return {
300
+ toolName,
301
+ requiredScopes,
302
+ consentUrl,
303
+ authorizationUrl: consentUrl // Include both for compatibility
304
+ };
305
+ }
306
+
307
+ /**
308
+ * Normalize tool protection configuration
309
+ * Migrates legacy oauthProvider field to authorization object
310
+ *
311
+ * // TODO: Remove normalizeToolProtection() when all tools migrated (target: Phase 3)
312
+ */
313
+ export function normalizeToolProtection(
314
+ raw: ToolProtection
315
+ ): ToolProtection {
316
+ // If authorization is already present, return as is
317
+ if (raw.authorization) {
318
+ return raw;
319
+ }
320
+
321
+ // Migrate oauthProvider to authorization
322
+ if (raw.oauthProvider) {
323
+ return {
324
+ ...raw,
325
+ authorization: {
326
+ type: 'oauth',
327
+ provider: raw.oauthProvider,
328
+ },
329
+ // Keep oauthProvider for backward compatibility until Phase 3
330
+ };
331
+ }
332
+
333
+ // Default for requiresDelegation=true without specific auth: type='none' (consent only)
334
+ // But ONLY if authorization is missing entirely
335
+ if (raw.requiresDelegation && !raw.authorization && !raw.oauthProvider) {
336
+ // We don't automatically set type='none' here to allow
337
+ // ProviderResolver to do its scope inference fallback logic.
338
+ // The fallback logic will eventually be moved into an AuthorizationService.
339
+ return raw;
340
+ }
341
+
342
+ return raw;
343
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Shared validation utilities for mcpi packages
3
+ * Consolidates common validation patterns to follow DRY principles
4
+ */
5
+
6
+ import { z } from "zod";
7
+
8
+ /**
9
+ * Generic validation result type
10
+ */
11
+ export interface ValidationResult<T = any> {
12
+ valid: boolean;
13
+ data?: T;
14
+ errors: string[];
15
+ }
16
+
17
+ /**
18
+ * Generic validation function with helpful error messages
19
+ */
20
+ export function validateInput<T>(
21
+ schema: z.ZodSchema<T>,
22
+ data: unknown,
23
+ context?: string
24
+ ): ValidationResult<T> {
25
+ const result = schema.safeParse(data);
26
+
27
+ if (result.success) {
28
+ return {
29
+ valid: true,
30
+ data: result.data,
31
+ errors: [],
32
+ };
33
+ }
34
+
35
+ const errors = result.error.errors.map((err) => {
36
+ const path = err.path.length > 0 ? ` at ${err.path.join(".")}` : "";
37
+ const contextStr = context ? ` (${context})` : "";
38
+ return `${err.message}${path}${contextStr}`;
39
+ });
40
+
41
+ return {
42
+ valid: false,
43
+ errors,
44
+ };
45
+ }
46
+
47
+ /**
48
+ * Validate object has required properties
49
+ */
50
+ export function hasRequiredProperties(
51
+ obj: any,
52
+ properties: string[],
53
+ context?: string
54
+ ): ValidationResult {
55
+ if (typeof obj !== "object" || obj === null) {
56
+ return {
57
+ valid: false,
58
+ errors: [`Expected object${context ? ` for ${context}` : ""}`],
59
+ };
60
+ }
61
+
62
+ const missing = properties.filter((prop) => !(prop in obj));
63
+
64
+ if (missing.length > 0) {
65
+ return {
66
+ valid: false,
67
+ errors: [
68
+ `Missing required properties: ${missing.join(", ")}${context ? ` in ${context}` : ""}`,
69
+ ],
70
+ };
71
+ }
72
+
73
+ return { valid: true, errors: [] };
74
+ }
75
+
76
+ /**
77
+ * Validate string format patterns
78
+ */
79
+ export const StringValidators = {
80
+ did: (value: string): boolean =>
81
+ /^did:[a-z0-9]+:[a-zA-Z0-9._-]+$/.test(value),
82
+ kid: (value: string): boolean => /^[a-zA-Z0-9._-]+$/.test(value),
83
+ url: (value: string): boolean => {
84
+ try {
85
+ new URL(value);
86
+ return true;
87
+ } catch {
88
+ return false;
89
+ }
90
+ },
91
+ projectName: (value: string): boolean =>
92
+ /^[a-z0-9-]+$/.test(value) && value.length >= 1 && value.length <= 214,
93
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Verifiable Credentials Module Exports
3
+ *
4
+ * W3C Verifiable Credentials types, schemas, and utilities
5
+ */
6
+
7
+ export * from './schemas.js';
8
+ export * from './statuslist.js';