@kya-os/contracts 1.5.3-canary.16 → 1.5.3-canary.17
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/.turbo/turbo-build.log +17 -0
- package/.turbo/turbo-test$colon$coverage.log +85 -0
- package/.turbo/turbo-test.log +32 -0
- package/coverage/coverage-final.json +38 -0
- package/dist/consent/schemas.d.ts +18 -0
- package/dist/consent/schemas.js +10 -0
- package/dist/dashboard-config/schemas.d.ts +1424 -220
- package/dist/tool-protection/index.d.ts +418 -8
- package/dist/tool-protection/index.js +61 -2
- package/package.json +35 -129
- package/schemas/cli/register-output/v1.0.0.json +69 -0
- package/schemas/identity/v1.0.0.json +46 -0
- package/schemas/proof/v1.0.0.json +80 -0
- package/schemas/registry/receipt-v1.0.0.json +60 -0
- package/schemas/verifier/verify-page/v1.0.0.json +94 -0
- package/schemas/well-known/agent/v1.0.0.json +67 -0
- package/schemas/well-known/did/v1.0.0.json +174 -0
- package/scripts/emit-schemas.js +11 -0
- package/src/agentshield-api/admin-schemas.ts +31 -0
- package/src/agentshield-api/admin-types.ts +47 -0
- package/src/agentshield-api/endpoints.ts +60 -0
- package/src/agentshield-api/index.ts +70 -0
- package/src/agentshield-api/schemas.ts +304 -0
- package/src/agentshield-api/types.ts +317 -0
- package/src/audit/index.ts +128 -0
- package/src/cli.ts +156 -0
- package/src/config/base.ts +107 -0
- package/src/config/builder.ts +97 -0
- package/src/config/delegation.ts +232 -0
- package/src/config/identity.ts +252 -0
- package/src/config/index.ts +78 -0
- package/src/config/proofing.ts +138 -0
- package/src/config/tool-context.ts +41 -0
- package/src/config/tool-protection.ts +174 -0
- package/src/consent/index.ts +32 -0
- package/src/consent/schemas.ts +334 -0
- package/src/consent/types.ts +199 -0
- package/src/dashboard-config/default-config.json +86 -0
- package/src/dashboard-config/default-config.ts +266 -0
- package/src/dashboard-config/index.ts +48 -0
- package/src/dashboard-config/schemas.ts +286 -0
- package/src/dashboard-config/types.ts +404 -0
- package/src/delegation/constraints.ts +267 -0
- package/src/delegation/index.ts +8 -0
- package/src/delegation/schemas.ts +595 -0
- package/src/did/index.ts +9 -0
- package/src/did/resolve-contract.ts +255 -0
- package/src/did/schemas.ts +190 -0
- package/src/did/types.ts +224 -0
- package/src/env/constants.ts +70 -0
- package/src/env/index.ts +5 -0
- package/src/handshake.ts +125 -0
- package/src/index.ts +45 -0
- package/src/proof/index.ts +31 -0
- package/src/proof/proof-record.ts +163 -0
- package/src/proof/signing-spec.ts +146 -0
- package/src/proof.ts +99 -0
- package/src/registry.ts +146 -0
- package/src/runtime/errors.ts +153 -0
- package/src/runtime/headers.ts +136 -0
- package/src/runtime/index.ts +6 -0
- package/src/test.ts +143 -0
- package/src/tlkrc/index.ts +5 -0
- package/src/tlkrc/rotation.ts +153 -0
- package/src/tool-protection/index.ts +343 -0
- package/src/utils/validation.ts +93 -0
- package/src/vc/index.ts +8 -0
- package/src/vc/schemas.ts +277 -0
- package/src/vc/statuslist.ts +279 -0
- package/src/verifier.ts +92 -0
- package/src/well-known/index.ts +237 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proofing Configuration Types
|
|
3
|
+
*
|
|
4
|
+
* Configuration for proof generation and submission including batch
|
|
5
|
+
* processing, destinations, and retry logic.
|
|
6
|
+
*
|
|
7
|
+
* @module @kya-os/contracts/config
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Proof destination types
|
|
12
|
+
*/
|
|
13
|
+
export type ProofDestinationType = 'agentshield' | 'kta' | 'custom';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Proof destination configuration
|
|
17
|
+
* Defines where proofs should be submitted
|
|
18
|
+
*/
|
|
19
|
+
export interface ProofDestination {
|
|
20
|
+
/**
|
|
21
|
+
* Type of destination
|
|
22
|
+
*/
|
|
23
|
+
type: ProofDestinationType;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* API base URL for the destination
|
|
27
|
+
* Required for 'agentshield' and 'kta' types
|
|
28
|
+
* @example 'https://kya.vouched.id'
|
|
29
|
+
*/
|
|
30
|
+
apiUrl?: string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* API key for authentication
|
|
34
|
+
* Required for most destinations
|
|
35
|
+
*/
|
|
36
|
+
apiKey?: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Custom submission function
|
|
40
|
+
* Required for 'custom' type destinations
|
|
41
|
+
*/
|
|
42
|
+
submit?: (proofs: any[]) => Promise<void>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Additional destination-specific configuration
|
|
46
|
+
*/
|
|
47
|
+
options?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Proof batch queue configuration
|
|
52
|
+
* Controls how proofs are batched and submitted
|
|
53
|
+
*/
|
|
54
|
+
export interface ProofBatchQueueConfig {
|
|
55
|
+
/**
|
|
56
|
+
* Destinations where proofs should be sent
|
|
57
|
+
* Multiple destinations are processed in parallel
|
|
58
|
+
*/
|
|
59
|
+
destinations: ProofDestination[];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Maximum number of proofs to batch before auto-submission
|
|
63
|
+
* @default 10
|
|
64
|
+
*/
|
|
65
|
+
maxBatchSize?: number;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Time interval (ms) between automatic flush attempts
|
|
69
|
+
* @default 5000
|
|
70
|
+
*/
|
|
71
|
+
flushIntervalMs?: number;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Maximum number of retry attempts for failed submissions
|
|
75
|
+
* @default 3
|
|
76
|
+
*/
|
|
77
|
+
maxRetries?: number;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Backoff multiplier for retry delays
|
|
81
|
+
* @default 2
|
|
82
|
+
*/
|
|
83
|
+
retryBackoff?: number;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Enable debug logging for proof submission
|
|
87
|
+
* @default false
|
|
88
|
+
*/
|
|
89
|
+
debug?: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Proofing configuration (platform-agnostic)
|
|
94
|
+
*
|
|
95
|
+
* Controls proof generation, batching, and submission to external services
|
|
96
|
+
* like AgentShield or Know That AI (KTA).
|
|
97
|
+
*/
|
|
98
|
+
export interface ProofingConfig {
|
|
99
|
+
/**
|
|
100
|
+
* Enable proof generation and submission
|
|
101
|
+
* @default true
|
|
102
|
+
*/
|
|
103
|
+
enabled: boolean;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Proof batch queue configuration
|
|
107
|
+
* Controls batching and submission behavior
|
|
108
|
+
*/
|
|
109
|
+
batchQueue?: ProofBatchQueueConfig;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Include additional metadata in proofs
|
|
113
|
+
* @default true
|
|
114
|
+
*/
|
|
115
|
+
includeMetadata?: boolean;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Custom proof generation options
|
|
119
|
+
*/
|
|
120
|
+
options?: {
|
|
121
|
+
/**
|
|
122
|
+
* Include timestamp in all proofs
|
|
123
|
+
* @default true
|
|
124
|
+
*/
|
|
125
|
+
includeTimestamp?: boolean;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Include session context in proofs
|
|
129
|
+
* @default true
|
|
130
|
+
*/
|
|
131
|
+
includeSession?: boolean;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Custom fields to include in every proof
|
|
135
|
+
*/
|
|
136
|
+
customFields?: Record<string, unknown>;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Execution Context
|
|
3
|
+
*
|
|
4
|
+
* Execution context passed to tool handlers, enabling tools to access
|
|
5
|
+
* IDP tokens for external API calls (GitHub, Google, etc.).
|
|
6
|
+
*
|
|
7
|
+
* All fields are optional for backward compatibility - tools that don't
|
|
8
|
+
* require OAuth will receive undefined context.
|
|
9
|
+
*
|
|
10
|
+
* @package @kya-os/contracts
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Execution context passed to tool handlers
|
|
15
|
+
*
|
|
16
|
+
* Enables tools to access IDP tokens for external API calls.
|
|
17
|
+
* Context is only provided when:
|
|
18
|
+
* - Tool requires OAuth (has requiredScopes)
|
|
19
|
+
* - User DID is available
|
|
20
|
+
* - IDP token is successfully resolved
|
|
21
|
+
*/
|
|
22
|
+
export interface ToolExecutionContext {
|
|
23
|
+
/** IDP access token for external API calls (e.g., GitHub, Google) */
|
|
24
|
+
idpToken?: string;
|
|
25
|
+
|
|
26
|
+
/** OAuth provider name (e.g., "github", "google") */
|
|
27
|
+
provider?: string;
|
|
28
|
+
|
|
29
|
+
/** Scopes granted for this token */
|
|
30
|
+
scopes?: string[];
|
|
31
|
+
|
|
32
|
+
/** User DID associated with this token */
|
|
33
|
+
userDid?: string;
|
|
34
|
+
|
|
35
|
+
/** Session ID */
|
|
36
|
+
sessionId?: string;
|
|
37
|
+
|
|
38
|
+
/** Delegation token (MCP-I internal authorization) */
|
|
39
|
+
delegationToken?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Protection Configuration Types
|
|
3
|
+
*
|
|
4
|
+
* Configuration for tool protection including delegation requirements,
|
|
5
|
+
* scopes, and multi-source resolution strategies.
|
|
6
|
+
*
|
|
7
|
+
* @module @kya-os/contracts/config
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Import core tool protection types from the spec
|
|
11
|
+
import type {
|
|
12
|
+
ToolProtection as BaseToolProtection,
|
|
13
|
+
ToolProtectionMap as BaseToolProtectionMap,
|
|
14
|
+
DelegationRequiredErrorData as BaseDelegationRequiredErrorData,
|
|
15
|
+
ToolProtectionResponse as BaseToolProtectionResponse
|
|
16
|
+
} from '../tool-protection/index.js';
|
|
17
|
+
|
|
18
|
+
// Re-export for convenience
|
|
19
|
+
export type ToolProtection = BaseToolProtection;
|
|
20
|
+
export type ToolProtectionMap = BaseToolProtectionMap;
|
|
21
|
+
export type DelegationRequiredErrorData = BaseDelegationRequiredErrorData;
|
|
22
|
+
export type ToolProtectionResponse = BaseToolProtectionResponse;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Tool protection source types
|
|
26
|
+
*/
|
|
27
|
+
export type ToolProtectionSourceType =
|
|
28
|
+
| 'inline' // Inline configuration in code
|
|
29
|
+
| 'local' // Local file (tool-protections.json)
|
|
30
|
+
| 'agentshield' // AgentShield API
|
|
31
|
+
| 'kta' // Know That AI
|
|
32
|
+
| 'multi'; // Multiple sources with priority resolution
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Tool protection source configuration
|
|
36
|
+
* Defines where tool protection settings come from
|
|
37
|
+
*/
|
|
38
|
+
export interface ToolProtectionSourceConfig {
|
|
39
|
+
/**
|
|
40
|
+
* Type of source to use
|
|
41
|
+
*/
|
|
42
|
+
source: ToolProtectionSourceType;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Inline tool protection map
|
|
46
|
+
* Used when source is 'inline'
|
|
47
|
+
*/
|
|
48
|
+
inline?: BaseToolProtectionMap;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Path to local tool protections file
|
|
52
|
+
* Used when source is 'local'
|
|
53
|
+
* @example './tool-protections.json'
|
|
54
|
+
*/
|
|
55
|
+
localFile?: string;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* AgentShield configuration
|
|
59
|
+
* Used when source is 'agentshield'
|
|
60
|
+
*/
|
|
61
|
+
agentShield?: {
|
|
62
|
+
/**
|
|
63
|
+
* AgentShield API base URL
|
|
64
|
+
* @example 'https://kya.vouched.id'
|
|
65
|
+
*/
|
|
66
|
+
apiUrl: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* API key for authentication
|
|
70
|
+
*/
|
|
71
|
+
apiKey?: string;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Project ID (optional, for backward compatibility)
|
|
75
|
+
* Modern approach uses agent DID
|
|
76
|
+
*/
|
|
77
|
+
projectId?: string;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Cache TTL in milliseconds
|
|
81
|
+
* @default 300000 (5 minutes)
|
|
82
|
+
*/
|
|
83
|
+
cacheTtl?: number;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* KTA configuration
|
|
88
|
+
* Used when source is 'kta'
|
|
89
|
+
*/
|
|
90
|
+
kta?: {
|
|
91
|
+
/**
|
|
92
|
+
* KTA API base URL
|
|
93
|
+
*/
|
|
94
|
+
apiUrl: string;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* API key for authentication
|
|
98
|
+
*/
|
|
99
|
+
apiKey?: string;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Multi-source configuration
|
|
104
|
+
* Used when source is 'multi'
|
|
105
|
+
* Sources are checked in priority order
|
|
106
|
+
*/
|
|
107
|
+
sources?: Array<{
|
|
108
|
+
/**
|
|
109
|
+
* Source configuration
|
|
110
|
+
*/
|
|
111
|
+
config: Omit<ToolProtectionSourceConfig, 'source' | 'sources'>;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Priority (higher number = higher priority)
|
|
115
|
+
* @default 0
|
|
116
|
+
*/
|
|
117
|
+
priority?: number;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Whether to stop after this source if found
|
|
121
|
+
* @default false
|
|
122
|
+
*/
|
|
123
|
+
exclusive?: boolean;
|
|
124
|
+
}>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Fallback configuration if all sources fail
|
|
128
|
+
*/
|
|
129
|
+
fallback?: BaseToolProtectionMap;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Enable debug logging
|
|
133
|
+
* @default false
|
|
134
|
+
*/
|
|
135
|
+
debug?: boolean;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Tool protection service configuration
|
|
140
|
+
* Used by provider-based implementations
|
|
141
|
+
*/
|
|
142
|
+
export interface ToolProtectionServiceConfig {
|
|
143
|
+
/**
|
|
144
|
+
* API base URL for fetching tool protections
|
|
145
|
+
*/
|
|
146
|
+
apiUrl: string;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* API key for authentication
|
|
150
|
+
*/
|
|
151
|
+
apiKey: string;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Project ID (optional)
|
|
155
|
+
*/
|
|
156
|
+
projectId?: string;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Cache TTL in milliseconds
|
|
160
|
+
* @default 300000 (5 minutes)
|
|
161
|
+
*/
|
|
162
|
+
cacheTtl?: number;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Fallback configuration if API is unavailable
|
|
166
|
+
*/
|
|
167
|
+
fallbackConfig?: BaseToolProtectionMap;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Enable debug logging
|
|
171
|
+
* @default false
|
|
172
|
+
*/
|
|
173
|
+
debug?: boolean;
|
|
174
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consent Module Exports
|
|
3
|
+
*
|
|
4
|
+
* Types and schemas for consent page configuration and approval handling
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Export schemas and inferred types (types are derived from schemas)
|
|
8
|
+
export {
|
|
9
|
+
consentBrandingSchema,
|
|
10
|
+
consentTermsSchema,
|
|
11
|
+
consentCustomFieldSchema,
|
|
12
|
+
consentCustomFieldOptionSchema,
|
|
13
|
+
consentPageConfigSchema,
|
|
14
|
+
consentApprovalRequestSchema,
|
|
15
|
+
consentApprovalResponseSchema,
|
|
16
|
+
consentConfigSchema,
|
|
17
|
+
oauthIdentitySchema,
|
|
18
|
+
validateConsentPageConfig,
|
|
19
|
+
validateConsentApprovalRequest,
|
|
20
|
+
validateConsentApprovalResponse,
|
|
21
|
+
validateConsentConfig,
|
|
22
|
+
type ConsentBranding,
|
|
23
|
+
type ConsentTerms,
|
|
24
|
+
type ConsentCustomField,
|
|
25
|
+
type ConsentPageConfig,
|
|
26
|
+
type ConsentApprovalRequest,
|
|
27
|
+
type ConsentApprovalResponse,
|
|
28
|
+
type ConsentConfig,
|
|
29
|
+
type OAuthIdentity,
|
|
30
|
+
} from './schemas.js';
|
|
31
|
+
|
|
32
|
+
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consent Schemas
|
|
3
|
+
*
|
|
4
|
+
* Zod schemas for runtime validation of consent-related data structures.
|
|
5
|
+
* All types are derived from these schemas using z.infer.
|
|
6
|
+
*
|
|
7
|
+
* Related Spec: MCP-I Phase 0 Implementation Plan
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Consent Branding Schema
|
|
14
|
+
*/
|
|
15
|
+
export const consentBrandingSchema = z.object({
|
|
16
|
+
primaryColor: z
|
|
17
|
+
.string()
|
|
18
|
+
.regex(/^#[0-9A-Fa-f]{6}$/, "Must be a valid hex color (e.g., #0066CC)")
|
|
19
|
+
.optional(),
|
|
20
|
+
logoUrl: z.string().url("Must be a valid URL").optional(),
|
|
21
|
+
companyName: z
|
|
22
|
+
.string()
|
|
23
|
+
.max(100, "Company name must be 100 characters or less")
|
|
24
|
+
.optional(),
|
|
25
|
+
theme: z.enum(["light", "dark", "auto"]).optional(),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export type ConsentBranding = z.infer<typeof consentBrandingSchema>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Consent Terms Schema
|
|
32
|
+
*/
|
|
33
|
+
export const consentTermsSchema = z.object({
|
|
34
|
+
text: z
|
|
35
|
+
.string()
|
|
36
|
+
.max(10000, "Terms text must be 10000 characters or less")
|
|
37
|
+
.optional(),
|
|
38
|
+
url: z.string().url("Must be a valid URL").optional(),
|
|
39
|
+
version: z
|
|
40
|
+
.string()
|
|
41
|
+
.max(50, "Version must be 50 characters or less")
|
|
42
|
+
.optional(),
|
|
43
|
+
required: z.boolean().default(true),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export type ConsentTerms = z.infer<typeof consentTermsSchema>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Consent Custom Field Option Schema
|
|
50
|
+
*/
|
|
51
|
+
export const consentCustomFieldOptionSchema = z.object({
|
|
52
|
+
value: z.string().max(100, "Option value must be 100 characters or less"),
|
|
53
|
+
label: z.string().max(100, "Option label must be 100 characters or less"),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Consent Custom Field Schema
|
|
58
|
+
*/
|
|
59
|
+
export const consentCustomFieldSchema = z
|
|
60
|
+
.object({
|
|
61
|
+
name: z
|
|
62
|
+
.string()
|
|
63
|
+
.min(1, "Field name is required")
|
|
64
|
+
.max(50, "Field name must be 50 characters or less")
|
|
65
|
+
.regex(
|
|
66
|
+
/^[a-zA-Z0-9_]+$/,
|
|
67
|
+
"Field name must contain only letters, numbers, and underscores"
|
|
68
|
+
),
|
|
69
|
+
label: z
|
|
70
|
+
.string()
|
|
71
|
+
.min(1, "Field label is required")
|
|
72
|
+
.max(100, "Field label must be 100 characters or less"),
|
|
73
|
+
type: z.enum(["text", "textarea", "checkbox", "select"]),
|
|
74
|
+
required: z.boolean(),
|
|
75
|
+
placeholder: z
|
|
76
|
+
.string()
|
|
77
|
+
.max(200, "Placeholder must be 200 characters or less")
|
|
78
|
+
.optional(),
|
|
79
|
+
options: z
|
|
80
|
+
.array(consentCustomFieldOptionSchema)
|
|
81
|
+
.min(1, "Select fields must have at least one option")
|
|
82
|
+
.optional(),
|
|
83
|
+
pattern: z
|
|
84
|
+
.string()
|
|
85
|
+
.max(500, "Pattern must be 500 characters or less")
|
|
86
|
+
.optional(),
|
|
87
|
+
})
|
|
88
|
+
.refine(
|
|
89
|
+
(data) => {
|
|
90
|
+
// Select fields must have options
|
|
91
|
+
if (
|
|
92
|
+
data.type === "select" &&
|
|
93
|
+
(!data.options || data.options.length === 0)
|
|
94
|
+
) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
// Non-select fields should not have options
|
|
98
|
+
if (data.type !== "select" && data.options) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
message:
|
|
105
|
+
"Select fields must have options, and non-select fields must not have options",
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
export type ConsentCustomField = z.infer<typeof consentCustomFieldSchema>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* OAuth Identity Schema
|
|
113
|
+
*
|
|
114
|
+
* Represents a user's OAuth provider account information.
|
|
115
|
+
* Used in Phase 4 to link OAuth accounts to persistent User DIDs.
|
|
116
|
+
*/
|
|
117
|
+
export const oauthIdentitySchema = z.object({
|
|
118
|
+
/**
|
|
119
|
+
* OAuth provider name (e.g., "google", "github", "microsoft")
|
|
120
|
+
*/
|
|
121
|
+
provider: z
|
|
122
|
+
.string()
|
|
123
|
+
.min(1, "Provider is required")
|
|
124
|
+
.max(50, "Provider name must be 50 characters or less"),
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* OAuth subject identifier (unique user ID from provider)
|
|
128
|
+
* @example "123456789" (Google), "github-user-id" (GitHub)
|
|
129
|
+
*/
|
|
130
|
+
subject: z
|
|
131
|
+
.string()
|
|
132
|
+
.min(1, "Subject is required")
|
|
133
|
+
.max(255, "Subject must be 255 characters or less"),
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* User's email address from OAuth provider (optional)
|
|
137
|
+
*/
|
|
138
|
+
email: z
|
|
139
|
+
.string()
|
|
140
|
+
.email("Must be a valid email address")
|
|
141
|
+
.max(255, "Email must be 255 characters or less")
|
|
142
|
+
.optional(),
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* User's display name from OAuth provider (optional)
|
|
146
|
+
*/
|
|
147
|
+
name: z.string().max(255, "Name must be 255 characters or less").optional(),
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
export type OAuthIdentity = z.infer<typeof oauthIdentitySchema>;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Consent Page Config Schema
|
|
154
|
+
*/
|
|
155
|
+
export const consentPageConfigSchema = z.object({
|
|
156
|
+
tool: z.string().min(1, "Tool name is required"),
|
|
157
|
+
toolDescription: z
|
|
158
|
+
.string()
|
|
159
|
+
.max(500, "Tool description must be 500 characters or less"),
|
|
160
|
+
scopes: z.array(z.string()).min(0, "Scopes array cannot be negative"),
|
|
161
|
+
agentDid: z.string().min(1, "Agent DID is required"),
|
|
162
|
+
sessionId: z.string().min(1, "Session ID is required"),
|
|
163
|
+
projectId: z.string().min(1, "Project ID is required"),
|
|
164
|
+
provider: z.string().optional(), // Phase 2: OAuth provider name (e.g., "github", "google")
|
|
165
|
+
branding: consentBrandingSchema.optional(),
|
|
166
|
+
terms: consentTermsSchema.optional(),
|
|
167
|
+
customFields: z
|
|
168
|
+
.array(consentCustomFieldSchema)
|
|
169
|
+
.max(10, "Maximum 10 custom fields allowed")
|
|
170
|
+
.optional(),
|
|
171
|
+
serverUrl: z.string().url("Server URL must be a valid URL"),
|
|
172
|
+
autoClose: z.boolean().optional(),
|
|
173
|
+
/**
|
|
174
|
+
* Whether OAuth authorization is required immediately
|
|
175
|
+
* If true, the consent page will act as a landing page before redirecting
|
|
176
|
+
*/
|
|
177
|
+
oauthRequired: z.boolean().optional(),
|
|
178
|
+
/**
|
|
179
|
+
* The OAuth authorization URL to redirect to
|
|
180
|
+
* Required if oauthRequired is true
|
|
181
|
+
*/
|
|
182
|
+
oauthUrl: z.string().url().optional(),
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
export type ConsentPageConfig = z.infer<typeof consentPageConfigSchema>;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Consent Approval Request Schema
|
|
189
|
+
*
|
|
190
|
+
* Note: Uses snake_case for API compatibility (agent_did, session_id, project_id)
|
|
191
|
+
*
|
|
192
|
+
* Phase 4 additions:
|
|
193
|
+
* - oauth_identity: Optional OAuth provider information for identity linking
|
|
194
|
+
* - user_did: Optional User DID for persistent identity (if already known)
|
|
195
|
+
*/
|
|
196
|
+
export const consentApprovalRequestSchema = z.object({
|
|
197
|
+
tool: z.string().min(1, "Tool name is required"),
|
|
198
|
+
scopes: z.array(z.string()).min(0, "Scopes array cannot be negative"),
|
|
199
|
+
agent_did: z.string().min(1, "Agent DID is required"),
|
|
200
|
+
session_id: z.string().min(1, "Session ID is required"),
|
|
201
|
+
project_id: z.string().min(1, "Project ID is required"),
|
|
202
|
+
termsAccepted: z.boolean(),
|
|
203
|
+
termsVersion: z
|
|
204
|
+
.string()
|
|
205
|
+
.max(50, "Terms version must be 50 characters or less")
|
|
206
|
+
.optional(),
|
|
207
|
+
customFields: z.record(z.union([z.string(), z.boolean()])).optional(),
|
|
208
|
+
|
|
209
|
+
// Phase 4: OAuth identity linking
|
|
210
|
+
/**
|
|
211
|
+
* OAuth provider identity information (optional)
|
|
212
|
+
* Used to link OAuth accounts to persistent User DIDs
|
|
213
|
+
*
|
|
214
|
+
* CRITICAL: Uses .nullish() to accept null, undefined, or OAuthIdentity
|
|
215
|
+
* This matches JSON parsing behavior where missing fields become null
|
|
216
|
+
*/
|
|
217
|
+
oauth_identity: oauthIdentitySchema.nullish(),
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* User DID (optional)
|
|
221
|
+
* If provided, represents the persistent User DID for this user
|
|
222
|
+
* Format: did:key:... or did:web:...
|
|
223
|
+
*/
|
|
224
|
+
user_did: z
|
|
225
|
+
.string()
|
|
226
|
+
.regex(/^did:/, "Must be a valid DID format (starting with did:)")
|
|
227
|
+
.max(500, "DID must be 500 characters or less")
|
|
228
|
+
.optional(),
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
export type ConsentApprovalRequest = z.infer<
|
|
232
|
+
typeof consentApprovalRequestSchema
|
|
233
|
+
>;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Consent Approval Response Schema
|
|
237
|
+
*/
|
|
238
|
+
export const consentApprovalResponseSchema = z
|
|
239
|
+
.object({
|
|
240
|
+
success: z.boolean(),
|
|
241
|
+
delegation_id: z.string().min(1).optional(),
|
|
242
|
+
delegation_token: z.string().min(1).optional(),
|
|
243
|
+
error: z.string().optional(),
|
|
244
|
+
error_code: z.string().optional(),
|
|
245
|
+
})
|
|
246
|
+
.refine(
|
|
247
|
+
(data) => {
|
|
248
|
+
// If success is true, must have delegation_id and delegation_token
|
|
249
|
+
if (data.success) {
|
|
250
|
+
return !!data.delegation_id && !!data.delegation_token;
|
|
251
|
+
}
|
|
252
|
+
// If success is false, must have error or error_code
|
|
253
|
+
return !!data.error || !!data.error_code;
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
message:
|
|
257
|
+
"Successful responses must include delegation_id and delegation_token. Failed responses must include error or error_code",
|
|
258
|
+
}
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
export type ConsentApprovalResponse = z.infer<
|
|
262
|
+
typeof consentApprovalResponseSchema
|
|
263
|
+
>;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Consent Config Schema
|
|
267
|
+
*/
|
|
268
|
+
export const consentConfigSchema = z.object({
|
|
269
|
+
branding: consentBrandingSchema.optional(),
|
|
270
|
+
terms: consentTermsSchema.optional(),
|
|
271
|
+
customFields: z
|
|
272
|
+
.array(consentCustomFieldSchema)
|
|
273
|
+
.max(10, "Maximum 10 custom fields allowed")
|
|
274
|
+
.optional(),
|
|
275
|
+
ui: z
|
|
276
|
+
.object({
|
|
277
|
+
theme: z.enum(["light", "dark", "auto"]).optional(),
|
|
278
|
+
popupEnabled: z.boolean().optional(),
|
|
279
|
+
autoClose: z.boolean().optional(),
|
|
280
|
+
autoCloseDelay: z
|
|
281
|
+
.number()
|
|
282
|
+
.int()
|
|
283
|
+
.positive()
|
|
284
|
+
.max(60000, "Auto-close delay must be 60000ms or less")
|
|
285
|
+
.optional(),
|
|
286
|
+
})
|
|
287
|
+
.optional(),
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
export type ConsentConfig = z.infer<typeof consentConfigSchema>;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Validation Helpers
|
|
294
|
+
*/
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Validate a consent page config
|
|
298
|
+
*
|
|
299
|
+
* @param config - The config to validate
|
|
300
|
+
* @returns Validation result
|
|
301
|
+
*/
|
|
302
|
+
export function validateConsentPageConfig(config: unknown) {
|
|
303
|
+
return consentPageConfigSchema.safeParse(config);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Validate a consent approval request
|
|
308
|
+
*
|
|
309
|
+
* @param request - The request to validate
|
|
310
|
+
* @returns Validation result
|
|
311
|
+
*/
|
|
312
|
+
export function validateConsentApprovalRequest(request: unknown) {
|
|
313
|
+
return consentApprovalRequestSchema.safeParse(request);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Validate a consent approval response
|
|
318
|
+
*
|
|
319
|
+
* @param response - The response to validate
|
|
320
|
+
* @returns Validation result
|
|
321
|
+
*/
|
|
322
|
+
export function validateConsentApprovalResponse(response: unknown) {
|
|
323
|
+
return consentApprovalResponseSchema.safeParse(response);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Validate a consent config
|
|
328
|
+
*
|
|
329
|
+
* @param config - The config to validate
|
|
330
|
+
* @returns Validation result
|
|
331
|
+
*/
|
|
332
|
+
export function validateConsentConfig(config: unknown) {
|
|
333
|
+
return consentConfigSchema.safeParse(config);
|
|
334
|
+
}
|