@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.
Files changed (71) 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/consent/schemas.d.ts +18 -0
  6. package/dist/consent/schemas.js +10 -0
  7. package/dist/dashboard-config/schemas.d.ts +1424 -220
  8. package/dist/tool-protection/index.d.ts +418 -8
  9. package/dist/tool-protection/index.js +61 -2
  10. package/package.json +35 -129
  11. package/schemas/cli/register-output/v1.0.0.json +69 -0
  12. package/schemas/identity/v1.0.0.json +46 -0
  13. package/schemas/proof/v1.0.0.json +80 -0
  14. package/schemas/registry/receipt-v1.0.0.json +60 -0
  15. package/schemas/verifier/verify-page/v1.0.0.json +94 -0
  16. package/schemas/well-known/agent/v1.0.0.json +67 -0
  17. package/schemas/well-known/did/v1.0.0.json +174 -0
  18. package/scripts/emit-schemas.js +11 -0
  19. package/src/agentshield-api/admin-schemas.ts +31 -0
  20. package/src/agentshield-api/admin-types.ts +47 -0
  21. package/src/agentshield-api/endpoints.ts +60 -0
  22. package/src/agentshield-api/index.ts +70 -0
  23. package/src/agentshield-api/schemas.ts +304 -0
  24. package/src/agentshield-api/types.ts +317 -0
  25. package/src/audit/index.ts +128 -0
  26. package/src/cli.ts +156 -0
  27. package/src/config/base.ts +107 -0
  28. package/src/config/builder.ts +97 -0
  29. package/src/config/delegation.ts +232 -0
  30. package/src/config/identity.ts +252 -0
  31. package/src/config/index.ts +78 -0
  32. package/src/config/proofing.ts +138 -0
  33. package/src/config/tool-context.ts +41 -0
  34. package/src/config/tool-protection.ts +174 -0
  35. package/src/consent/index.ts +32 -0
  36. package/src/consent/schemas.ts +334 -0
  37. package/src/consent/types.ts +199 -0
  38. package/src/dashboard-config/default-config.json +86 -0
  39. package/src/dashboard-config/default-config.ts +266 -0
  40. package/src/dashboard-config/index.ts +48 -0
  41. package/src/dashboard-config/schemas.ts +286 -0
  42. package/src/dashboard-config/types.ts +404 -0
  43. package/src/delegation/constraints.ts +267 -0
  44. package/src/delegation/index.ts +8 -0
  45. package/src/delegation/schemas.ts +595 -0
  46. package/src/did/index.ts +9 -0
  47. package/src/did/resolve-contract.ts +255 -0
  48. package/src/did/schemas.ts +190 -0
  49. package/src/did/types.ts +224 -0
  50. package/src/env/constants.ts +70 -0
  51. package/src/env/index.ts +5 -0
  52. package/src/handshake.ts +125 -0
  53. package/src/index.ts +45 -0
  54. package/src/proof/index.ts +31 -0
  55. package/src/proof/proof-record.ts +163 -0
  56. package/src/proof/signing-spec.ts +146 -0
  57. package/src/proof.ts +99 -0
  58. package/src/registry.ts +146 -0
  59. package/src/runtime/errors.ts +153 -0
  60. package/src/runtime/headers.ts +136 -0
  61. package/src/runtime/index.ts +6 -0
  62. package/src/test.ts +143 -0
  63. package/src/tlkrc/index.ts +5 -0
  64. package/src/tlkrc/rotation.ts +153 -0
  65. package/src/tool-protection/index.ts +343 -0
  66. package/src/utils/validation.ts +93 -0
  67. package/src/vc/index.ts +8 -0
  68. package/src/vc/schemas.ts +277 -0
  69. package/src/vc/statuslist.ts +279 -0
  70. package/src/verifier.ts +92 -0
  71. package/src/well-known/index.ts +237 -0
@@ -0,0 +1,174 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://schemas.kya-os.ai/xmcp-i/well-known/did/v1.0.0",
4
+ "title": "W3C DID Document",
5
+ "description": "Schema for /.well-known/did.json endpoint (W3C DID Core specification)",
6
+ "type": "object",
7
+ "properties": {
8
+ "@context": {
9
+ "description": "JSON-LD context - must be W3C DID v1 string or array with W3C DID v1 as first element",
10
+ "oneOf": [
11
+ {
12
+ "type": "string",
13
+ "const": "https://www.w3.org/ns/did/v1"
14
+ },
15
+ {
16
+ "type": "array",
17
+ "minItems": 1,
18
+ "maxItems": 10,
19
+ "items": {
20
+ "oneOf": [
21
+ {
22
+ "const": "https://www.w3.org/ns/did/v1"
23
+ },
24
+ {
25
+ "type": "string"
26
+ }
27
+ ]
28
+ },
29
+ "contains": {
30
+ "const": "https://www.w3.org/ns/did/v1"
31
+ }
32
+ }
33
+ ]
34
+
35
+ },
36
+ "id": {
37
+ "type": "string",
38
+ "description": "DID identifier",
39
+ "pattern": "^did:"
40
+ },
41
+ "verificationMethod": {
42
+ "type": "array",
43
+ "description": "Verification methods",
44
+ "items": {
45
+ "type": "object",
46
+ "required": ["id", "type", "controller"],
47
+ "properties": {
48
+ "id": {
49
+ "type": "string",
50
+ "description": "Verification method ID"
51
+ },
52
+ "type": {
53
+ "type": "string",
54
+ "description": "Verification method type",
55
+ "enum": [
56
+ "Ed25519VerificationKey2020",
57
+ "Ed25519VerificationKey2018",
58
+ "JsonWebKey2020"
59
+ ]
60
+ },
61
+ "controller": {
62
+ "type": "string",
63
+ "description": "Controller DID",
64
+ "pattern": "^did:"
65
+ },
66
+ "publicKeyBase64": {
67
+ "type": "string",
68
+ "description": "Base64-encoded public key"
69
+ },
70
+ "publicKeyMultibase": {
71
+ "type": "string",
72
+ "description": "Multibase-encoded public key"
73
+ },
74
+ "publicKeyJwk": {
75
+ "type": "object",
76
+ "description": "JSON Web Key"
77
+ }
78
+ },
79
+ "anyOf": [
80
+ {
81
+ "properties": {
82
+ "publicKeyBase64": {
83
+ "type": "string"
84
+ }
85
+ },
86
+ "required": ["publicKeyBase64"]
87
+ },
88
+ {
89
+ "properties": {
90
+ "publicKeyMultibase": {
91
+ "type": "string"
92
+ }
93
+ },
94
+ "required": ["publicKeyMultibase"]
95
+ },
96
+ {
97
+ "properties": {
98
+ "publicKeyJwk": {
99
+ "type": "object"
100
+ }
101
+ },
102
+ "required": ["publicKeyJwk"]
103
+ }
104
+ ]
105
+ },
106
+ "minItems": 1
107
+ },
108
+ "authentication": {
109
+ "type": "array",
110
+ "description": "Authentication methods",
111
+ "items": {
112
+ "type": "string"
113
+ },
114
+ "minItems": 1
115
+ },
116
+ "assertionMethod": {
117
+ "type": "array",
118
+ "description": "Assertion methods",
119
+ "items": {
120
+ "type": "string"
121
+ }
122
+ },
123
+ "keyAgreement": {
124
+ "type": "array",
125
+ "description": "Key agreement methods",
126
+ "items": {
127
+ "type": "string"
128
+ }
129
+ },
130
+ "capabilityInvocation": {
131
+ "type": "array",
132
+ "description": "Capability invocation methods",
133
+ "items": {
134
+ "type": "string"
135
+ }
136
+ },
137
+ "capabilityDelegation": {
138
+ "type": "array",
139
+ "description": "Capability delegation methods",
140
+ "items": {
141
+ "type": "string"
142
+ }
143
+ },
144
+ "service": {
145
+ "type": "array",
146
+ "description": "Service endpoints",
147
+ "items": {
148
+ "type": "object",
149
+ "properties": {
150
+ "id": {
151
+ "type": "string"
152
+ },
153
+ "type": {
154
+ "type": "string"
155
+ },
156
+ "serviceEndpoint": {
157
+ "oneOf": [
158
+ {
159
+ "type": "string",
160
+ "format": "uri"
161
+ },
162
+ {
163
+ "type": "object"
164
+ }
165
+ ]
166
+ }
167
+ },
168
+ "required": ["id", "type", "serviceEndpoint"]
169
+ }
170
+ }
171
+ },
172
+ "required": ["@context", "id", "verificationMethod", "authentication"],
173
+ "additionalProperties": true
174
+ }
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Schema Emission Script
4
+ *
5
+ * This script generates JSON Schemas from Zod schemas for interoperability
6
+ * with other languages and validation tools.
7
+ */
8
+
9
+ // Placeholder - will be implemented after Zod schemas are created
10
+ console.log('Schema emission script - to be implemented');
11
+ process.exit(0);
@@ -0,0 +1,31 @@
1
+ /**
2
+ * AgentShield Admin API Validation Schemas
3
+ *
4
+ * Zod schemas for administrative operations in AgentShield.
5
+ *
6
+ * @package @kya-os/contracts/agentshield-api
7
+ */
8
+
9
+ import { z } from 'zod';
10
+
11
+ /**
12
+ * Request schema for clearing agent cache
13
+ */
14
+ export const clearCacheRequestSchema = z.object({
15
+ agent_did: z.string().min(1).describe('The DID of the agent whose cache should be cleared'),
16
+ });
17
+
18
+ /**
19
+ * Response schema for clear cache operation
20
+ */
21
+ export const clearCacheResponseSchema = z.object({
22
+ message: z.string().describe('Human-readable message about the operation result'),
23
+ agent_did: z.string().describe('The agent DID that was cleared'),
24
+ project_id: z.string().nullable().describe('The project ID if available'),
25
+ cache_key: z.string().describe('The cache key that was cleared'),
26
+ old_cache_key: z.string().nullable().describe('Old cache key that was also cleared (for migration)'),
27
+ had_value: z.boolean().describe('Whether the cache entry existed before clearing'),
28
+ had_old_value: z.boolean().describe('Whether the old cache entry existed before clearing'),
29
+ cleared: z.boolean().describe('Whether the cache was successfully cleared'),
30
+ });
31
+
@@ -0,0 +1,47 @@
1
+ /**
2
+ * AgentShield Admin API Type Definitions
3
+ *
4
+ * TypeScript interfaces for administrative operations in AgentShield.
5
+ * These types ensure parity between xmcp-i admin endpoints and the AgentShield service.
6
+ *
7
+ * @package @kya-os/contracts/agentshield-api
8
+ */
9
+
10
+ /**
11
+ * Request to clear agent cache
12
+ * POST /admin/clear-cache
13
+ */
14
+ export interface ClearCacheRequest {
15
+ /** The DID of the agent whose cache should be cleared */
16
+ agent_did: string;
17
+ }
18
+
19
+ /**
20
+ * Response from clear cache operation
21
+ */
22
+ export interface ClearCacheResponse {
23
+ /** Human-readable message about the operation result */
24
+ message: string;
25
+
26
+ /** The agent DID that was cleared */
27
+ agent_did: string;
28
+
29
+ /** The project ID if available */
30
+ project_id: string | null;
31
+
32
+ /** The cache key that was cleared */
33
+ cache_key: string;
34
+
35
+ /** Old cache key that was also cleared (for migration) */
36
+ old_cache_key: string | null;
37
+
38
+ /** Whether the cache entry existed before clearing */
39
+ had_value: boolean;
40
+
41
+ /** Whether the old cache entry existed before clearing */
42
+ had_old_value: boolean;
43
+
44
+ /** Whether the cache was successfully cleared */
45
+ cleared: boolean;
46
+ }
47
+
@@ -0,0 +1,60 @@
1
+ /**
2
+ * AgentShield/Bouncer API Endpoint Constants
3
+ *
4
+ * Centralized endpoint definitions to prevent hardcoded URLs
5
+ * and ensure consistency across all API clients.
6
+ *
7
+ * @package @kya-os/contracts/agentshield-api
8
+ */
9
+
10
+ /**
11
+ * Base path for all AgentShield/Bouncer API endpoints
12
+ */
13
+ export const AGENTSHIELD_API_BASE = '/api/v1/bouncer' as const;
14
+
15
+ /**
16
+ * AgentShield API endpoint paths
17
+ *
18
+ * These are relative paths that should be appended to the base API URL.
19
+ * Example: `${apiUrl}${AGENTSHIELD_ENDPOINTS.PROOFS}`
20
+ */
21
+ export const AGENTSHIELD_ENDPOINTS = {
22
+ /** Submit proofs in batch */
23
+ PROOFS: `${AGENTSHIELD_API_BASE}/proofs` as const,
24
+
25
+ /** Verify delegation by agent DID and scopes */
26
+ DELEGATIONS_VERIFY: `${AGENTSHIELD_API_BASE}/delegations/verify` as const,
27
+
28
+ /** Get delegation by ID */
29
+ DELEGATIONS_GET: (id: string) => `${AGENTSHIELD_API_BASE}/delegations/${id}` as const,
30
+
31
+ /** Create new delegation */
32
+ DELEGATIONS_CREATE: `${AGENTSHIELD_API_BASE}/delegations` as const,
33
+
34
+ /** Revoke delegation */
35
+ DELEGATIONS_REVOKE: (id: string) => `${AGENTSHIELD_API_BASE}/delegations/${id}/revoke` as const,
36
+
37
+ /** Get server configuration */
38
+ CONFIG: (projectId: string) => `${AGENTSHIELD_API_BASE}/projects/${projectId}/config` as const,
39
+ } as const;
40
+
41
+ /**
42
+ * HTTP methods for each endpoint
43
+ */
44
+ export const AGENTSHIELD_METHODS = {
45
+ PROOFS: 'POST' as const,
46
+ DELEGATIONS_VERIFY: 'POST' as const,
47
+ DELEGATIONS_GET: 'GET' as const,
48
+ DELEGATIONS_CREATE: 'POST' as const,
49
+ DELEGATIONS_REVOKE: 'POST' as const,
50
+ CONFIG: 'GET' as const,
51
+ } as const;
52
+
53
+ /**
54
+ * Required headers for AgentShield API requests
55
+ */
56
+ export interface AgentShieldAPIHeaders {
57
+ 'Content-Type': 'application/json';
58
+ 'Authorization': `Bearer ${string}`;
59
+ }
60
+
@@ -0,0 +1,70 @@
1
+ /**
2
+ * AgentShield/Bouncer API Contracts
3
+ *
4
+ * Centralized type definitions, validation schemas, and endpoint constants
5
+ * for the AgentShield dashboard API integration.
6
+ *
7
+ * @package @kya-os/contracts/agentshield-api
8
+ */
9
+
10
+ // Type exports
11
+ export type {
12
+ AgentShieldAPIResponse,
13
+ AgentShieldAPIErrorResponse,
14
+ ProofSubmissionRequest,
15
+ ProofSubmissionResponse,
16
+ ToolCallContext,
17
+ ConsentEventContext,
18
+ BouncerOutcome,
19
+ VerifyDelegationRequest,
20
+ VerifyDelegationResponse,
21
+ VerifyDelegationAPIResponse,
22
+ DelegationCredential,
23
+ AgentShieldToolProtection,
24
+ ToolProtectionConfigResponse,
25
+ ToolProtectionConfigAPIResponse,
26
+ CreateDelegationRequest,
27
+ CreateDelegationResponse,
28
+ CreateDelegationAPIResponse,
29
+ RevokeDelegationRequest,
30
+ RevokeDelegationResponse,
31
+ RevokeDelegationAPIResponse,
32
+ } from "./types.js";
33
+
34
+ export { AgentShieldAPIError } from "./types.js";
35
+ export type { AgentShieldAPIHeaders } from "./endpoints.js";
36
+
37
+ export type { ClearCacheRequest, ClearCacheResponse } from "./admin-types.js";
38
+
39
+ // Schema exports
40
+ export {
41
+ agentShieldAPIErrorSchema,
42
+ agentShieldAPIResponseSchema,
43
+ proofSubmissionRequestSchema,
44
+ proofSubmissionResponseSchema,
45
+ delegationCredentialSchema,
46
+ verifyDelegationRequestSchema,
47
+ verifyDelegationResponseSchema,
48
+ verifyDelegationAPIResponseSchema,
49
+ agentShieldToolProtectionSchema,
50
+ toolProtectionConfigResponseSchema,
51
+ toolProtectionConfigAPIResponseSchema,
52
+ createDelegationRequestSchema,
53
+ createDelegationResponseSchema,
54
+ createDelegationAPIResponseSchema,
55
+ revokeDelegationRequestSchema,
56
+ revokeDelegationResponseSchema,
57
+ revokeDelegationAPIResponseSchema,
58
+ } from "./schemas.js";
59
+
60
+ export {
61
+ clearCacheRequestSchema,
62
+ clearCacheResponseSchema,
63
+ } from "./admin-schemas.js";
64
+
65
+ // Endpoint exports
66
+ export {
67
+ AGENTSHIELD_API_BASE,
68
+ AGENTSHIELD_ENDPOINTS,
69
+ AGENTSHIELD_METHODS,
70
+ } from "./endpoints.js";
@@ -0,0 +1,304 @@
1
+ /**
2
+ * AgentShield/Bouncer API Zod Validation Schemas
3
+ *
4
+ * Runtime validation schemas matching the API contract types.
5
+ * These schemas ensure request/response validation before sending/receiving.
6
+ *
7
+ * @package @kya-os/contracts/agentshield-api
8
+ */
9
+
10
+ import { z } from "zod";
11
+ import { DetachedProofSchema } from "../proof.js";
12
+ import { DelegationRecordSchema } from "../delegation/index.js";
13
+
14
+ /**
15
+ * Standard error schema
16
+ */
17
+ export const agentShieldAPIErrorSchema = z.object({
18
+ code: z.string(),
19
+ message: z.string(),
20
+ details: z.record(z.unknown()).optional(),
21
+ });
22
+
23
+ /**
24
+ * Standard API response wrapper schema
25
+ */
26
+ export const agentShieldAPIResponseSchema = <T extends z.ZodTypeAny>(
27
+ dataSchema: T
28
+ ) =>
29
+ z.object({
30
+ success: z.boolean(),
31
+ data: dataSchema,
32
+ metadata: z
33
+ .object({
34
+ requestId: z.string(),
35
+ timestamp: z.string(),
36
+ })
37
+ .optional(),
38
+ });
39
+
40
+ // ============================================================================
41
+ // Proof Submission Schemas
42
+ // ============================================================================
43
+
44
+ /**
45
+ * Tool Call Context Schema (AgentShield Extension)
46
+ * Optional plaintext context for dashboard enrichment
47
+ */
48
+ const toolCallContextSchema = z.object({
49
+ tool: z.string().min(1, "Tool name is required"),
50
+ args: z.record(z.unknown()),
51
+ result: z.unknown().optional(),
52
+ scopeId: z.string().min(1, "scopeId is required to link context to proof"),
53
+ userIdentifier: z.string().optional(),
54
+ });
55
+
56
+ /**
57
+ * Consent Event Context Schema
58
+ * Represents consent-related events for audit tracking
59
+ */
60
+ const consentEventContextSchema = z.object({
61
+ eventType: z.enum([
62
+ "consent:page_viewed",
63
+ "consent:approved",
64
+ "consent:delegation_created",
65
+ "consent:credential_required"
66
+ ]),
67
+ timestamp: z.number().int().positive(),
68
+ sessionId: z.string().min(1),
69
+ userDid: z.string().optional(),
70
+ agentDid: z.string().min(1),
71
+ targetTools: z.array(z.string()).min(1), // ALWAYS array
72
+ scopes: z.array(z.string()).min(0),
73
+ delegationId: z.string().uuid().optional(),
74
+ projectId: z.string().uuid(),
75
+ termsAccepted: z.boolean().optional(),
76
+ credentialStatus: z.enum(["present", "required", "obtained"]).optional(),
77
+ oauthIdentity: z.object({
78
+ provider: z.string(),
79
+ identifier: z.string(),
80
+ }).optional(),
81
+ });
82
+
83
+ /**
84
+ * Proof submission request schema
85
+ */
86
+ export const proofSubmissionRequestSchema = z.object({
87
+ session_id: z.string().max(100), // AgentShield session ID (may differ from MCP-I sessionId)
88
+ delegation_id: z.string().uuid().nullish(),
89
+ proofs: z.array(DetachedProofSchema).min(1),
90
+ // AgentShield extension: Optional context for dashboard enrichment
91
+ context: z
92
+ .object({
93
+ toolCalls: z.array(toolCallContextSchema).optional(),
94
+ consentEvents: z.array(consentEventContextSchema).optional(), // NEW: Consent events for audit tracking
95
+ mcpServerUrl: z.string().url().optional(), // MCP server URL for tool discovery
96
+ })
97
+ .optional(),
98
+ });
99
+
100
+ /**
101
+ * Proof submission response schema
102
+ */
103
+ export const proofSubmissionResponseSchema = z.object({
104
+ success: z.boolean(),
105
+ accepted: z.number().int().min(0),
106
+ rejected: z.number().int().min(0),
107
+ outcomes: z.record(z.string(), z.number().int().min(0)).optional(), // Record<BouncerOutcome, number> - Optional because API may return empty object or omit it
108
+ errors: z
109
+ .array(
110
+ z.object({
111
+ proof_index: z.number().int().min(0),
112
+ error: z.object({
113
+ code: z.string(),
114
+ message: z.string(),
115
+ details: z.record(z.unknown()).optional(),
116
+ }),
117
+ })
118
+ )
119
+ .optional(),
120
+ });
121
+
122
+ // ============================================================================
123
+ // Delegation Verification Schemas
124
+ // ============================================================================
125
+
126
+ /**
127
+ * Delegation credential schema
128
+ */
129
+ export const delegationCredentialSchema = z.object({
130
+ agent_did: z.string(),
131
+ user_id: z.string().optional(),
132
+ user_identifier: z.string().optional(),
133
+ scopes: z.array(z.string()),
134
+ constraints: z.record(z.unknown()).optional(),
135
+ issued_at: z.number().int().positive(),
136
+ created_at: z.number().int().positive(),
137
+ });
138
+
139
+ /**
140
+ * Delegation verification request schema
141
+ */
142
+ export const verifyDelegationRequestSchema = z.object({
143
+ agent_did: z.string(),
144
+ credential_jwt: z.string().optional(), // Optional, omit (don't set to empty string) when not available for OAuth flow
145
+ delegation_token: z.string().optional(), // Optional, for stateless MCP servers
146
+ scopes: z.array(z.string()).optional(), // Optional, can be empty array
147
+ timestamp: z.number().int().positive().optional(),
148
+ client_info: z
149
+ .object({
150
+ ip_address: z.string().ip().optional(),
151
+ origin: z.string().url().optional(),
152
+ user_agent: z.string().optional(),
153
+ })
154
+ .optional(),
155
+ }).partial({ scopes: true }); // Make scopes truly optional by using partial
156
+
157
+ /**
158
+ * Delegation verification response schema
159
+ */
160
+ export const verifyDelegationResponseSchema = z.object({
161
+ valid: z.boolean(),
162
+ delegation: DelegationRecordSchema.optional(),
163
+ delegation_id: z.string().uuid().optional(),
164
+ credential: delegationCredentialSchema.optional(),
165
+ error: agentShieldAPIErrorSchema.optional(),
166
+ reason: z.string().optional(),
167
+ });
168
+
169
+ /**
170
+ * Wrapped verification response schema
171
+ */
172
+ export const verifyDelegationAPIResponseSchema = agentShieldAPIResponseSchema(
173
+ verifyDelegationResponseSchema
174
+ );
175
+
176
+ // ============================================================================
177
+ // Tool Protection Configuration Schemas
178
+ // ============================================================================
179
+
180
+ /**
181
+ * AgentShield tool protection schema (supports both snake_case and camelCase)
182
+ * This is the API-specific format, not the MCP-I spec schema
183
+ */
184
+ export const agentShieldToolProtectionSchema = z
185
+ .object({
186
+ scopes: z.array(z.string()),
187
+ requires_delegation: z.boolean().optional(),
188
+ requiresDelegation: z.boolean().optional(),
189
+ required_scopes: z.array(z.string()).optional(),
190
+ })
191
+ .passthrough(); // Allow additional properties
192
+
193
+ /**
194
+ * Tool protection config response schema
195
+ */
196
+ export const toolProtectionConfigResponseSchema = z.object({
197
+ agent_did: z.string(),
198
+ tools: z.record(z.string(), agentShieldToolProtectionSchema),
199
+ reputation_threshold: z.number().min(0).max(1).optional(),
200
+ denied_agents: z.array(z.string()).optional(),
201
+ crisp_budget: z
202
+ .object({
203
+ max_tokens: z.number(),
204
+ max_cost: z.number(),
205
+ currency: z.string(),
206
+ time_window: z.string(),
207
+ })
208
+ .optional(),
209
+ });
210
+
211
+ /**
212
+ * Wrapped config response schema
213
+ */
214
+ export const toolProtectionConfigAPIResponseSchema =
215
+ agentShieldAPIResponseSchema(toolProtectionConfigResponseSchema);
216
+
217
+ // ============================================================================
218
+ // Delegation Management Schemas
219
+ // ============================================================================
220
+
221
+ /**
222
+ * Create delegation request schema
223
+ *
224
+ * Note: AgentShield API accepts a simplified format, not the full DelegationRecord.
225
+ * The API accepts: agent_did, scopes, expires_in_days, expires_at, session_id, project_id, user_identifier, custom_fields
226
+ *
227
+ * IMPORTANT: expires_in_days and expires_at are mutually exclusive - use one or the other, not both.
228
+ */
229
+ export const createDelegationRequestSchema = z
230
+ .object({
231
+ agent_did: z.string().min(1),
232
+ scopes: z.array(z.string()).min(1),
233
+ expires_in_days: z.number().int().positive().optional(),
234
+ expires_at: z.string().datetime().optional(),
235
+ session_id: z.string().optional(),
236
+ project_id: z.string().uuid().optional(),
237
+ user_identifier: z.string().max(200).optional(), // Matches AgentShield's max(200)
238
+ custom_fields: z.record(z.unknown()).optional(),
239
+ })
240
+ .passthrough()
241
+ .refine(
242
+ (data) => {
243
+ // expires_in_days and expires_at are mutually exclusive
244
+ const hasExpiresInDays = data.expires_in_days !== undefined;
245
+ const hasExpiresAt = data.expires_at !== undefined;
246
+ return !(hasExpiresInDays && hasExpiresAt);
247
+ },
248
+ {
249
+ message:
250
+ "expires_in_days and expires_at are mutually exclusive - use one or the other, not both",
251
+ path: ["expires_in_days", "expires_at"],
252
+ }
253
+ );
254
+
255
+ /**
256
+ * Create delegation response schema
257
+ *
258
+ * Canonical format returned by POST /api/v1/bouncer/delegations
259
+ *
260
+ * IMPORTANT: delegation_token is NOT returned by this endpoint.
261
+ * delegation_token is only available via OAuth callback flow (/api/v1/bouncer/oauth/callback)
262
+ * and is passed as a URL parameter, not in the API response body.
263
+ */
264
+ export const createDelegationResponseSchema = z.object({
265
+ delegation_id: z.string().uuid(),
266
+ agent_did: z.string().min(1),
267
+ user_id: z.string().optional(),
268
+ user_identifier: z.string().optional(),
269
+ scopes: z.array(z.string()),
270
+ status: z.enum(['active', 'expired', 'revoked']), // Matches AgentShield's actual API behavior
271
+ issued_at: z.string().datetime(),
272
+ expires_at: z.string().datetime().nullable().optional(), // AgentShield allows null values
273
+ created_at: z.string().datetime(),
274
+ });
275
+
276
+ /**
277
+ * Wrapped creation response schema
278
+ */
279
+ export const createDelegationAPIResponseSchema = agentShieldAPIResponseSchema(
280
+ createDelegationResponseSchema
281
+ );
282
+
283
+ /**
284
+ * Revoke delegation request schema
285
+ */
286
+ export const revokeDelegationRequestSchema = z.object({
287
+ reason: z.string().optional(),
288
+ });
289
+
290
+ /**
291
+ * Revoke delegation response schema
292
+ */
293
+ export const revokeDelegationResponseSchema = z.object({
294
+ delegation_id: z.string().uuid(),
295
+ revoked: z.boolean(),
296
+ revoked_at: z.number().int().positive(),
297
+ });
298
+
299
+ /**
300
+ * Wrapped revocation response schema
301
+ */
302
+ export const revokeDelegationAPIResponseSchema = agentShieldAPIResponseSchema(
303
+ revokeDelegationResponseSchema
304
+ );