@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,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentShield/Bouncer API Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* TypeScript interfaces matching the AgentShield dashboard API contract.
|
|
5
|
+
* These types ensure parity between xmcp-i clients and the AgentShield service.
|
|
6
|
+
*
|
|
7
|
+
* @package @kya-os/contracts/agentshield-api
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { DetachedProof } from "../proof.js";
|
|
11
|
+
import type { DelegationRecord } from "../delegation/index.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Standard AgentShield API response wrapper
|
|
15
|
+
*/
|
|
16
|
+
export interface AgentShieldAPIResponse<T> {
|
|
17
|
+
success: boolean;
|
|
18
|
+
data: T;
|
|
19
|
+
metadata?: {
|
|
20
|
+
requestId: string;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Standard AgentShield API error response structure
|
|
27
|
+
* (Use AgentShieldAPIError class for runtime errors)
|
|
28
|
+
*/
|
|
29
|
+
export interface AgentShieldAPIErrorResponse {
|
|
30
|
+
code: string;
|
|
31
|
+
message: string;
|
|
32
|
+
details?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Proof Submission API
|
|
37
|
+
// ============================================================================
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Tool Call Context (AgentShield Extension to MCP-I)
|
|
41
|
+
*
|
|
42
|
+
* Optional plaintext context for dashboard enrichment.
|
|
43
|
+
* Links to MCP-I proof via scopeId.
|
|
44
|
+
*/
|
|
45
|
+
export interface ToolCallContext {
|
|
46
|
+
tool: string; // Tool name (e.g., "greet", "searchProducts")
|
|
47
|
+
args: Record<string, unknown>; // Tool arguments from canonical request
|
|
48
|
+
result?: unknown; // Tool result from canonical response (optional)
|
|
49
|
+
scopeId: string; // Links to proof.meta.scopeId
|
|
50
|
+
userIdentifier?: string; // User context (optional)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Consent Event Context
|
|
55
|
+
*
|
|
56
|
+
* Represents consent-related events that occur during the consent flow.
|
|
57
|
+
* These events are logged separately from tool executions and allow
|
|
58
|
+
* multiple events per session (unlike regular audit logs).
|
|
59
|
+
*/
|
|
60
|
+
export interface ConsentEventContext {
|
|
61
|
+
eventType: "consent:page_viewed" | "consent:approved" | "consent:delegation_created" | "consent:credential_required";
|
|
62
|
+
timestamp: number;
|
|
63
|
+
sessionId: string;
|
|
64
|
+
userDid?: string;
|
|
65
|
+
agentDid: string;
|
|
66
|
+
targetTools: string[]; // ALWAYS array, even for single tool
|
|
67
|
+
scopes: string[];
|
|
68
|
+
delegationId?: string;
|
|
69
|
+
projectId: string;
|
|
70
|
+
termsAccepted?: boolean;
|
|
71
|
+
credentialStatus?: "present" | "required" | "obtained";
|
|
72
|
+
oauthIdentity?: {
|
|
73
|
+
provider: string;
|
|
74
|
+
identifier: string;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Request body for proof submission endpoint
|
|
80
|
+
* POST /api/v1/bouncer/proofs
|
|
81
|
+
*/
|
|
82
|
+
export interface ProofSubmissionRequest {
|
|
83
|
+
/** Delegation ID (nullable, optional - null if no delegation context) */
|
|
84
|
+
delegation_id?: string | null;
|
|
85
|
+
|
|
86
|
+
/** Session ID for grouping proofs (AgentShield session ID, may differ from MCP-I sessionId) */
|
|
87
|
+
session_id: string;
|
|
88
|
+
|
|
89
|
+
/** Array of proofs to submit */
|
|
90
|
+
proofs: DetachedProof[];
|
|
91
|
+
|
|
92
|
+
/** AgentShield extension: Optional context for dashboard enrichment */
|
|
93
|
+
context?: {
|
|
94
|
+
toolCalls?: ToolCallContext[];
|
|
95
|
+
consentEvents?: ConsentEventContext[]; // NEW: Consent events for audit tracking
|
|
96
|
+
mcpServerUrl?: string; // MCP server URL for tool discovery
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Bouncer outcome types
|
|
102
|
+
*/
|
|
103
|
+
export type BouncerOutcome = "success" | "failed" | "blocked" | "error";
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Response from proof submission endpoint
|
|
107
|
+
*/
|
|
108
|
+
export interface ProofSubmissionResponse {
|
|
109
|
+
success: boolean;
|
|
110
|
+
accepted: number;
|
|
111
|
+
rejected: number;
|
|
112
|
+
outcomes?: Record<BouncerOutcome, number>; // Optional - API may omit or return empty object
|
|
113
|
+
errors?: Array<{
|
|
114
|
+
proof_index: number;
|
|
115
|
+
error: {
|
|
116
|
+
code: string;
|
|
117
|
+
message: string;
|
|
118
|
+
details?: Record<string, unknown>;
|
|
119
|
+
};
|
|
120
|
+
}>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ============================================================================
|
|
124
|
+
// Delegation Verification API
|
|
125
|
+
// ============================================================================
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Request body for delegation verification endpoint
|
|
129
|
+
* POST /api/v1/bouncer/delegations/verify
|
|
130
|
+
*/
|
|
131
|
+
export interface VerifyDelegationRequest {
|
|
132
|
+
/** Agent DID to verify */
|
|
133
|
+
agent_did: string;
|
|
134
|
+
|
|
135
|
+
/** Credential JWT (optional, defaults to empty string for OAuth flow) */
|
|
136
|
+
credential_jwt?: string;
|
|
137
|
+
|
|
138
|
+
/** Delegation token from OAuth flow (optional, for stateless MCP servers) */
|
|
139
|
+
delegation_token?: string;
|
|
140
|
+
|
|
141
|
+
/** Required scopes (optional, can be empty array) */
|
|
142
|
+
scopes?: string[];
|
|
143
|
+
|
|
144
|
+
/** Optional timestamp for verification */
|
|
145
|
+
timestamp?: number;
|
|
146
|
+
|
|
147
|
+
/** Optional client info for IP/origin checking */
|
|
148
|
+
client_info?: {
|
|
149
|
+
ip_address?: string;
|
|
150
|
+
origin?: string;
|
|
151
|
+
user_agent?: string;
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Credential information returned in verification response
|
|
157
|
+
*/
|
|
158
|
+
export interface DelegationCredential {
|
|
159
|
+
agent_did: string;
|
|
160
|
+
user_id?: string;
|
|
161
|
+
user_identifier?: string;
|
|
162
|
+
scopes: string[];
|
|
163
|
+
constraints?: Record<string, unknown>;
|
|
164
|
+
issued_at: number;
|
|
165
|
+
created_at: number;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Response from delegation verification endpoint
|
|
170
|
+
*/
|
|
171
|
+
export interface VerifyDelegationResponse {
|
|
172
|
+
valid: boolean;
|
|
173
|
+
delegation?: DelegationRecord;
|
|
174
|
+
delegation_id?: string;
|
|
175
|
+
credential?: DelegationCredential;
|
|
176
|
+
error?: AgentShieldAPIErrorResponse;
|
|
177
|
+
reason?: string;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Wrapped verification response (AgentShield wraps in success/data)
|
|
182
|
+
*/
|
|
183
|
+
export type VerifyDelegationAPIResponse =
|
|
184
|
+
AgentShieldAPIResponse<VerifyDelegationResponse>;
|
|
185
|
+
|
|
186
|
+
// ============================================================================
|
|
187
|
+
// Tool Protection Configuration API
|
|
188
|
+
// ============================================================================
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* AgentShield API tool protection format for a single tool
|
|
192
|
+
* This is the API-specific format, not the MCP-I spec type
|
|
193
|
+
*/
|
|
194
|
+
export interface AgentShieldToolProtection {
|
|
195
|
+
scopes: string[];
|
|
196
|
+
requires_delegation?: boolean;
|
|
197
|
+
requiresDelegation?: boolean; // Support both snake_case and camelCase
|
|
198
|
+
required_scopes?: string[]; // Alternative naming
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Response from tool protection config endpoint
|
|
203
|
+
* GET /api/v1/bouncer/projects/{projectId}/config
|
|
204
|
+
*/
|
|
205
|
+
export interface ToolProtectionConfigResponse {
|
|
206
|
+
agent_did: string;
|
|
207
|
+
tools: Record<string, AgentShieldToolProtection>;
|
|
208
|
+
reputation_threshold?: number;
|
|
209
|
+
denied_agents?: string[];
|
|
210
|
+
crisp_budget?: {
|
|
211
|
+
max_tokens: number;
|
|
212
|
+
max_cost: number;
|
|
213
|
+
currency: string;
|
|
214
|
+
time_window: string;
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Wrapped config response
|
|
220
|
+
*/
|
|
221
|
+
export type ToolProtectionConfigAPIResponse =
|
|
222
|
+
AgentShieldAPIResponse<ToolProtectionConfigResponse>;
|
|
223
|
+
|
|
224
|
+
// ============================================================================
|
|
225
|
+
// Delegation Management API
|
|
226
|
+
// ============================================================================
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Request body for creating a delegation
|
|
230
|
+
* POST /api/v1/bouncer/delegations
|
|
231
|
+
*
|
|
232
|
+
* Note: AgentShield API accepts a simplified format, not the full DelegationRecord.
|
|
233
|
+
* The API accepts: agent_did, scopes, expires_in_days, expires_at, session_id, project_id, user_identifier, custom_fields
|
|
234
|
+
*
|
|
235
|
+
* IMPORTANT: expires_in_days and expires_at are mutually exclusive - use one or the other, not both.
|
|
236
|
+
*/
|
|
237
|
+
export interface CreateDelegationRequest {
|
|
238
|
+
agent_did: string;
|
|
239
|
+
scopes: string[];
|
|
240
|
+
/** Number of days until expiration (1-365). Mutually exclusive with expires_at. */
|
|
241
|
+
expires_in_days?: number;
|
|
242
|
+
/** ISO 8601 datetime when delegation expires. Mutually exclusive with expires_in_days. */
|
|
243
|
+
expires_at?: string;
|
|
244
|
+
session_id?: string;
|
|
245
|
+
project_id?: string; // Usually extracted from API key, but can be provided
|
|
246
|
+
/** User identifier string, max 200 chars, optional */
|
|
247
|
+
user_identifier?: string;
|
|
248
|
+
custom_fields?: Record<string, unknown>;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Response from delegation creation endpoint
|
|
253
|
+
*
|
|
254
|
+
* Canonical format returned by POST /api/v1/bouncer/delegations
|
|
255
|
+
*
|
|
256
|
+
* IMPORTANT: delegation_token is NOT returned by this endpoint.
|
|
257
|
+
* delegation_token is only available via OAuth callback flow (/api/v1/bouncer/oauth/callback)
|
|
258
|
+
* and is passed as a URL parameter, not in the API response body.
|
|
259
|
+
*/
|
|
260
|
+
export interface CreateDelegationResponse {
|
|
261
|
+
delegation_id: string;
|
|
262
|
+
agent_did: string;
|
|
263
|
+
user_id?: string;
|
|
264
|
+
user_identifier?: string;
|
|
265
|
+
scopes: string[];
|
|
266
|
+
status: "active" | "expired" | "revoked"; // Matches AgentShield's actual API behavior
|
|
267
|
+
issued_at: string; // ISO 8601 datetime
|
|
268
|
+
expires_at?: string | null; // ISO 8601 datetime, nullable
|
|
269
|
+
created_at: string; // ISO 8601 datetime
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Wrapped creation response
|
|
274
|
+
*/
|
|
275
|
+
export type CreateDelegationAPIResponse =
|
|
276
|
+
AgentShieldAPIResponse<CreateDelegationResponse>;
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Request body for revoking a delegation
|
|
280
|
+
* POST /api/v1/bouncer/delegations/{id}/revoke
|
|
281
|
+
*/
|
|
282
|
+
export interface RevokeDelegationRequest {
|
|
283
|
+
reason?: string;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Response from delegation revocation endpoint
|
|
288
|
+
*/
|
|
289
|
+
export interface RevokeDelegationResponse {
|
|
290
|
+
delegation_id: string;
|
|
291
|
+
revoked: boolean;
|
|
292
|
+
revoked_at: number;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Wrapped revocation response
|
|
297
|
+
*/
|
|
298
|
+
export type RevokeDelegationAPIResponse =
|
|
299
|
+
AgentShieldAPIResponse<RevokeDelegationResponse>;
|
|
300
|
+
|
|
301
|
+
// ============================================================================
|
|
302
|
+
// Error Types
|
|
303
|
+
// ============================================================================
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* AgentShield API error class
|
|
307
|
+
*/
|
|
308
|
+
export class AgentShieldAPIError extends Error {
|
|
309
|
+
constructor(
|
|
310
|
+
public readonly code: string,
|
|
311
|
+
message: string,
|
|
312
|
+
public readonly details?: Record<string, unknown>
|
|
313
|
+
) {
|
|
314
|
+
super(message);
|
|
315
|
+
this.name = "AgentShieldAPIError";
|
|
316
|
+
}
|
|
317
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Types and Schemas
|
|
3
|
+
*
|
|
4
|
+
* Types and Zod schemas for audit logging in the MCP-I framework.
|
|
5
|
+
* These types are platform-agnostic and used across all implementations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import type { AgentIdentity } from "../config/identity.js";
|
|
10
|
+
import type { SessionContext } from "../handshake.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Audit context schema for logging audit records
|
|
14
|
+
*
|
|
15
|
+
* Contains all metadata needed to generate an audit record.
|
|
16
|
+
* Privacy Note: Only metadata is extracted from these objects.
|
|
17
|
+
* The identity's private key, session's nonce, and other sensitive
|
|
18
|
+
* fields are NEVER included in the audit log.
|
|
19
|
+
*/
|
|
20
|
+
export const AuditContextSchema = z.object({
|
|
21
|
+
/**
|
|
22
|
+
* Agent identity
|
|
23
|
+
* Only `did` and `keyId` are logged. Private key is NEVER logged.
|
|
24
|
+
*/
|
|
25
|
+
identity: z
|
|
26
|
+
.object({
|
|
27
|
+
did: z.string().min(1),
|
|
28
|
+
kid: z.string().min(1),
|
|
29
|
+
})
|
|
30
|
+
.passthrough(), // Allow additional fields but only did/kid are used
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Session context
|
|
34
|
+
* Only `sessionId` and `audience` are logged. Nonce is NEVER logged.
|
|
35
|
+
*/
|
|
36
|
+
session: z
|
|
37
|
+
.object({
|
|
38
|
+
sessionId: z.string().min(1),
|
|
39
|
+
audience: z.string().min(1),
|
|
40
|
+
})
|
|
41
|
+
.passthrough(), // Allow additional fields but only sessionId/audience are used
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Request hash (SHA-256 with `sha256:` prefix)
|
|
45
|
+
*/
|
|
46
|
+
requestHash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Response hash (SHA-256 with `sha256:` prefix)
|
|
50
|
+
*/
|
|
51
|
+
responseHash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Verification result
|
|
55
|
+
* - 'yes': Proof was verified successfully
|
|
56
|
+
* - 'no': Proof verification failed
|
|
57
|
+
*/
|
|
58
|
+
verified: z.enum(["yes", "no"]),
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Optional scope identifier
|
|
62
|
+
* Application-level scope (e.g., 'orders.create', 'users.read').
|
|
63
|
+
* If not provided, '-' is used in the audit log.
|
|
64
|
+
*/
|
|
65
|
+
scopeId: z.string().optional(),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export type AuditContext = {
|
|
69
|
+
identity: AgentIdentity;
|
|
70
|
+
session: SessionContext;
|
|
71
|
+
requestHash: string;
|
|
72
|
+
responseHash: string;
|
|
73
|
+
verified: "yes" | "no";
|
|
74
|
+
scopeId?: string;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Event context schema for logging events that bypass session deduplication
|
|
79
|
+
*
|
|
80
|
+
* Used for consent events where multiple events occur in the same session.
|
|
81
|
+
* Unlike AuditContext, this allows multiple events per session.
|
|
82
|
+
*/
|
|
83
|
+
export const AuditEventContextSchema = z.object({
|
|
84
|
+
/**
|
|
85
|
+
* Event type identifier
|
|
86
|
+
* @example "consent:page_viewed", "consent:approved", "runtime:initialized"
|
|
87
|
+
*/
|
|
88
|
+
eventType: z.string().min(1),
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Agent identity
|
|
92
|
+
* Only `did` and `keyId` are logged. Private key is NEVER logged.
|
|
93
|
+
*/
|
|
94
|
+
identity: z
|
|
95
|
+
.object({
|
|
96
|
+
did: z.string().min(1),
|
|
97
|
+
kid: z.string().min(1),
|
|
98
|
+
})
|
|
99
|
+
.passthrough(), // Allow additional fields but only did/kid are used
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Session context
|
|
103
|
+
* Only `sessionId` and `audience` are logged. Nonce is NEVER logged.
|
|
104
|
+
*/
|
|
105
|
+
session: z
|
|
106
|
+
.object({
|
|
107
|
+
sessionId: z.string().min(1),
|
|
108
|
+
audience: z.string().min(1),
|
|
109
|
+
})
|
|
110
|
+
.passthrough(), // Allow additional fields but only sessionId/audience are used
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Optional event-specific data
|
|
114
|
+
* Used for generating event hash. Not logged directly.
|
|
115
|
+
*/
|
|
116
|
+
eventData: z.record(z.unknown()).optional(),
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
export type AuditEventContext = {
|
|
120
|
+
eventType: string;
|
|
121
|
+
identity: AgentIdentity;
|
|
122
|
+
session: SessionContext;
|
|
123
|
+
eventData?: Record<string, any>;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Re-export AuditRecord from proof module
|
|
127
|
+
export type { AuditRecord } from "../proof.js";
|
|
128
|
+
export { AuditRecordSchema } from "../proof.js";
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CLI command schemas and results
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* CLI Identity File Format Schema
|
|
9
|
+
*
|
|
10
|
+
* Format for identity.json files stored on disk.
|
|
11
|
+
* Used by CLI tools for identity management.
|
|
12
|
+
*/
|
|
13
|
+
export const CLIIdentityFileSchema = z.object({
|
|
14
|
+
version: z.literal("1.0"),
|
|
15
|
+
did: z.string().min(1),
|
|
16
|
+
// Accept both kid and keyId for backward compatibility with pre-1.3 identity files
|
|
17
|
+
kid: z.string().min(1).optional(),
|
|
18
|
+
keyId: z.string().min(1).optional(),
|
|
19
|
+
privateKey: z.string().regex(/^[A-Za-z0-9+/]{43}=$/, "Must be a valid base64-encoded Ed25519 private key (44 characters)"),
|
|
20
|
+
publicKey: z.string().regex(/^[A-Za-z0-9+/]{43}=$/, "Must be a valid base64-encoded Ed25519 public key (44 characters)"),
|
|
21
|
+
createdAt: z.string().datetime(),
|
|
22
|
+
lastRotated: z.string().datetime().optional(),
|
|
23
|
+
}).refine(
|
|
24
|
+
(data) => data.kid || data.keyId,
|
|
25
|
+
{
|
|
26
|
+
message: "Either kid or keyId must be provided",
|
|
27
|
+
}
|
|
28
|
+
).transform((data) => ({
|
|
29
|
+
version: data.version,
|
|
30
|
+
did: data.did,
|
|
31
|
+
kid: data.kid || data.keyId!,
|
|
32
|
+
privateKey: data.privateKey,
|
|
33
|
+
publicKey: data.publicKey,
|
|
34
|
+
createdAt: data.createdAt,
|
|
35
|
+
lastRotated: data.lastRotated,
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
export const KeyRotationResultSchema = z.object({
|
|
39
|
+
success: z.boolean(),
|
|
40
|
+
oldKeyId: z.string().min(1),
|
|
41
|
+
newKeyId: z.string().min(1),
|
|
42
|
+
did: z.string().min(1),
|
|
43
|
+
mode: z.enum(["dev", "prod"]),
|
|
44
|
+
delegated: z.boolean(),
|
|
45
|
+
forced: z.boolean(),
|
|
46
|
+
auditLine: z.string().min(1),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export const StatusReportSchema = z.object({
|
|
50
|
+
did: z.string().min(1),
|
|
51
|
+
kid: z.string().min(1), // Changed from keyId to kid for spec compliance
|
|
52
|
+
ktaURL: z.string().url(),
|
|
53
|
+
mirrorStatus: z.enum(["pending", "success", "error"]),
|
|
54
|
+
lastHandshake: z.number().int().positive().optional(),
|
|
55
|
+
environment: z.enum(["dev", "prod"]),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const PackageInfoSchema = z.object({
|
|
59
|
+
name: z.string(),
|
|
60
|
+
version: z.string(),
|
|
61
|
+
compatible: z.boolean(),
|
|
62
|
+
issues: z.array(z.string()).optional(),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export const XMCPUpstreamInfoSchema = z.object({
|
|
66
|
+
version: z.string(),
|
|
67
|
+
compatible: z.boolean(),
|
|
68
|
+
issues: z.array(z.string()).optional(),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
export const EnvironmentInfoSchema = z.object({
|
|
72
|
+
valid: z.boolean(),
|
|
73
|
+
missing: z.array(z.string()),
|
|
74
|
+
issues: z.array(z.string()).optional(),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
export const KTAInfoSchema = z.object({
|
|
78
|
+
reachable: z.boolean(),
|
|
79
|
+
authenticated: z.boolean(),
|
|
80
|
+
issues: z.array(z.string()).optional(),
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
export const CacheInfoSchema = z.object({
|
|
84
|
+
type: z.string(),
|
|
85
|
+
functional: z.boolean(),
|
|
86
|
+
issues: z.array(z.string()).optional(),
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
export const DoctorResultSchema = z.object({
|
|
90
|
+
packages: z.array(PackageInfoSchema),
|
|
91
|
+
xmcpUpstream: XMCPUpstreamInfoSchema,
|
|
92
|
+
environment: EnvironmentInfoSchema,
|
|
93
|
+
kta: KTAInfoSchema,
|
|
94
|
+
cache: CacheInfoSchema,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
export const ScaffolderOptionsSchema = z.object({
|
|
98
|
+
projectName: z.string().min(1),
|
|
99
|
+
xmcpVersion: z.string().optional(),
|
|
100
|
+
xmcpChannel: z.enum(["latest", "next"]).optional(),
|
|
101
|
+
noIdentity: z.boolean().default(false),
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
export const ScaffolderResultSchema = z.object({
|
|
105
|
+
success: z.boolean(),
|
|
106
|
+
projectPath: z.string().min(1),
|
|
107
|
+
xmcpVersion: z.string().min(1),
|
|
108
|
+
identityEnabled: z.boolean(),
|
|
109
|
+
warnings: z.array(z.string()).optional(),
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Type exports
|
|
113
|
+
export type CLIIdentityFile = z.infer<typeof CLIIdentityFileSchema>;
|
|
114
|
+
export type KeyRotationResult = z.infer<typeof KeyRotationResultSchema>;
|
|
115
|
+
export type StatusReport = z.infer<typeof StatusReportSchema>;
|
|
116
|
+
export type PackageInfo = z.infer<typeof PackageInfoSchema>;
|
|
117
|
+
export type XMCPUpstreamInfo = z.infer<typeof XMCPUpstreamInfoSchema>;
|
|
118
|
+
export type EnvironmentInfo = z.infer<typeof EnvironmentInfoSchema>;
|
|
119
|
+
export type KTAInfo = z.infer<typeof KTAInfoSchema>;
|
|
120
|
+
export type CacheInfo = z.infer<typeof CacheInfoSchema>;
|
|
121
|
+
export type DoctorResult = z.infer<typeof DoctorResultSchema>;
|
|
122
|
+
export type ScaffolderOptions = z.infer<typeof ScaffolderOptionsSchema>;
|
|
123
|
+
export type ScaffolderResult = z.infer<typeof ScaffolderResultSchema>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @deprecated Use CLIIdentityFile instead
|
|
127
|
+
* This export is maintained for backward compatibility
|
|
128
|
+
*/
|
|
129
|
+
export type IdentityConfig = CLIIdentityFile;
|
|
130
|
+
|
|
131
|
+
// Error codes as string literal union
|
|
132
|
+
export const ERROR_CODES = {
|
|
133
|
+
XMCP_I_EBADPROOF: "XMCP_I_EBADPROOF",
|
|
134
|
+
XMCP_I_ENOIDENTITY: "XMCP_I_ENOIDENTITY",
|
|
135
|
+
XMCP_I_EMIRRORPENDING: "XMCP_I_EMIRRORPENDING",
|
|
136
|
+
XMCP_I_EHANDSHAKE: "XMCP_I_EHANDSHAKE",
|
|
137
|
+
XMCP_I_ESESSION: "XMCP_I_ESESSION",
|
|
138
|
+
XMCP_I_ECLAIM: "XMCP_I_ECLAIM",
|
|
139
|
+
XMCP_I_ECONFIG: "XMCP_I_ECONFIG",
|
|
140
|
+
XMCP_I_ERUNTIME: "XMCP_I_ERUNTIME",
|
|
141
|
+
} as const;
|
|
142
|
+
|
|
143
|
+
export type ErrorCode = keyof typeof ERROR_CODES;
|
|
144
|
+
|
|
145
|
+
// CLI exit codes
|
|
146
|
+
export const CLI_EXIT_CODES = {
|
|
147
|
+
SUCCESS: 0,
|
|
148
|
+
GENERAL_ERROR: 1,
|
|
149
|
+
BADPROOF: 20,
|
|
150
|
+
NOIDENTITY: 21,
|
|
151
|
+
HANDSHAKE: 22,
|
|
152
|
+
SESSION: 23,
|
|
153
|
+
CLAIM: 24,
|
|
154
|
+
CONFIG: 25,
|
|
155
|
+
RUNTIME: 26,
|
|
156
|
+
} as const;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Configuration Types
|
|
3
|
+
*
|
|
4
|
+
* Shared configuration interfaces that are platform-agnostic and used
|
|
5
|
+
* across all XMCP-I implementations. These form the foundation of the
|
|
6
|
+
* configuration hierarchy.
|
|
7
|
+
*
|
|
8
|
+
* @module @kya-os/contracts/config
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Base configuration shared across ALL platforms
|
|
13
|
+
*
|
|
14
|
+
* This interface defines the core configuration options that are
|
|
15
|
+
* universally applicable regardless of the runtime platform (Node.js,
|
|
16
|
+
* Cloudflare Workers, etc.).
|
|
17
|
+
*/
|
|
18
|
+
export interface MCPIBaseConfig {
|
|
19
|
+
/**
|
|
20
|
+
* Runtime environment setting
|
|
21
|
+
* - 'development': Enables debug logging, dev identity, relaxed security
|
|
22
|
+
* - 'production': Production security, identity from env vars, minimal logging
|
|
23
|
+
*/
|
|
24
|
+
environment: 'development' | 'production';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Session configuration
|
|
28
|
+
* Controls how sessions are managed and validated
|
|
29
|
+
*/
|
|
30
|
+
session?: {
|
|
31
|
+
/**
|
|
32
|
+
* Maximum time skew allowed for timestamp validation (in seconds)
|
|
33
|
+
* Helps handle clock drift between client and server
|
|
34
|
+
* @default 120
|
|
35
|
+
*/
|
|
36
|
+
timestampSkewSeconds?: number;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Session time-to-live in minutes
|
|
40
|
+
* How long a session remains valid after creation
|
|
41
|
+
* @default 30
|
|
42
|
+
*/
|
|
43
|
+
ttlMinutes?: number;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Absolute session lifetime in minutes (optional)
|
|
47
|
+
* Maximum lifetime regardless of activity
|
|
48
|
+
*/
|
|
49
|
+
absoluteLifetime?: number;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Audit logging configuration
|
|
54
|
+
* Controls what gets logged for security and compliance
|
|
55
|
+
*/
|
|
56
|
+
audit?: {
|
|
57
|
+
/**
|
|
58
|
+
* Enable audit logging
|
|
59
|
+
* @default true in production, false in development
|
|
60
|
+
*/
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Include proof hashes in audit logs
|
|
65
|
+
* Useful for cryptographic verification but increases log size
|
|
66
|
+
* @default false
|
|
67
|
+
*/
|
|
68
|
+
includeProofHashes?: boolean;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Include full payloads in audit logs
|
|
72
|
+
* WARNING: May include sensitive data
|
|
73
|
+
* @default false
|
|
74
|
+
*/
|
|
75
|
+
includePayloads?: boolean;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Custom log function for audit records
|
|
79
|
+
* If not provided, uses console.log
|
|
80
|
+
*/
|
|
81
|
+
logFunction?: (record: string) => void;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Well-known endpoints configuration
|
|
86
|
+
* Controls the /.well-known/* endpoints for identity discovery
|
|
87
|
+
*/
|
|
88
|
+
wellKnown?: {
|
|
89
|
+
/**
|
|
90
|
+
* Enable well-known endpoints
|
|
91
|
+
* @default true
|
|
92
|
+
*/
|
|
93
|
+
enabled: boolean;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Service name advertised in well-known endpoints
|
|
97
|
+
* @default 'MCP-I Service'
|
|
98
|
+
*/
|
|
99
|
+
serviceName?: string;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Service endpoint URL
|
|
103
|
+
* @default 'https://example.com'
|
|
104
|
+
*/
|
|
105
|
+
serviceEndpoint?: string;
|
|
106
|
+
};
|
|
107
|
+
}
|