@kya-os/contracts 1.7.2 → 1.7.4

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.
@@ -2,20 +2,23 @@
2
2
  /**
3
3
  * MCP-I Tool Protection Specification
4
4
  *
5
- * This module defines the core tool protection types as specified in the
6
- * MCP-I protocol. These are pure specification types that define how tools
7
- * can be protected with delegation requirements and scopes.
5
+ * Core types for tool protection with delegation requirements.
6
+ *
7
+ * Consent Flow: type='none' 2 screens, others → 3 screens (Auth→Consent→Success).
8
+ * DelegationCredential (VC) is created when user confirms on Consent Screen.
8
9
  *
9
10
  * @module @kya-os/contracts/tool-protection
10
11
  */
11
12
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.DelegationRequiredErrorDataSchema = exports.ToolProtectionResponseSchema = exports.ToolProtectionMapSchema = exports.ToolProtectionSchema = exports.AuthorizationRequirementSchema = void 0;
13
+ exports.CONSENT_PROVIDER_TYPES = exports.DelegationRequiredErrorDataSchema = exports.ToolProtectionResponseSchema = exports.ToolProtectionMapSchema = exports.ToolProtectionSchema = exports.AuthorizationRequirementSchema = exports.AUTHORIZATION_TYPES = void 0;
13
14
  exports.isToolProtection = isToolProtection;
14
15
  exports.isToolProtectionMap = isToolProtectionMap;
15
16
  exports.isToolProtectionResponse = isToolProtectionResponse;
16
17
  exports.isDelegationRequiredErrorData = isDelegationRequiredErrorData;
17
18
  exports.isAuthorizationRequirement = isAuthorizationRequirement;
18
19
  exports.hasOAuthAuthorization = hasOAuthAuthorization;
20
+ exports.hasPasswordAuthorization = hasPasswordAuthorization;
21
+ exports.hasVerifiableCredentialAuthorization = hasVerifiableCredentialAuthorization;
19
22
  exports.validateToolProtection = validateToolProtection;
20
23
  exports.validateToolProtectionMap = validateToolProtectionMap;
21
24
  exports.validateToolProtectionResponse = validateToolProtectionResponse;
@@ -25,7 +28,23 @@ exports.getToolRequiredScopes = getToolRequiredScopes;
25
28
  exports.getToolRiskLevel = getToolRiskLevel;
26
29
  exports.createDelegationRequiredError = createDelegationRequiredError;
27
30
  exports.normalizeToolProtection = normalizeToolProtection;
31
+ exports.determineConsentProviderType = determineConsentProviderType;
32
+ exports.normalizeAuthorizationType = normalizeAuthorizationType;
33
+ exports.getAuthorizationTypeLabel = getAuthorizationTypeLabel;
34
+ exports.getAuthorizationTypeKey = getAuthorizationTypeKey;
28
35
  const zod_1 = require("zod");
36
+ /** Canonical authorization type values for type safety */
37
+ exports.AUTHORIZATION_TYPES = {
38
+ OAUTH: 'oauth',
39
+ PASSWORD: 'password',
40
+ MDL: 'mdl',
41
+ IDV: 'idv',
42
+ /** FUTURE: Not yet implemented */
43
+ VERIFIABLE_CREDENTIAL: 'verifiable_credential',
44
+ /** @deprecated Use VERIFIABLE_CREDENTIAL */
45
+ CREDENTIAL: 'credential',
46
+ NONE: 'none',
47
+ };
29
48
  /**
30
49
  * Zod Schemas for Validation
31
50
  */
@@ -35,6 +54,10 @@ exports.AuthorizationRequirementSchema = zod_1.z.discriminatedUnion('type', [
35
54
  provider: zod_1.z.string(),
36
55
  requiredScopes: zod_1.z.array(zod_1.z.string()).optional(),
37
56
  }),
57
+ zod_1.z.object({
58
+ type: zod_1.z.literal('password'),
59
+ provider: zod_1.z.string(),
60
+ }),
38
61
  zod_1.z.object({
39
62
  type: zod_1.z.literal('mdl'),
40
63
  issuer: zod_1.z.string(),
@@ -45,6 +68,12 @@ exports.AuthorizationRequirementSchema = zod_1.z.discriminatedUnion('type', [
45
68
  provider: zod_1.z.string(),
46
69
  verificationLevel: zod_1.z.enum(['basic', 'enhanced', 'loa3']).optional(),
47
70
  }),
71
+ zod_1.z.object({
72
+ type: zod_1.z.literal('verifiable_credential'),
73
+ credentialType: zod_1.z.string(),
74
+ issuer: zod_1.z.string().optional(),
75
+ }),
76
+ // Backward compatibility: 'credential' is an alias for 'verifiable_credential'
48
77
  zod_1.z.object({
49
78
  type: zod_1.z.literal('credential'),
50
79
  credentialType: zod_1.z.string(),
@@ -104,6 +133,20 @@ function isAuthorizationRequirement(obj) {
104
133
  function hasOAuthAuthorization(protection) {
105
134
  return protection.authorization?.type === 'oauth';
106
135
  }
136
+ /**
137
+ * Type guard to check if a ToolProtection has password authorization
138
+ */
139
+ function hasPasswordAuthorization(protection) {
140
+ return protection.authorization?.type === 'password';
141
+ }
142
+ /**
143
+ * Type guard to check if a ToolProtection requires a Verifiable Credential
144
+ * Handles both 'verifiable_credential' and legacy 'credential' types
145
+ */
146
+ function hasVerifiableCredentialAuthorization(protection) {
147
+ const type = protection.authorization?.type;
148
+ return type === 'verifiable_credential' || type === 'credential';
149
+ }
107
150
  /**
108
151
  * Validation Functions
109
152
  */
@@ -198,3 +241,120 @@ function normalizeToolProtection(raw) {
198
241
  }
199
242
  return normalized;
200
243
  }
244
+ // =============================================================================
245
+ // CONSENT PROVIDER TYPES - Records what auth method was USED (not required)
246
+ // =============================================================================
247
+ /** Consent provider types - stored in delegation metadata to track auth method used */
248
+ exports.CONSENT_PROVIDER_TYPES = {
249
+ /** Consent-only mode - no authentication, just clickwrap agreement */
250
+ NONE: 'none',
251
+ /** OAuth2 provider authentication */
252
+ OAUTH2: 'oauth2',
253
+ /** Password-based authentication (email/password, username/password) */
254
+ PASSWORD: 'password',
255
+ /** @deprecated Use PASSWORD instead. Alias for backward compatibility */
256
+ CREDENTIAL: 'credential',
257
+ /** Email magic link authentication */
258
+ MAGIC_LINK: 'magic_link',
259
+ /** One-time password (SMS/email code) */
260
+ OTP: 'otp',
261
+ };
262
+ /**
263
+ * Determine consent provider type based on available identity information
264
+ *
265
+ * This is the single source of truth for consent provider type determination.
266
+ *
267
+ * @param hasOAuthIdentity - Whether OAuth identity is available
268
+ * @param isPasswordFlow - Whether this is a password/credential flow
269
+ * @param isMagicLinkFlow - Whether this is a magic link flow
270
+ * @param isOtpFlow - Whether this is an OTP flow
271
+ * @returns The consent provider type
272
+ */
273
+ function determineConsentProviderType(hasOAuthIdentity, isPasswordFlow = false, isMagicLinkFlow = false, isOtpFlow = false) {
274
+ if (isPasswordFlow) {
275
+ return exports.CONSENT_PROVIDER_TYPES.PASSWORD;
276
+ }
277
+ if (isMagicLinkFlow) {
278
+ return exports.CONSENT_PROVIDER_TYPES.MAGIC_LINK;
279
+ }
280
+ if (isOtpFlow) {
281
+ return exports.CONSENT_PROVIDER_TYPES.OTP;
282
+ }
283
+ if (hasOAuthIdentity) {
284
+ return exports.CONSENT_PROVIDER_TYPES.OAUTH2;
285
+ }
286
+ return exports.CONSENT_PROVIDER_TYPES.NONE;
287
+ }
288
+ // =============================================================================
289
+ // AUTHORIZATION TYPE NORMALIZATION
290
+ // =============================================================================
291
+ /**
292
+ * Normalize authorization requirement to use canonical type names
293
+ *
294
+ * Migrates legacy 'credential' type to 'verifiable_credential'
295
+ * This ensures consistent type usage across the codebase.
296
+ *
297
+ * @param auth - The authorization requirement (may have legacy type)
298
+ * @returns Normalized authorization requirement with canonical type
299
+ */
300
+ function normalizeAuthorizationType(auth) {
301
+ // Migrate legacy 'credential' to 'verifiable_credential'
302
+ if (auth.type === 'credential') {
303
+ return {
304
+ type: 'verifiable_credential',
305
+ credentialType: auth.credentialType,
306
+ issuer: auth.issuer,
307
+ };
308
+ }
309
+ return auth;
310
+ }
311
+ /**
312
+ * Get a human-readable label for an authorization requirement type
313
+ */
314
+ function getAuthorizationTypeLabel(auth) {
315
+ switch (auth.type) {
316
+ case 'oauth':
317
+ return auth.provider
318
+ ? auth.provider.charAt(0).toUpperCase() + auth.provider.slice(1)
319
+ : 'OAuth Provider';
320
+ case 'password':
321
+ return 'Password Authentication';
322
+ case 'mdl':
323
+ return "Mobile Driver's License";
324
+ case 'idv':
325
+ return 'Identity Verification';
326
+ case 'verifiable_credential':
327
+ case 'credential':
328
+ return auth.credentialType || 'Verifiable Credential';
329
+ case 'none':
330
+ return 'Consent Only';
331
+ default:
332
+ // TypeScript exhaustiveness check
333
+ const _exhaustive = auth;
334
+ return 'Unknown';
335
+ }
336
+ }
337
+ /**
338
+ * Get a unique key for an authorization requirement (for React keys, caching, etc.)
339
+ */
340
+ function getAuthorizationTypeKey(auth) {
341
+ switch (auth.type) {
342
+ case 'oauth':
343
+ return `oauth:${auth.provider}`;
344
+ case 'password':
345
+ return `password:${auth.provider}`;
346
+ case 'mdl':
347
+ return `mdl:${auth.issuer}:${auth.credentialType || ''}`;
348
+ case 'idv':
349
+ return `idv:${auth.provider}:${auth.verificationLevel || ''}`;
350
+ case 'verifiable_credential':
351
+ case 'credential':
352
+ return `vc:${auth.issuer || 'any'}:${auth.credentialType}`;
353
+ case 'none':
354
+ return 'none';
355
+ default:
356
+ // TypeScript exhaustiveness check
357
+ const _exhaustive = auth;
358
+ return 'unknown';
359
+ }
360
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kya-os/contracts",
3
- "version": "1.7.2",
3
+ "version": "1.7.4",
4
4
  "description": "Shared contracts, types, and schemas for MCP-I framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",