@sealkeeper/schema 0.0.1 → 0.4.0
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/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +14 -1
- package/dist/agent-id.d.ts +13 -0
- package/dist/agent-id.js +29 -0
- package/dist/agent-name.d.ts +9 -0
- package/dist/agent-name.js +58 -0
- package/dist/api.d.ts +1207 -0
- package/dist/api.js +624 -0
- package/dist/base64url.d.ts +4 -0
- package/dist/base64url.js +43 -0
- package/dist/credential.d.ts +392 -0
- package/dist/credential.js +287 -0
- package/dist/db/agent-renames.d.ts +126 -0
- package/dist/db/agent-renames.js +20 -0
- package/dist/db/agents.d.ts +145 -0
- package/dist/db/agents.js +40 -0
- package/dist/db/client.d.ts +1893 -0
- package/dist/db/client.js +34 -0
- package/dist/db/credentials.d.ts +143 -0
- package/dist/db/credentials.js +16 -0
- package/dist/db/deleted-operators.d.ts +75 -0
- package/dist/db/deleted-operators.js +13 -0
- package/dist/db/events.d.ts +160 -0
- package/dist/db/events.js +34 -0
- package/dist/db/feed-items.d.ts +109 -0
- package/dist/db/feed-items.js +16 -0
- package/dist/db/index.d.ts +56 -0
- package/dist/db/index.js +23 -0
- package/dist/db/migrate.d.ts +1 -0
- package/dist/db/migrate.js +30 -0
- package/dist/db/migrator.d.ts +2 -0
- package/dist/db/migrator.js +20 -0
- package/dist/db/operators.d.ts +109 -0
- package/dist/db/operators.js +11 -0
- package/dist/db/quota-counters.d.ts +109 -0
- package/dist/db/quota-counters.js +17 -0
- package/dist/db/ratings.d.ts +160 -0
- package/dist/db/ratings.js +27 -0
- package/dist/db/scores.d.ts +160 -0
- package/dist/db/scores.js +15 -0
- package/dist/db/standing.d.ts +228 -0
- package/dist/db/standing.js +29 -0
- package/dist/db/task-outcomes.d.ts +126 -0
- package/dist/db/task-outcomes.js +18 -0
- package/dist/db/tasks.d.ts +251 -0
- package/dist/db/tasks.js +49 -0
- package/dist/db/timestamps.d.ts +4 -0
- package/dist/db/timestamps.js +24 -0
- package/dist/db/url.d.ts +12 -0
- package/dist/db/url.js +25 -0
- package/dist/dimensions.d.ts +21 -0
- package/dist/dimensions.js +15 -0
- package/dist/envelope.d.ts +16 -0
- package/dist/envelope.js +70 -0
- package/dist/events.d.ts +153 -0
- package/dist/events.js +98 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/seal-conformance.d.ts +14 -0
- package/dist/seal-conformance.js +176 -0
- package/dist/standing.d.ts +46 -0
- package/dist/standing.js +79 -0
- package/dist/tasks.d.ts +49 -0
- package/dist/tasks.js +102 -0
- package/dist/top-dimensions.d.ts +9 -0
- package/dist/top-dimensions.js +13 -0
- package/package.json +69 -5
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const CREDENTIAL_ISSUER = "sealkeeper.run";
|
|
3
|
+
export declare const LEGACY_ISSUERS: readonly ['vouched.run'];
|
|
4
|
+
export declare const LEGACY_ISSUER_UNTIL: number;
|
|
5
|
+
export declare function acceptedIssuer(iss: unknown, nowSeconds: number): boolean;
|
|
6
|
+
export declare const WELL_KNOWN_PATH = "/.well-known/seal.json";
|
|
7
|
+
export declare const LEGACY_WELL_KNOWN_PATH = "/.well-known/vouched.json";
|
|
8
|
+
export declare const WELL_KNOWN_URL = "https://sealkeeper.run/.well-known/seal.json";
|
|
9
|
+
export declare const LEGACY_WELL_KNOWN_URL = "https://vouched.run/.well-known/vouched.json";
|
|
10
|
+
export declare const SEAL_EXTENSION_URI = "https://sealkeeper.run/ext/seal/v1";
|
|
11
|
+
export declare const LEGACY_SEAL_EXTENSION_URI = "https://vouched.run/ext/seal/v1";
|
|
12
|
+
export declare const CREDENTIAL_EXTENSION_URI = "https://vouched.run/ext/credential/v1";
|
|
13
|
+
export declare const LEGACY_SEAL_EXTENSION_URIS: readonly string[];
|
|
14
|
+
export declare const SEAL_EXTENSION_URIS: readonly string[];
|
|
15
|
+
export declare const SEAL_VERSION = 1;
|
|
16
|
+
export declare const LEGACY_UNTIL: number;
|
|
17
|
+
export declare const IdentityKind: z.ZodUnion<readonly [z.ZodEnum<{
|
|
18
|
+
kya: "kya";
|
|
19
|
+
oidc: "oidc";
|
|
20
|
+
saml: "saml";
|
|
21
|
+
verifiable_credential: "verifiable_credential";
|
|
22
|
+
}>, z.ZodURL]>;
|
|
23
|
+
export type IdentityKind = z.infer<typeof IdentityKind>;
|
|
24
|
+
export declare const IdentityReference: z.ZodObject<{
|
|
25
|
+
provider: z.ZodURL;
|
|
26
|
+
kind: z.ZodUnion<readonly [z.ZodEnum<{
|
|
27
|
+
kya: "kya";
|
|
28
|
+
oidc: "oidc";
|
|
29
|
+
saml: "saml";
|
|
30
|
+
verifiable_credential: "verifiable_credential";
|
|
31
|
+
}>, z.ZodURL]>;
|
|
32
|
+
ref: z.ZodString;
|
|
33
|
+
subject_hash: z.ZodString;
|
|
34
|
+
attested_at: z.ZodInt;
|
|
35
|
+
scope: z.ZodEnum<{
|
|
36
|
+
agent: "agent";
|
|
37
|
+
operator: "operator";
|
|
38
|
+
}>;
|
|
39
|
+
}, z.core.$strict>;
|
|
40
|
+
export type IdentityReference = z.infer<typeof IdentityReference>;
|
|
41
|
+
export declare const operatorVerified: (identity: readonly IdentityReference[]) => boolean;
|
|
42
|
+
export declare const SEAL_MAX_TTL_SECONDS: number;
|
|
43
|
+
export declare const SEAL_CLOCK_SKEW_SECONDS = 300;
|
|
44
|
+
export declare const CredentialPayload: z.ZodObject<{
|
|
45
|
+
iss: z.ZodLiteral<"sealkeeper.run">;
|
|
46
|
+
sub: z.ZodString;
|
|
47
|
+
ver: z.ZodLiteral<1>;
|
|
48
|
+
iat: z.ZodInt;
|
|
49
|
+
exp: z.ZodInt;
|
|
50
|
+
agent_version: z.ZodString;
|
|
51
|
+
version: z.ZodString;
|
|
52
|
+
level: z.ZodEnum<{
|
|
53
|
+
bronze: "bronze";
|
|
54
|
+
gold: "gold";
|
|
55
|
+
none: "none";
|
|
56
|
+
silver: "silver";
|
|
57
|
+
}>;
|
|
58
|
+
scores: z.ZodRecord<z.ZodUnion<readonly [z.ZodEnum<{
|
|
59
|
+
cost_latency: "cost_latency";
|
|
60
|
+
provenance: "provenance";
|
|
61
|
+
reliability: "reliability";
|
|
62
|
+
safety: "safety";
|
|
63
|
+
}>, z.ZodTemplateLiteral<`competence:${string}`>]> & z.core.$partial, z.ZodNullable<z.ZodNumber>>;
|
|
64
|
+
counts: z.ZodObject<{
|
|
65
|
+
events: z.ZodInt;
|
|
66
|
+
history_days: z.ZodInt;
|
|
67
|
+
verified_tasks: z.ZodInt;
|
|
68
|
+
seed_tasks: z.ZodInt;
|
|
69
|
+
server_checked_tasks: z.ZodInt;
|
|
70
|
+
confirmed_tasks: z.ZodInt;
|
|
71
|
+
distinct_operators: z.ZodInt;
|
|
72
|
+
safety_incidents_90d: z.ZodInt;
|
|
73
|
+
}, z.core.$strict>;
|
|
74
|
+
operator: z.ZodObject<{
|
|
75
|
+
verified: z.ZodBoolean;
|
|
76
|
+
}, z.core.$strict>;
|
|
77
|
+
identity: z.ZodArray<z.ZodObject<{
|
|
78
|
+
provider: z.ZodURL;
|
|
79
|
+
kind: z.ZodUnion<readonly [z.ZodEnum<{
|
|
80
|
+
kya: "kya";
|
|
81
|
+
oidc: "oidc";
|
|
82
|
+
saml: "saml";
|
|
83
|
+
verifiable_credential: "verifiable_credential";
|
|
84
|
+
}>, z.ZodURL]>;
|
|
85
|
+
ref: z.ZodString;
|
|
86
|
+
subject_hash: z.ZodString;
|
|
87
|
+
attested_at: z.ZodInt;
|
|
88
|
+
scope: z.ZodEnum<{
|
|
89
|
+
agent: "agent";
|
|
90
|
+
operator: "operator";
|
|
91
|
+
}>;
|
|
92
|
+
}, z.core.$strict>>;
|
|
93
|
+
last_active: z.ZodNullable<z.ZodInt>;
|
|
94
|
+
dormant_days: z.ZodNullable<z.ZodInt>;
|
|
95
|
+
}, z.core.$strict>;
|
|
96
|
+
export type CredentialPayload = z.infer<typeof CredentialPayload>;
|
|
97
|
+
export declare const LegacyCredentialPayload: z.ZodObject<{
|
|
98
|
+
iss: z.ZodLiteral<"sealkeeper.run">;
|
|
99
|
+
sub: z.ZodString;
|
|
100
|
+
iat: z.ZodInt;
|
|
101
|
+
exp: z.ZodInt;
|
|
102
|
+
version: z.ZodString;
|
|
103
|
+
scores: z.ZodRecord<z.ZodUnion<readonly [z.ZodEnum<{
|
|
104
|
+
cost_latency: "cost_latency";
|
|
105
|
+
provenance: "provenance";
|
|
106
|
+
reliability: "reliability";
|
|
107
|
+
safety: "safety";
|
|
108
|
+
}>, z.ZodTemplateLiteral<`competence:${string}`>]> & z.core.$partial, z.ZodNullable<z.ZodNumber>>;
|
|
109
|
+
counts: z.ZodObject<{
|
|
110
|
+
events: z.ZodInt;
|
|
111
|
+
verified_tasks: z.ZodInt;
|
|
112
|
+
seed_tasks: z.ZodOptional<z.ZodInt>;
|
|
113
|
+
}, z.core.$strict>;
|
|
114
|
+
}, z.core.$strict>;
|
|
115
|
+
export type LegacyCredentialPayload = z.infer<typeof LegacyCredentialPayload>;
|
|
116
|
+
export declare const VerifiedCredentialPayload: z.ZodObject<{
|
|
117
|
+
iss: z.ZodEnum<{
|
|
118
|
+
"sealkeeper.run": "sealkeeper.run";
|
|
119
|
+
"vouched.run": "vouched.run";
|
|
120
|
+
}>;
|
|
121
|
+
sub: z.ZodString;
|
|
122
|
+
ver: z.ZodLiteral<1>;
|
|
123
|
+
iat: z.ZodInt;
|
|
124
|
+
exp: z.ZodInt;
|
|
125
|
+
agent_version: z.ZodString;
|
|
126
|
+
version: z.ZodString;
|
|
127
|
+
level: z.ZodEnum<{
|
|
128
|
+
bronze: "bronze";
|
|
129
|
+
gold: "gold";
|
|
130
|
+
none: "none";
|
|
131
|
+
silver: "silver";
|
|
132
|
+
}>;
|
|
133
|
+
scores: z.ZodRecord<z.ZodUnion<readonly [z.ZodEnum<{
|
|
134
|
+
cost_latency: "cost_latency";
|
|
135
|
+
provenance: "provenance";
|
|
136
|
+
reliability: "reliability";
|
|
137
|
+
safety: "safety";
|
|
138
|
+
}>, z.ZodTemplateLiteral<`competence:${string}`>]> & z.core.$partial, z.ZodNullable<z.ZodNumber>>;
|
|
139
|
+
counts: z.ZodObject<{
|
|
140
|
+
events: z.ZodInt;
|
|
141
|
+
history_days: z.ZodInt;
|
|
142
|
+
verified_tasks: z.ZodInt;
|
|
143
|
+
seed_tasks: z.ZodInt;
|
|
144
|
+
server_checked_tasks: z.ZodInt;
|
|
145
|
+
confirmed_tasks: z.ZodInt;
|
|
146
|
+
distinct_operators: z.ZodInt;
|
|
147
|
+
safety_incidents_90d: z.ZodInt;
|
|
148
|
+
}, z.core.$strict>;
|
|
149
|
+
operator: z.ZodObject<{
|
|
150
|
+
verified: z.ZodBoolean;
|
|
151
|
+
}, z.core.$strict>;
|
|
152
|
+
identity: z.ZodArray<z.ZodObject<{
|
|
153
|
+
provider: z.ZodURL;
|
|
154
|
+
kind: z.ZodUnion<readonly [z.ZodEnum<{
|
|
155
|
+
kya: "kya";
|
|
156
|
+
oidc: "oidc";
|
|
157
|
+
saml: "saml";
|
|
158
|
+
verifiable_credential: "verifiable_credential";
|
|
159
|
+
}>, z.ZodURL]>;
|
|
160
|
+
ref: z.ZodString;
|
|
161
|
+
subject_hash: z.ZodString;
|
|
162
|
+
attested_at: z.ZodInt;
|
|
163
|
+
scope: z.ZodEnum<{
|
|
164
|
+
agent: "agent";
|
|
165
|
+
operator: "operator";
|
|
166
|
+
}>;
|
|
167
|
+
}, z.core.$strict>>;
|
|
168
|
+
last_active: z.ZodNullable<z.ZodInt>;
|
|
169
|
+
dormant_days: z.ZodNullable<z.ZodInt>;
|
|
170
|
+
}, z.core.$strict>;
|
|
171
|
+
export type VerifiedCredentialPayload = z.infer<typeof VerifiedCredentialPayload>;
|
|
172
|
+
export declare const VerifiedLegacyCredentialPayload: z.ZodObject<{
|
|
173
|
+
iss: z.ZodEnum<{
|
|
174
|
+
"sealkeeper.run": "sealkeeper.run";
|
|
175
|
+
"vouched.run": "vouched.run";
|
|
176
|
+
}>;
|
|
177
|
+
sub: z.ZodString;
|
|
178
|
+
iat: z.ZodInt;
|
|
179
|
+
exp: z.ZodInt;
|
|
180
|
+
version: z.ZodString;
|
|
181
|
+
scores: z.ZodRecord<z.ZodUnion<readonly [z.ZodEnum<{
|
|
182
|
+
cost_latency: "cost_latency";
|
|
183
|
+
provenance: "provenance";
|
|
184
|
+
reliability: "reliability";
|
|
185
|
+
safety: "safety";
|
|
186
|
+
}>, z.ZodTemplateLiteral<`competence:${string}`>]> & z.core.$partial, z.ZodNullable<z.ZodNumber>>;
|
|
187
|
+
counts: z.ZodObject<{
|
|
188
|
+
events: z.ZodInt;
|
|
189
|
+
verified_tasks: z.ZodInt;
|
|
190
|
+
seed_tasks: z.ZodOptional<z.ZodInt>;
|
|
191
|
+
}, z.core.$strict>;
|
|
192
|
+
}, z.core.$strict>;
|
|
193
|
+
export type VerifiedLegacyCredentialPayload = z.infer<typeof VerifiedLegacyCredentialPayload>;
|
|
194
|
+
export declare const SealPayload: z.ZodUnion<readonly [z.ZodObject<{
|
|
195
|
+
iss: z.ZodEnum<{
|
|
196
|
+
"sealkeeper.run": "sealkeeper.run";
|
|
197
|
+
"vouched.run": "vouched.run";
|
|
198
|
+
}>;
|
|
199
|
+
sub: z.ZodString;
|
|
200
|
+
ver: z.ZodLiteral<1>;
|
|
201
|
+
iat: z.ZodInt;
|
|
202
|
+
exp: z.ZodInt;
|
|
203
|
+
agent_version: z.ZodString;
|
|
204
|
+
version: z.ZodString;
|
|
205
|
+
level: z.ZodEnum<{
|
|
206
|
+
bronze: "bronze";
|
|
207
|
+
gold: "gold";
|
|
208
|
+
none: "none";
|
|
209
|
+
silver: "silver";
|
|
210
|
+
}>;
|
|
211
|
+
scores: z.ZodRecord<z.ZodUnion<readonly [z.ZodEnum<{
|
|
212
|
+
cost_latency: "cost_latency";
|
|
213
|
+
provenance: "provenance";
|
|
214
|
+
reliability: "reliability";
|
|
215
|
+
safety: "safety";
|
|
216
|
+
}>, z.ZodTemplateLiteral<`competence:${string}`>]> & z.core.$partial, z.ZodNullable<z.ZodNumber>>;
|
|
217
|
+
counts: z.ZodObject<{
|
|
218
|
+
events: z.ZodInt;
|
|
219
|
+
history_days: z.ZodInt;
|
|
220
|
+
verified_tasks: z.ZodInt;
|
|
221
|
+
seed_tasks: z.ZodInt;
|
|
222
|
+
server_checked_tasks: z.ZodInt;
|
|
223
|
+
confirmed_tasks: z.ZodInt;
|
|
224
|
+
distinct_operators: z.ZodInt;
|
|
225
|
+
safety_incidents_90d: z.ZodInt;
|
|
226
|
+
}, z.core.$strict>;
|
|
227
|
+
operator: z.ZodObject<{
|
|
228
|
+
verified: z.ZodBoolean;
|
|
229
|
+
}, z.core.$strict>;
|
|
230
|
+
identity: z.ZodArray<z.ZodObject<{
|
|
231
|
+
provider: z.ZodURL;
|
|
232
|
+
kind: z.ZodUnion<readonly [z.ZodEnum<{
|
|
233
|
+
kya: "kya";
|
|
234
|
+
oidc: "oidc";
|
|
235
|
+
saml: "saml";
|
|
236
|
+
verifiable_credential: "verifiable_credential";
|
|
237
|
+
}>, z.ZodURL]>;
|
|
238
|
+
ref: z.ZodString;
|
|
239
|
+
subject_hash: z.ZodString;
|
|
240
|
+
attested_at: z.ZodInt;
|
|
241
|
+
scope: z.ZodEnum<{
|
|
242
|
+
agent: "agent";
|
|
243
|
+
operator: "operator";
|
|
244
|
+
}>;
|
|
245
|
+
}, z.core.$strict>>;
|
|
246
|
+
last_active: z.ZodNullable<z.ZodInt>;
|
|
247
|
+
dormant_days: z.ZodNullable<z.ZodInt>;
|
|
248
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
249
|
+
iss: z.ZodEnum<{
|
|
250
|
+
"sealkeeper.run": "sealkeeper.run";
|
|
251
|
+
"vouched.run": "vouched.run";
|
|
252
|
+
}>;
|
|
253
|
+
sub: z.ZodString;
|
|
254
|
+
iat: z.ZodInt;
|
|
255
|
+
exp: z.ZodInt;
|
|
256
|
+
version: z.ZodString;
|
|
257
|
+
scores: z.ZodRecord<z.ZodUnion<readonly [z.ZodEnum<{
|
|
258
|
+
cost_latency: "cost_latency";
|
|
259
|
+
provenance: "provenance";
|
|
260
|
+
reliability: "reliability";
|
|
261
|
+
safety: "safety";
|
|
262
|
+
}>, z.ZodTemplateLiteral<`competence:${string}`>]> & z.core.$partial, z.ZodNullable<z.ZodNumber>>;
|
|
263
|
+
counts: z.ZodObject<{
|
|
264
|
+
events: z.ZodInt;
|
|
265
|
+
verified_tasks: z.ZodInt;
|
|
266
|
+
seed_tasks: z.ZodOptional<z.ZodInt>;
|
|
267
|
+
}, z.core.$strict>;
|
|
268
|
+
}, z.core.$strict>]>;
|
|
269
|
+
export type SealPayload = z.infer<typeof SealPayload>;
|
|
270
|
+
export declare const isSealV1: (p: SealPayload) => p is VerifiedCredentialPayload;
|
|
271
|
+
export declare function sealVersionProblem(raw: unknown, nowSeconds: number): 'unsupported_version' | null;
|
|
272
|
+
export declare function sealIatProblem(iat: number, nowSeconds: number): 'not_yet_valid' | null;
|
|
273
|
+
export type SealPayloadResult = {
|
|
274
|
+
ok: true;
|
|
275
|
+
payload: SealPayload;
|
|
276
|
+
} | {
|
|
277
|
+
ok: false;
|
|
278
|
+
reason: 'wrong_issuer' | 'unsupported_version' | 'malformed';
|
|
279
|
+
};
|
|
280
|
+
export declare function parseSealPayload(raw: unknown, nowSeconds: number): SealPayloadResult;
|
|
281
|
+
export declare const WellKnownKey: z.ZodObject<{
|
|
282
|
+
kid: z.ZodString;
|
|
283
|
+
kty: z.ZodLiteral<"OKP">;
|
|
284
|
+
crv: z.ZodLiteral<"Ed25519">;
|
|
285
|
+
alg: z.ZodLiteral<"EdDSA">;
|
|
286
|
+
x: z.ZodString;
|
|
287
|
+
}, z.core.$strict>;
|
|
288
|
+
export type WellKnownKey = z.infer<typeof WellKnownKey>;
|
|
289
|
+
export declare const WellKnown: z.ZodObject<{
|
|
290
|
+
keys: z.ZodArray<z.ZodObject<{
|
|
291
|
+
kid: z.ZodString;
|
|
292
|
+
kty: z.ZodLiteral<"OKP">;
|
|
293
|
+
crv: z.ZodLiteral<"Ed25519">;
|
|
294
|
+
alg: z.ZodLiteral<"EdDSA">;
|
|
295
|
+
x: z.ZodString;
|
|
296
|
+
}, z.core.$strict>>;
|
|
297
|
+
}, z.core.$strict>;
|
|
298
|
+
export type WellKnown = z.infer<typeof WellKnown>;
|
|
299
|
+
export declare const CredentialExtension: z.ZodObject<{
|
|
300
|
+
uri: z.ZodLiteral<"https://vouched.run/ext/credential/v1">;
|
|
301
|
+
description: z.ZodString;
|
|
302
|
+
params: z.ZodObject<{
|
|
303
|
+
credential: z.ZodString;
|
|
304
|
+
}, z.core.$strict>;
|
|
305
|
+
}, z.core.$strict>;
|
|
306
|
+
export type CredentialExtension = z.infer<typeof CredentialExtension>;
|
|
307
|
+
export declare const LegacySealExtension: z.ZodObject<{
|
|
308
|
+
uri: z.ZodLiteral<"https://vouched.run/ext/seal/v1">;
|
|
309
|
+
description: z.ZodString;
|
|
310
|
+
params: z.ZodObject<{
|
|
311
|
+
credential: z.ZodString;
|
|
312
|
+
}, z.core.$strict>;
|
|
313
|
+
}, z.core.$strict>;
|
|
314
|
+
export type LegacySealExtension = z.infer<typeof LegacySealExtension>;
|
|
315
|
+
export declare const SealExtension: z.ZodObject<{
|
|
316
|
+
uri: z.ZodLiteral<"https://sealkeeper.run/ext/seal/v1">;
|
|
317
|
+
description: z.ZodString;
|
|
318
|
+
params: z.ZodObject<{
|
|
319
|
+
credential: z.ZodString;
|
|
320
|
+
}, z.core.$strict>;
|
|
321
|
+
}, z.core.$strict>;
|
|
322
|
+
export type SealExtension = z.infer<typeof SealExtension>;
|
|
323
|
+
export declare const credentialExtension: (jws: string) => CredentialExtension;
|
|
324
|
+
export declare const legacySealExtension: (jws: string) => LegacySealExtension;
|
|
325
|
+
export declare const sealExtension: (jws: string) => SealExtension;
|
|
326
|
+
export declare const sealExtensions: (jws: string) => ({
|
|
327
|
+
uri: "https://vouched.run/ext/credential/v1";
|
|
328
|
+
description: string;
|
|
329
|
+
params: {
|
|
330
|
+
credential: string;
|
|
331
|
+
};
|
|
332
|
+
} | {
|
|
333
|
+
uri: "https://vouched.run/ext/seal/v1";
|
|
334
|
+
description: string;
|
|
335
|
+
params: {
|
|
336
|
+
credential: string;
|
|
337
|
+
};
|
|
338
|
+
} | {
|
|
339
|
+
uri: "https://sealkeeper.run/ext/seal/v1";
|
|
340
|
+
description: string;
|
|
341
|
+
params: {
|
|
342
|
+
credential: string;
|
|
343
|
+
};
|
|
344
|
+
})[];
|
|
345
|
+
export declare const A2A_PROTOCOL_VERSION = "0.3.0";
|
|
346
|
+
export declare const AgentSkill: z.ZodObject<{
|
|
347
|
+
id: z.ZodString;
|
|
348
|
+
name: z.ZodString;
|
|
349
|
+
description: z.ZodString;
|
|
350
|
+
tags: z.ZodArray<z.ZodString>;
|
|
351
|
+
examples: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
352
|
+
}, z.core.$strict>;
|
|
353
|
+
export type AgentSkill = z.infer<typeof AgentSkill>;
|
|
354
|
+
export declare const AgentCard: z.ZodObject<{
|
|
355
|
+
protocolVersion: z.ZodLiteral<"0.3.0">;
|
|
356
|
+
name: z.ZodString;
|
|
357
|
+
description: z.ZodString;
|
|
358
|
+
url: z.ZodOptional<z.ZodURL>;
|
|
359
|
+
version: z.ZodString;
|
|
360
|
+
capabilities: z.ZodObject<{
|
|
361
|
+
extensions: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
362
|
+
uri: z.ZodLiteral<"https://sealkeeper.run/ext/seal/v1">;
|
|
363
|
+
description: z.ZodString;
|
|
364
|
+
params: z.ZodObject<{
|
|
365
|
+
credential: z.ZodString;
|
|
366
|
+
}, z.core.$strict>;
|
|
367
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
368
|
+
uri: z.ZodLiteral<"https://vouched.run/ext/seal/v1">;
|
|
369
|
+
description: z.ZodString;
|
|
370
|
+
params: z.ZodObject<{
|
|
371
|
+
credential: z.ZodString;
|
|
372
|
+
}, z.core.$strict>;
|
|
373
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
374
|
+
uri: z.ZodLiteral<"https://vouched.run/ext/credential/v1">;
|
|
375
|
+
description: z.ZodString;
|
|
376
|
+
params: z.ZodObject<{
|
|
377
|
+
credential: z.ZodString;
|
|
378
|
+
}, z.core.$strict>;
|
|
379
|
+
}, z.core.$strict>]>>;
|
|
380
|
+
}, z.core.$strict>;
|
|
381
|
+
skills: z.ZodArray<z.ZodObject<{
|
|
382
|
+
id: z.ZodString;
|
|
383
|
+
name: z.ZodString;
|
|
384
|
+
description: z.ZodString;
|
|
385
|
+
tags: z.ZodArray<z.ZodString>;
|
|
386
|
+
examples: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
387
|
+
}, z.core.$strict>>;
|
|
388
|
+
defaultInputModes: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
389
|
+
defaultOutputModes: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
390
|
+
}, z.core.$strict>;
|
|
391
|
+
export type AgentCard = z.infer<typeof AgentCard>;
|
|
392
|
+
export type AgentCardInput = z.input<typeof AgentCard>;
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AgentId, Ed25519PublicKey } from './agent-id.js';
|
|
3
|
+
import { Dimension } from './dimensions.js';
|
|
4
|
+
import { Jws } from './envelope.js';
|
|
5
|
+
import { Version } from './events.js';
|
|
6
|
+
import { Level, StandingCounts } from './standing.js';
|
|
7
|
+
// The issuer every SEAL carries as iss from the SealKeeper cutover on.
|
|
8
|
+
export const CREDENTIAL_ISSUER = 'sealkeeper.run';
|
|
9
|
+
// Issuers a verifier still accepts for a while after the cutover. A SEAL
|
|
10
|
+
// lives at most 24 hours, so one issued as vouched.run just before the
|
|
11
|
+
// cutover has expired well before LEGACY_ISSUER_UNTIL. From then on only
|
|
12
|
+
// CREDENTIAL_ISSUER is accepted.
|
|
13
|
+
export const LEGACY_ISSUERS = ['vouched.run'];
|
|
14
|
+
// Unix seconds, the first second a LEGACY_ISSUERS entry is no longer
|
|
15
|
+
// accepted. 2 October 2026 00:00 UTC.
|
|
16
|
+
export const LEGACY_ISSUER_UNTIL = Date.UTC(2026, 9, 2) / 1000;
|
|
17
|
+
// Whether a verifier accepts iss at nowSeconds. CREDENTIAL_ISSUER always, a
|
|
18
|
+
// legacy issuer only before LEGACY_ISSUER_UNTIL, anything else never.
|
|
19
|
+
export function acceptedIssuer(iss, nowSeconds) {
|
|
20
|
+
if (iss === CREDENTIAL_ISSUER)
|
|
21
|
+
return true;
|
|
22
|
+
return (typeof iss === 'string' &&
|
|
23
|
+
LEGACY_ISSUERS.includes(iss) &&
|
|
24
|
+
nowSeconds < LEGACY_ISSUER_UNTIL);
|
|
25
|
+
}
|
|
26
|
+
// The path of the keys document, on the issuer's own domain. It is product
|
|
27
|
+
// neutral so another issuer can serve the same path. The old path is served
|
|
28
|
+
// beside it for one release.
|
|
29
|
+
export const WELL_KNOWN_PATH = '/.well-known/seal.json';
|
|
30
|
+
export const LEGACY_WELL_KNOWN_PATH = '/.well-known/vouched.json';
|
|
31
|
+
export const WELL_KNOWN_URL = `https://${CREDENTIAL_ISSUER}${WELL_KNOWN_PATH}`;
|
|
32
|
+
export const LEGACY_WELL_KNOWN_URL = `https://vouched.run${LEGACY_WELL_KNOWN_PATH}`;
|
|
33
|
+
// The card extension a SEAL travels under. The two old URIs are kept beside
|
|
34
|
+
// it for one release, VOU-77 drops them.
|
|
35
|
+
export const SEAL_EXTENSION_URI = 'https://sealkeeper.run/ext/seal/v1';
|
|
36
|
+
export const LEGACY_SEAL_EXTENSION_URI = 'https://vouched.run/ext/seal/v1';
|
|
37
|
+
// The first card extension URI, kept under its old name so callers compile.
|
|
38
|
+
export const CREDENTIAL_EXTENSION_URI = 'https://vouched.run/ext/credential/v1';
|
|
39
|
+
export const LEGACY_SEAL_EXTENSION_URIS = [
|
|
40
|
+
LEGACY_SEAL_EXTENSION_URI,
|
|
41
|
+
CREDENTIAL_EXTENSION_URI,
|
|
42
|
+
];
|
|
43
|
+
// Every URI a SEAL extension may carry, the current one first. A card
|
|
44
|
+
// rebuilt with a fresh SEAL drops extensions with any of these first.
|
|
45
|
+
export const SEAL_EXTENSION_URIS = [
|
|
46
|
+
SEAL_EXTENSION_URI,
|
|
47
|
+
...LEGACY_SEAL_EXTENSION_URIS,
|
|
48
|
+
];
|
|
49
|
+
const Seconds = z.int().min(0);
|
|
50
|
+
const Count = z.int().min(0);
|
|
51
|
+
// The version of the SEAL standard this issuer writes, carried as ver.
|
|
52
|
+
export const SEAL_VERSION = 1;
|
|
53
|
+
// SEALs issued before version 1 carry no ver. Verifiers accept them as
|
|
54
|
+
// legacy until the end of 25 September 2026 UTC, which is past the 24 hour
|
|
55
|
+
// life of any SEAL issued before the deploy. From then on a SEAL without
|
|
56
|
+
// ver is broken, unsupported_version. Unix seconds, the first second no
|
|
57
|
+
// longer accepted.
|
|
58
|
+
export const LEGACY_UNTIL = Date.UTC(2026, 8, 26) / 1000;
|
|
59
|
+
// One identity attestation reference, SEAL standard section 4a. A pointer
|
|
60
|
+
// to an attestation an external provider made, never the attestation, a
|
|
61
|
+
// name or a tenant id. kind is one of the four names or a URL for anything
|
|
62
|
+
// else. subject_hash is SHA-256 of the provider's subject id, base64url.
|
|
63
|
+
export const IdentityKind = z.union([
|
|
64
|
+
z.enum(['oidc', 'saml', 'verifiable_credential', 'kya']),
|
|
65
|
+
z.url().max(512),
|
|
66
|
+
]);
|
|
67
|
+
export const IdentityReference = z.strictObject({
|
|
68
|
+
provider: z.url().max(512),
|
|
69
|
+
kind: IdentityKind,
|
|
70
|
+
ref: z.string().min(1).max(512),
|
|
71
|
+
subject_hash: z.string().regex(/^[A-Za-z0-9_-]{43}$/, 'SHA-256, base64url'),
|
|
72
|
+
attested_at: Seconds,
|
|
73
|
+
scope: z.enum(['operator', 'agent']),
|
|
74
|
+
});
|
|
75
|
+
// operator.verified in the SEAL. True when an operator scoped reference is
|
|
76
|
+
// held. The issuer drops a reference when its attestation expires or is
|
|
77
|
+
// revoked, so every reference it still holds is current.
|
|
78
|
+
export const operatorVerified = (identity) => identity.some((r) => r.scope === 'operator');
|
|
79
|
+
// Each score is 0 to 1, or null when unearned (standard section 2). A
|
|
80
|
+
// payload with a score outside that is malformed.
|
|
81
|
+
const Scores = z.partialRecord(Dimension, z.number().min(0).max(1).nullable());
|
|
82
|
+
// A SEAL lives at most 24 hours from issue, standard section 2. The issuer's
|
|
83
|
+
// CREDENTIAL_TTL_HOURS may not go above it, and a payload whose exp is
|
|
84
|
+
// further from its iat is malformed.
|
|
85
|
+
export const SEAL_MAX_TTL_SECONDS = 24 * 3600;
|
|
86
|
+
// How far ahead of the verifier's clock iat may be before a SEAL is not yet
|
|
87
|
+
// valid. Five minutes covers clock drift between issuer and verifier.
|
|
88
|
+
export const SEAL_CLOCK_SKEW_SECONDS = 300;
|
|
89
|
+
// iss on the issuer side is CREDENTIAL_ISSUER and nothing else. The API
|
|
90
|
+
// writes it and reads its stored SEALs back with CredentialPayload, so a
|
|
91
|
+
// stored SEAL with a legacy issuer fails that parse and is reissued. Only
|
|
92
|
+
// a verifier accepts a legacy issuer, through the Verified shapes below,
|
|
93
|
+
// and parseSealPayload checks the clock with acceptedIssuer first.
|
|
94
|
+
const IssuedIssuer = z.literal(CREDENTIAL_ISSUER);
|
|
95
|
+
const VerifiedIssuer = z.enum([CREDENTIAL_ISSUER, ...LEGACY_ISSUERS]);
|
|
96
|
+
const withinMaxTtl = (c) => c.exp - c.iat <= SEAL_MAX_TTL_SECONDS;
|
|
97
|
+
const MAX_TTL_MESSAGE = 'exp must be at most 24 hours after iat';
|
|
98
|
+
/*
|
|
99
|
+
* The SEAL payload, version 1 of the SEAL standard (section 2). Strict, it
|
|
100
|
+
* is what the API issues. version is agent_version under its old name, sent
|
|
101
|
+
* for one release so a verifier written against the old shape keeps
|
|
102
|
+
* working. VOU-77 drops it.
|
|
103
|
+
*
|
|
104
|
+
* counts are the standard's eight, over the 180 day window. last_active is
|
|
105
|
+
* Unix seconds of the agent's newest accepted event, null when it has sent
|
|
106
|
+
* none, and dormant_days whole days since then at issue, null with it.
|
|
107
|
+
*/
|
|
108
|
+
const v1Payload = (iss) => z
|
|
109
|
+
.strictObject({
|
|
110
|
+
iss,
|
|
111
|
+
sub: AgentId,
|
|
112
|
+
ver: z.literal(SEAL_VERSION),
|
|
113
|
+
iat: Seconds,
|
|
114
|
+
exp: Seconds,
|
|
115
|
+
agent_version: Version,
|
|
116
|
+
version: Version,
|
|
117
|
+
level: Level,
|
|
118
|
+
scores: Scores,
|
|
119
|
+
counts: StandingCounts,
|
|
120
|
+
operator: z.strictObject({ verified: z.boolean() }),
|
|
121
|
+
identity: z.array(IdentityReference).max(16),
|
|
122
|
+
last_active: Seconds.nullable(),
|
|
123
|
+
dormant_days: Count.nullable(),
|
|
124
|
+
})
|
|
125
|
+
.refine((c) => c.exp > c.iat, 'exp must be after iat')
|
|
126
|
+
.refine(withinMaxTtl, MAX_TTL_MESSAGE)
|
|
127
|
+
.refine((c) => c.version === c.agent_version, 'version must equal agent_version');
|
|
128
|
+
// The payload issued before version 1, with no ver. Accepted by verifiers
|
|
129
|
+
// until LEGACY_UNTIL, never issued again. seed_tasks is optional because a
|
|
130
|
+
// SEAL issued before it was added has none.
|
|
131
|
+
const legacyPayload = (iss) => z
|
|
132
|
+
.strictObject({
|
|
133
|
+
iss,
|
|
134
|
+
sub: AgentId,
|
|
135
|
+
iat: Seconds,
|
|
136
|
+
exp: Seconds,
|
|
137
|
+
version: Version,
|
|
138
|
+
scores: Scores,
|
|
139
|
+
counts: z.strictObject({
|
|
140
|
+
events: Count,
|
|
141
|
+
verified_tasks: Count,
|
|
142
|
+
seed_tasks: Count.optional(),
|
|
143
|
+
}),
|
|
144
|
+
})
|
|
145
|
+
.refine((c) => c.exp > c.iat, 'exp must be after iat')
|
|
146
|
+
.refine(withinMaxTtl, MAX_TTL_MESSAGE);
|
|
147
|
+
// The issuer side. iss is CREDENTIAL_ISSUER only.
|
|
148
|
+
export const CredentialPayload = v1Payload(IssuedIssuer);
|
|
149
|
+
export const LegacyCredentialPayload = legacyPayload(IssuedIssuer);
|
|
150
|
+
// The verifier side. iss may also be a LEGACY_ISSUERS entry. The shape has
|
|
151
|
+
// no clock, so read these through parseSealPayload, never on their own.
|
|
152
|
+
export const VerifiedCredentialPayload = v1Payload(VerifiedIssuer);
|
|
153
|
+
export const VerifiedLegacyCredentialPayload = legacyPayload(VerifiedIssuer);
|
|
154
|
+
// Any payload a verifier accepts today, version 1 or legacy, from the
|
|
155
|
+
// current issuer or a legacy one.
|
|
156
|
+
export const SealPayload = z.union([
|
|
157
|
+
VerifiedCredentialPayload,
|
|
158
|
+
VerifiedLegacyCredentialPayload,
|
|
159
|
+
]);
|
|
160
|
+
// A version 1 payload carries every legacy field too, so the guard is on
|
|
161
|
+
// version 1, the narrower of the two. Its false branch is the legacy shape.
|
|
162
|
+
export const isSealV1 = (p) => 'ver' in p;
|
|
163
|
+
const hasVer = (raw) => typeof raw === 'object' && raw !== null && 'ver' in raw;
|
|
164
|
+
/*
|
|
165
|
+
* Whether a verifier understands the version of a signed payload. Read
|
|
166
|
+
* after the signature and the issuer check out and before the shape. ver 1
|
|
167
|
+
* is understood. Any other ver is unsupported_version, as section 9 of the
|
|
168
|
+
* standard says, never valid with an unknown meaning. No ver at all is a
|
|
169
|
+
* legacy SEAL, accepted before LEGACY_UNTIL and unsupported_version from
|
|
170
|
+
* then on. Anything that is not an object is left to the shape check.
|
|
171
|
+
*/
|
|
172
|
+
export function sealVersionProblem(raw, nowSeconds) {
|
|
173
|
+
if (typeof raw !== 'object' || raw === null)
|
|
174
|
+
return null;
|
|
175
|
+
if (hasVer(raw)) {
|
|
176
|
+
return raw.ver === SEAL_VERSION ? null : 'unsupported_version';
|
|
177
|
+
}
|
|
178
|
+
return nowSeconds < LEGACY_UNTIL ? null : 'unsupported_version';
|
|
179
|
+
}
|
|
180
|
+
/*
|
|
181
|
+
* The iat half of step 4 of the standard, section 3. "Check exp is in the
|
|
182
|
+
* future and iat is not." Every verifier calls this after the shape parse
|
|
183
|
+
* and right after its expiry check, in the standard's order, exp first and
|
|
184
|
+
* then iat. A SEAL whose iat is more than SEAL_CLOCK_SKEW_SECONDS ahead of
|
|
185
|
+
* the verifier's clock is not_yet_valid. Within the skew it is accepted, so
|
|
186
|
+
* a verifier whose clock runs a little slow does not break fresh SEALs.
|
|
187
|
+
*/
|
|
188
|
+
export function sealIatProblem(iat, nowSeconds) {
|
|
189
|
+
return iat - nowSeconds > SEAL_CLOCK_SKEW_SECONDS ? 'not_yet_valid' : null;
|
|
190
|
+
}
|
|
191
|
+
// The issuer, then the version check above, then the shape for that
|
|
192
|
+
// version, in the standard's order. The API and the web read a verified
|
|
193
|
+
// payload through this. The CLI, which reads payloads loosely, calls
|
|
194
|
+
// acceptedIssuer and sealVersionProblem itself.
|
|
195
|
+
export function parseSealPayload(raw, nowSeconds) {
|
|
196
|
+
const iss = typeof raw === 'object' && raw !== null && 'iss' in raw
|
|
197
|
+
? raw.iss
|
|
198
|
+
: undefined;
|
|
199
|
+
if (!acceptedIssuer(iss, nowSeconds)) {
|
|
200
|
+
return { ok: false, reason: 'wrong_issuer' };
|
|
201
|
+
}
|
|
202
|
+
const problem = sealVersionProblem(raw, nowSeconds);
|
|
203
|
+
if (problem)
|
|
204
|
+
return { ok: false, reason: problem };
|
|
205
|
+
const parsed = (hasVer(raw) ? VerifiedCredentialPayload : VerifiedLegacyCredentialPayload).safeParse(raw);
|
|
206
|
+
return parsed.success
|
|
207
|
+
? { ok: true, payload: parsed.data }
|
|
208
|
+
: { ok: false, reason: 'malformed' };
|
|
209
|
+
}
|
|
210
|
+
export const WellKnownKey = z.strictObject({
|
|
211
|
+
kid: z.string().min(1).max(128),
|
|
212
|
+
kty: z.literal('OKP'),
|
|
213
|
+
crv: z.literal('Ed25519'),
|
|
214
|
+
alg: z.literal('EdDSA'),
|
|
215
|
+
x: Ed25519PublicKey,
|
|
216
|
+
});
|
|
217
|
+
export const WellKnown = z.strictObject({
|
|
218
|
+
keys: z.array(WellKnownKey).min(1).max(16),
|
|
219
|
+
});
|
|
220
|
+
const EXTENSION_DESCRIPTION = `SealKeeper SEAL, Signed Evidence of Agent Legitimacy. JWS compact, EdDSA, verify offline with the keys at ${WELL_KNOWN_URL}`;
|
|
221
|
+
// Every extension carries the same SEAL under the same params key. A card
|
|
222
|
+
// has the current one and the two old ones for one release, then only the
|
|
223
|
+
// current one (VOU-77).
|
|
224
|
+
export const CredentialExtension = z.strictObject({
|
|
225
|
+
uri: z.literal(CREDENTIAL_EXTENSION_URI),
|
|
226
|
+
description: z.string().min(1).max(512),
|
|
227
|
+
params: z.strictObject({ credential: Jws }),
|
|
228
|
+
});
|
|
229
|
+
export const LegacySealExtension = z.strictObject({
|
|
230
|
+
uri: z.literal(LEGACY_SEAL_EXTENSION_URI),
|
|
231
|
+
description: z.string().min(1).max(512),
|
|
232
|
+
params: z.strictObject({ credential: Jws }),
|
|
233
|
+
});
|
|
234
|
+
export const SealExtension = z.strictObject({
|
|
235
|
+
uri: z.literal(SEAL_EXTENSION_URI),
|
|
236
|
+
description: z.string().min(1).max(512),
|
|
237
|
+
params: z.strictObject({ credential: Jws }),
|
|
238
|
+
});
|
|
239
|
+
export const credentialExtension = (jws) => ({
|
|
240
|
+
uri: CREDENTIAL_EXTENSION_URI,
|
|
241
|
+
description: EXTENSION_DESCRIPTION,
|
|
242
|
+
params: { credential: jws },
|
|
243
|
+
});
|
|
244
|
+
export const legacySealExtension = (jws) => ({
|
|
245
|
+
uri: LEGACY_SEAL_EXTENSION_URI,
|
|
246
|
+
description: EXTENSION_DESCRIPTION,
|
|
247
|
+
params: { credential: jws },
|
|
248
|
+
});
|
|
249
|
+
export const sealExtension = (jws) => ({
|
|
250
|
+
uri: SEAL_EXTENSION_URI,
|
|
251
|
+
description: EXTENSION_DESCRIPTION,
|
|
252
|
+
params: { credential: jws },
|
|
253
|
+
});
|
|
254
|
+
// The extensions a card carries for one SEAL, in SEAL_EXTENSION_URIS order,
|
|
255
|
+
// the current URI first.
|
|
256
|
+
export const sealExtensions = (jws) => [
|
|
257
|
+
sealExtension(jws),
|
|
258
|
+
legacySealExtension(jws),
|
|
259
|
+
credentialExtension(jws),
|
|
260
|
+
];
|
|
261
|
+
export const A2A_PROTOCOL_VERSION = '0.3.0';
|
|
262
|
+
export const AgentSkill = z.strictObject({
|
|
263
|
+
id: z.string().min(1).max(128),
|
|
264
|
+
name: z.string().min(1).max(128),
|
|
265
|
+
description: z.string().min(1).max(1024),
|
|
266
|
+
tags: z.array(z.string().min(1).max(64)).max(32),
|
|
267
|
+
examples: z.array(z.string().min(1).max(1024)).max(32).optional(),
|
|
268
|
+
});
|
|
269
|
+
const Modes = z.array(z.string().min(1).max(128)).max(32).default(['text']);
|
|
270
|
+
// The subset of the A2A agent card that Vouched emits, strict so the CLI
|
|
271
|
+
// never writes a field it did not mean to. Reading someone else's card uses
|
|
272
|
+
// the loose AgentCardResponse instead.
|
|
273
|
+
export const AgentCard = z.strictObject({
|
|
274
|
+
protocolVersion: z.literal(A2A_PROTOCOL_VERSION),
|
|
275
|
+
name: z.string().min(1).max(128),
|
|
276
|
+
description: z.string().min(1).max(1024),
|
|
277
|
+
url: z.url({ protocol: /^https$/ }).optional(),
|
|
278
|
+
version: z.string().min(1).max(64),
|
|
279
|
+
capabilities: z.strictObject({
|
|
280
|
+
extensions: z
|
|
281
|
+
.array(z.union([SealExtension, LegacySealExtension, CredentialExtension]))
|
|
282
|
+
.max(8),
|
|
283
|
+
}),
|
|
284
|
+
skills: z.array(AgentSkill).max(64),
|
|
285
|
+
defaultInputModes: Modes,
|
|
286
|
+
defaultOutputModes: Modes,
|
|
287
|
+
});
|