@metalabel/dfos-protocol 0.36.1 → 0.38.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/README.md +2 -2
- package/dist/chain/index.d.ts +2 -2
- package/dist/chain/index.js +2 -2
- package/dist/chunk-NXQW6EBF.js +672 -0
- package/dist/{chunk-W7IFQNUH.js → chunk-SGPSXM56.js} +1 -1
- package/dist/credentials/index.d.ts +394 -40
- package/dist/credentials/index.js +53 -11
- package/dist/{dfos-credential-DU7WvoHE.d.ts → dfos-credential-X6uvPIth.d.ts} +1 -10
- package/dist/index.d.ts +2 -2
- package/dist/index.js +53 -11
- package/package.json +1 -1
- package/dist/chunk-XP644GQK.js +0 -394
|
@@ -1,54 +1,408 @@
|
|
|
1
|
-
export { b as Attenuation,
|
|
1
|
+
export { b as Attenuation, e as CredentialVerificationError, D as DFOSCredentialPayload, h as MAX_CREDENTIAL_SIZE, R as RevocationChecker, V as VerifiedDFOSCredential, t as VerifiedDelegationChain, v as createDFOSCredential, w as decodeDFOSCredentialUnsafe, x as isAttenuated, y as matchesResource, B as verifyDFOSCredential, E as verifyDelegationChain } from '../dfos-credential-X6uvPIth.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
/**
|
|
5
|
+
* The normative JWS header `typ` for a request proof (API-AUTH.md). Signers MUST
|
|
6
|
+
* set it; the request-proof verifier rejects anything else — it is also what lets
|
|
7
|
+
* typ-routing dispatchers tell a proof apart from credentials and chain ops.
|
|
8
|
+
*/
|
|
9
|
+
declare const REQUEST_PROOF_JWS_TYP = "did:dfos:request-proof";
|
|
10
|
+
/**
|
|
11
|
+
* The normative JWS header `typ` for an identity proof (API-AUTH.md) — the
|
|
12
|
+
* request proof's credential-less sibling.
|
|
13
|
+
*
|
|
14
|
+
* THE TYP GATE IS ABSOLUTE, IN BOTH DIRECTIONS. "Possession of a grant's
|
|
15
|
+
* audience key" and "possession of a bare identity's key" are different claims,
|
|
16
|
+
* so a route requiring a credential rejects an identity proof at the header gate
|
|
17
|
+
* and a route requiring bare identity rejects a request proof at the same gate.
|
|
18
|
+
* No verifier ambiguity, no downgrade.
|
|
19
|
+
*/
|
|
20
|
+
declare const IDENTITY_PROOF_JWS_TYP = "did:dfos:identity-proof";
|
|
21
|
+
/**
|
|
22
|
+
* The digest of zero octets. A request with no body hashes the empty string —
|
|
23
|
+
* there is deliberately no absent-member form for bodyless requests, so every
|
|
24
|
+
* proof is checked the same way.
|
|
25
|
+
*/
|
|
26
|
+
declare const EMPTY_BODY_SHA256 = "47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU";
|
|
27
|
+
/** Size cap on the serialized proof token, checked BEFORE any decode. */
|
|
28
|
+
declare const MAX_REQUEST_PROOF_SIZE = 4096;
|
|
29
|
+
/** RECOMMENDED acceptance window `W` — how old a proof may be, in seconds. */
|
|
30
|
+
declare const DEFAULT_PROOF_WINDOW_SECONDS = 60;
|
|
31
|
+
/** RECOMMENDED clock-skew allowance `S` — how forward-dated a proof may be. */
|
|
32
|
+
declare const DEFAULT_PROOF_SKEW_SECONDS = 60;
|
|
33
|
+
/**
|
|
34
|
+
* The binding cap on `W + S`: the total span over which any one proof is
|
|
35
|
+
* accepted, and therefore its worst-case replay window. A configuration
|
|
36
|
+
* exceeding it is refused rather than clamped — a deployment that silently got a
|
|
37
|
+
* 10-minute replay window it did not ask for is the failure this forbids.
|
|
38
|
+
*/
|
|
39
|
+
declare const MAX_PROOF_FRESHNESS_SPAN_SECONDS = 300;
|
|
40
|
+
/**
|
|
41
|
+
* Default cap on the decoded body a verifier will hash, in bytes (1 MiB). The v0
|
|
42
|
+
* action registry is bodyless, so this never binds today; it is the defensive
|
|
43
|
+
* ceiling for the first body-bearing action, overridable per verifier.
|
|
44
|
+
*/
|
|
45
|
+
declare const MAX_BODY_BYTES = 1048576;
|
|
46
|
+
/**
|
|
47
|
+
* The `Authorization` scheme this family rides — the token `DFOS`, deliberately
|
|
48
|
+
* NOT `Bearer`, because nothing carried here is a bearer token and naming it one
|
|
49
|
+
* invites bearer handling (logging, caching, forwarding) the artifact exists to
|
|
50
|
+
* make useless.
|
|
51
|
+
*/
|
|
52
|
+
declare const DFOS_AUTH_SCHEME = "DFOS";
|
|
53
|
+
interface RequestProofPayload {
|
|
54
|
+
/** The HTTP method, uppercase. */
|
|
55
|
+
method: string;
|
|
56
|
+
/** The API's lowercase authority — `host` on 443, `host:port` otherwise. */
|
|
57
|
+
host: string;
|
|
58
|
+
/** The exact origin-form request target — path plus query string, byte for byte. */
|
|
59
|
+
path: string;
|
|
60
|
+
/** Canonical unpadded base64url of the SHA-256 of the raw request body octets. */
|
|
61
|
+
bodyHash: string;
|
|
62
|
+
/** CID of the leaf credential presented alongside this proof. */
|
|
63
|
+
credentialCID: string;
|
|
64
|
+
/** Issued-at — unix seconds (positive integer). */
|
|
65
|
+
iat: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The identity proof's payload: the request proof's five members MINUS
|
|
69
|
+
* `credentialCID`. All five are required, under the SAME member rules — there is
|
|
70
|
+
* no relaxation here, only one fewer member.
|
|
71
|
+
*/
|
|
72
|
+
interface IdentityProofPayload {
|
|
73
|
+
/** The HTTP method, uppercase. */
|
|
74
|
+
method: string;
|
|
75
|
+
/** The API's lowercase authority — `host` on 443, `host:port` otherwise. */
|
|
76
|
+
host: string;
|
|
77
|
+
/** The exact origin-form request target — path plus query string, byte for byte. */
|
|
78
|
+
path: string;
|
|
79
|
+
/** Canonical unpadded base64url of the SHA-256 of the raw request body octets. */
|
|
80
|
+
bodyHash: string;
|
|
81
|
+
/** Issued-at — unix seconds (positive integer). */
|
|
82
|
+
iat: number;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* ADDITIVE MEMBERS, appended AFTER the canonical order.
|
|
86
|
+
*
|
|
87
|
+
* API-AUTH.md's growth rule is additive members on this envelope, never a new
|
|
88
|
+
* envelope: "additional members register additively, appended to the canonical
|
|
89
|
+
* order". `jti` — the per-request uniqueness member a write-gating deployment
|
|
90
|
+
* requires — is the named one.
|
|
91
|
+
*
|
|
92
|
+
* TWO RULES MAKE THIS A BYTE-TWIN. (1) Extra members are emitted AFTER every
|
|
93
|
+
* canonical member, so a verifier that ignores them still reconstructs the same
|
|
94
|
+
* prefix. (2) Among themselves they are emitted in LEXICOGRAPHIC ORDER OF MEMBER
|
|
95
|
+
* NAME — not insertion order, because Go map iteration is randomized and a TS
|
|
96
|
+
* signer and a Go signer must emit identical bytes from identical inputs.
|
|
97
|
+
*
|
|
98
|
+
* Values are strings. The registered member (`jti`) is a string, and restricting
|
|
99
|
+
* the type keeps the two encoders from disagreeing about number formatting.
|
|
100
|
+
*/
|
|
101
|
+
type ProofExtraMembers = Readonly<Record<string, string>>;
|
|
102
|
+
/** The internal union of both payloads; `credentialCID` is present iff credentialed. */
|
|
103
|
+
interface ParsedProofPayload {
|
|
104
|
+
method: string;
|
|
105
|
+
host: string;
|
|
106
|
+
path: string;
|
|
107
|
+
bodyHash: string;
|
|
108
|
+
credentialCID?: string;
|
|
109
|
+
iat: number;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Validate and normalize additive members into their canonical emission order:
|
|
113
|
+
* lexicographic by name, after every canonical member. Returns `[]` for the
|
|
114
|
+
* common (no extras) case, so the bytes are unchanged from the five/six-member
|
|
115
|
+
* form when nothing additive is asked for.
|
|
116
|
+
*/
|
|
117
|
+
declare const canonicalExtraMembers: (extra: ProofExtraMembers | undefined, label: string) => [string, string][];
|
|
118
|
+
/**
|
|
119
|
+
* The request proof's canonical signing input — six members, in the fixed order
|
|
120
|
+
* `method, host, path, bodyHash, credentialCID, iat`, plus any additive members
|
|
121
|
+
* in lexicographic order.
|
|
122
|
+
*
|
|
123
|
+
* PURE and clientless: import it in a signing backend and in a verifier alike.
|
|
124
|
+
*/
|
|
125
|
+
declare const apiRequestSigningInput: (payload: RequestProofPayload, extraMembers?: ProofExtraMembers) => Uint8Array;
|
|
126
|
+
/**
|
|
127
|
+
* The identity proof's canonical signing input — five members, in the fixed
|
|
128
|
+
* order `method, host, path, bodyHash, iat`: the request proof's bytes minus
|
|
129
|
+
* `credentialCID`, from the same encoder, under the same member rules. Additive
|
|
130
|
+
* members follow in lexicographic order.
|
|
131
|
+
*
|
|
132
|
+
* PURE and clientless: import it in a signing backend and in a verifier alike.
|
|
133
|
+
*/
|
|
134
|
+
declare const apiIdentitySigningInput: (payload: IdentityProofPayload, extraMembers?: ProofExtraMembers) => Uint8Array;
|
|
135
|
+
/**
|
|
136
|
+
* The `bodyHash` member: canonical unpadded base64url of the SHA-256 of the
|
|
137
|
+
* APPLICATION body octets — the bytes the sender handed its HTTP client, which a
|
|
138
|
+
* verifier obtains after reversing transfer encoding and content encoding. Zero
|
|
139
|
+
* octets hash to `EMPTY_BODY_SHA256`.
|
|
140
|
+
*/
|
|
141
|
+
declare const sha256BodyHash: (body: Uint8Array) => string;
|
|
142
|
+
/**
|
|
143
|
+
* Parse an `Authorization: DFOS <token>` header, returning the bare token.
|
|
144
|
+
*
|
|
145
|
+
* The scheme is matched CASE-INSENSITIVELY per RFC 9110 §11.1 (`DFOS`, `dfos`,
|
|
146
|
+
* `Dfos` are one scheme), separated from the token by one or more spaces, with
|
|
147
|
+
* surrounding optional whitespace ignored. The token itself is case-sensitive
|
|
148
|
+
* and is not further decoded here. Returns `null` for an absent, differently
|
|
149
|
+
* schemed, or empty-token header — a `Bearer` header is NOT this family and
|
|
150
|
+
* never was.
|
|
151
|
+
*/
|
|
152
|
+
declare const parseDfosAuthorization: (header: string | undefined | null) => string | null;
|
|
153
|
+
interface SignApiRequestInput {
|
|
154
|
+
/** The HTTP method, uppercase. */
|
|
155
|
+
method: string;
|
|
156
|
+
/** The API's lowercase authority — `host` on 443, `host:port` otherwise. */
|
|
157
|
+
host: string;
|
|
158
|
+
/** The exact origin-form request target this proof will ride. */
|
|
159
|
+
path: string;
|
|
160
|
+
/** Application body octets; omitted or empty hashes to `EMPTY_BODY_SHA256`. */
|
|
161
|
+
body?: Uint8Array;
|
|
162
|
+
/** CID of the leaf credential presented alongside this proof. */
|
|
163
|
+
credentialCID: string;
|
|
164
|
+
/**
|
|
165
|
+
* The signing key's DID URL. Its DID portion MUST be the leaf credential's
|
|
166
|
+
* `aud` — that equality IS the possession being proven.
|
|
167
|
+
*/
|
|
12
168
|
kid: string;
|
|
13
|
-
/**
|
|
14
|
-
iat?: number;
|
|
15
|
-
/** Signer function */
|
|
169
|
+
/** Raw Ed25519 signer over the JWS signing input. */
|
|
16
170
|
sign: (message: Uint8Array) => Promise<Uint8Array>;
|
|
171
|
+
/** Issued-at override — unix seconds. Default `Math.floor(Date.now() / 1000)`. */
|
|
172
|
+
iat?: number;
|
|
173
|
+
/**
|
|
174
|
+
* ADDITIVE members, appended after the canonical order in lexicographic name
|
|
175
|
+
* order. `{ jti }` is the registered one — required by a deployment that gates
|
|
176
|
+
* WRITES with this envelope (API-AUTH.md, Security Considerations).
|
|
177
|
+
*/
|
|
178
|
+
extraMembers?: ProofExtraMembers;
|
|
17
179
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Sign one request. The producer half of the byte contract.
|
|
182
|
+
*
|
|
183
|
+
* `createJws` serializes the payload with `JSON.stringify`, so passing the
|
|
184
|
+
* fixed-order object makes the emitted payload segment EXACTLY
|
|
185
|
+
* `apiRequestSigningInput(payload, extraMembers)` — the equivalence is pinned by
|
|
186
|
+
* a test rather than assumed, because it is the whole reason there is one byte
|
|
187
|
+
* contract and not two.
|
|
188
|
+
*/
|
|
189
|
+
declare const signApiRequest: (input: SignApiRequestInput) => Promise<{
|
|
190
|
+
proof: string;
|
|
191
|
+
payload: RequestProofPayload;
|
|
192
|
+
}>;
|
|
193
|
+
interface SignApiIdentityRequestInput {
|
|
194
|
+
/** The HTTP method, uppercase. */
|
|
195
|
+
method: string;
|
|
196
|
+
/** The API's lowercase authority — `host` on 443, `host:port` otherwise. */
|
|
197
|
+
host: string;
|
|
198
|
+
/** The exact origin-form request target this proof will ride. */
|
|
199
|
+
path: string;
|
|
200
|
+
/** Application body octets; omitted or empty hashes to `EMPTY_BODY_SHA256`. */
|
|
201
|
+
body?: Uint8Array;
|
|
202
|
+
/**
|
|
203
|
+
* The signing key's DID URL. Its DID portion IS THE PRINCIPAL — the identity
|
|
204
|
+
* proof names no other party, and nothing is looked up from it.
|
|
205
|
+
*/
|
|
38
206
|
kid: string;
|
|
207
|
+
/** Raw Ed25519 signer over the JWS signing input. */
|
|
208
|
+
sign: (message: Uint8Array) => Promise<Uint8Array>;
|
|
209
|
+
/** Issued-at override — unix seconds. Default `Math.floor(Date.now() / 1000)`. */
|
|
210
|
+
iat?: number;
|
|
211
|
+
/**
|
|
212
|
+
* ADDITIVE members, appended after the canonical order in lexicographic name
|
|
213
|
+
* order. `{ jti }` is the registered one, and a WRITE-SHAPED surface — relay
|
|
214
|
+
* ingestion, blob upload — REQUIRES it (WEB-RELAY.md, Authentication).
|
|
215
|
+
*/
|
|
216
|
+
extraMembers?: ProofExtraMembers;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Sign one request as a BARE IDENTITY — `signApiRequest`'s input minus the
|
|
220
|
+
* credential material, and its payload minus `credentialCID`. The producer half
|
|
221
|
+
* of the identity proof's byte contract.
|
|
222
|
+
*
|
|
223
|
+
* The emitted payload segment is EXACTLY
|
|
224
|
+
* `apiIdentitySigningInput(payload, extraMembers)`, the same
|
|
225
|
+
* construction-by-fixed-order the request proof uses, and pinned by a test
|
|
226
|
+
* rather than assumed.
|
|
227
|
+
*/
|
|
228
|
+
declare const signApiIdentityRequest: (input: SignApiIdentityRequestInput) => Promise<{
|
|
229
|
+
proof: string;
|
|
230
|
+
payload: IdentityProofPayload;
|
|
231
|
+
}>;
|
|
232
|
+
/**
|
|
233
|
+
* The two headers a credential-gated request carries. The `Authorization` scheme
|
|
234
|
+
* is the token `DFOS`, deliberately NOT `Bearer`.
|
|
235
|
+
*/
|
|
236
|
+
declare const buildApiAuthHeaders: (input: {
|
|
237
|
+
proof: string;
|
|
238
|
+
credential: string;
|
|
239
|
+
}) => {
|
|
240
|
+
Authorization: string;
|
|
241
|
+
"X-Credential": string;
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* The ONE header an identity-proven request carries — the same `Authorization:
|
|
245
|
+
* DFOS <jws>`.
|
|
246
|
+
*
|
|
247
|
+
* On an `api:<host>` surface an accompanying `X-Credential` is MALFORMED: the
|
|
248
|
+
* two headers would assert two different claims at once. A relay content-plane
|
|
249
|
+
* read is NOT that case — there the identity proof is the AuthN half and a DFOS
|
|
250
|
+
* credential presentation is a separate authorization artifact (WEB-RELAY.md,
|
|
251
|
+
* Authentication) — so that refusal belongs to the middleware of the surface
|
|
252
|
+
* being served, never to this builder.
|
|
253
|
+
*/
|
|
254
|
+
declare const buildApiIdentityHeaders: (input: {
|
|
255
|
+
proof: string;
|
|
256
|
+
}) => {
|
|
257
|
+
Authorization: string;
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* The verdict class. Branch on `reason`, never on message text.
|
|
261
|
+
*
|
|
262
|
+
* - `invalid` — checked and failed.
|
|
263
|
+
* - `unverifiable` — could not check (an unresolvable presenter, an unreachable
|
|
264
|
+
* revocation source). A transient resolution failure is the server's
|
|
265
|
+
* condition, not the caller's.
|
|
266
|
+
* - `config` — the DEPLOYMENT is misconfigured (a `W + S` over the 300-second
|
|
267
|
+
* ceiling, or an empty required action). Not a judgment about the artifact.
|
|
268
|
+
*/
|
|
269
|
+
type RequestProofFailureReason = 'invalid' | 'unverifiable' | 'config';
|
|
270
|
+
/**
|
|
271
|
+
* The verification phase a failure arose in. Load-bearing for HTTP mapping: an
|
|
272
|
+
* `invalid` proof-layer failure is a 401 (with a `WWW-Authenticate: DFOS`
|
|
273
|
+
* challenge), an `invalid` credential-layer failure is a 403. `status` carries
|
|
274
|
+
* the recommended code directly so middleware never has to re-derive it.
|
|
275
|
+
*/
|
|
276
|
+
type RequestProofFailurePhase = 'proof' | 'credential' | 'config';
|
|
277
|
+
/** Branch on `reason`/`phase`/`status`, never on message text. */
|
|
278
|
+
declare class ApiRequestVerifyError extends Error {
|
|
279
|
+
readonly reason: RequestProofFailureReason;
|
|
280
|
+
readonly phase: RequestProofFailurePhase;
|
|
281
|
+
/** Recommended HTTP status: 401 proof-invalid, 403 credential-invalid, 503 unverifiable, 500 config. */
|
|
282
|
+
readonly status: number;
|
|
283
|
+
constructor(reason: RequestProofFailureReason, phase: RequestProofFailurePhase, status: number, message: string);
|
|
39
284
|
}
|
|
285
|
+
/** invalid, proof phase → 401. */
|
|
286
|
+
declare const invalidProof: (message: string) => ApiRequestVerifyError;
|
|
287
|
+
/** unverifiable, proof phase → 503. */
|
|
288
|
+
declare const unverifiableProof: (message: string) => ApiRequestVerifyError;
|
|
289
|
+
/** the DEPLOYMENT is misconfigured → 500. Never a judgment about the artifact. */
|
|
290
|
+
declare const misconfiguredProof: (message: string) => ApiRequestVerifyError;
|
|
40
291
|
/**
|
|
41
|
-
*
|
|
292
|
+
* A presenter's CURRENT identity state, as the proof phase needs it.
|
|
293
|
+
*
|
|
294
|
+
* `keys` is the union of every CURRENT key role — auth, assert, controller —
|
|
295
|
+
* because API-AUTH's "key resolution is current-state" admits any of them. It is
|
|
296
|
+
* the CALLER's job to build this from current state only: a resolver answering
|
|
297
|
+
* from historical state would let a rotated-out key keep minting proofs, which
|
|
298
|
+
* removes the only lever a compromised presenter has.
|
|
42
299
|
*/
|
|
43
|
-
|
|
300
|
+
interface ProofPresenterState {
|
|
301
|
+
/** Current-state deletion. A deleted presenter's proofs are INVALID (401). */
|
|
302
|
+
isDeleted: boolean;
|
|
303
|
+
/** Current keys, any role. */
|
|
304
|
+
keys: readonly {
|
|
305
|
+
id: string;
|
|
306
|
+
publicKeyMultibase: string;
|
|
307
|
+
}[];
|
|
308
|
+
}
|
|
44
309
|
/**
|
|
45
|
-
*
|
|
310
|
+
* Resolve a presenter DID to its CURRENT identity state.
|
|
46
311
|
*
|
|
47
|
-
*
|
|
312
|
+
* Return `null`, or throw, when the state could not be established — both map to
|
|
313
|
+
* `unverifiable` (503), because "could not check" is the server's condition, not
|
|
314
|
+
* a judgment about the caller. Returning a state with `isDeleted: true` is a
|
|
315
|
+
* judgment, and maps to `invalid` (401).
|
|
316
|
+
*/
|
|
317
|
+
type ResolveProofPresenter = (did: string) => Promise<ProofPresenterState | null>;
|
|
318
|
+
/**
|
|
319
|
+
* What the PROOF PHASE reads — the subset of a verifier's inputs that
|
|
320
|
+
* API-AUTH.md steps 1–7 touch.
|
|
48
321
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
322
|
+
interface ProofEnvelopeInput {
|
|
323
|
+
/** The proof JWS — the `Authorization: DFOS <token>` token, scheme stripped. */
|
|
324
|
+
proof: string;
|
|
325
|
+
/**
|
|
326
|
+
* THE VERIFIER'S OWN CONFIGURED AUTHORITY for the route being served — a value
|
|
327
|
+
* the deployment holds, NEVER one read from the request. `Host`,
|
|
328
|
+
* `X-Forwarded-Host`, and the request URL's authority are all attacker-supplied:
|
|
329
|
+
* a verifier that compared the proof's `host` against a request header would
|
|
330
|
+
* have no host binding at all. Include the port when it is not 443.
|
|
331
|
+
*/
|
|
332
|
+
host: string;
|
|
333
|
+
/** The received request's method. */
|
|
334
|
+
method: string;
|
|
335
|
+
/** The received origin-form request target — path plus query string, byte for byte. */
|
|
336
|
+
path: string;
|
|
337
|
+
/** The received application body octets, post-content-decoding. Omitted = no body. */
|
|
338
|
+
body?: Uint8Array;
|
|
339
|
+
/** Cap on the decoded body this verifier will hash. Default `MAX_BODY_BYTES`. */
|
|
340
|
+
maxBodyBytes?: number;
|
|
341
|
+
/** Acceptance window `W`, seconds. Default 60. `W + S` MUST NOT exceed 300. */
|
|
342
|
+
windowSeconds?: number;
|
|
343
|
+
/** Clock-skew allowance `S`, seconds. Default 60. `W + S` MUST NOT exceed 300. */
|
|
344
|
+
skewSeconds?: number;
|
|
345
|
+
/** Clock injection (unix ms). Default `Date.now()`. */
|
|
346
|
+
now?: () => number;
|
|
52
347
|
}
|
|
348
|
+
/**
|
|
349
|
+
* API-AUTH.md step 4's CONFIG half, hoisted so a caller can run it BEFORE any
|
|
350
|
+
* request-dependent gate.
|
|
351
|
+
*
|
|
352
|
+
* ORDER IS LOAD-BEARING. A deployment whose freshness span is out of bounds must
|
|
353
|
+
* never verify anything, and its misconfiguration must never be REPORTED as a
|
|
354
|
+
* judgment about the request — a config verdict masked by a 401 for an oversized
|
|
355
|
+
* token would hide the deployment bug behind the caller's mistake. Every entry
|
|
356
|
+
* point calls this first.
|
|
357
|
+
*/
|
|
358
|
+
declare const assertProofVerifierConfig: (input: {
|
|
359
|
+
windowSeconds?: number;
|
|
360
|
+
skewSeconds?: number;
|
|
361
|
+
maxBodyBytes?: number;
|
|
362
|
+
}) => {
|
|
363
|
+
window: number;
|
|
364
|
+
skew: number;
|
|
365
|
+
maxBodyBytes: number;
|
|
366
|
+
};
|
|
367
|
+
/** What a verified envelope hands back. */
|
|
368
|
+
interface VerifiedProofEnvelope {
|
|
369
|
+
/** The validated canonical members. */
|
|
370
|
+
payload: ParsedProofPayload;
|
|
371
|
+
/**
|
|
372
|
+
* The DECODED payload object, unknown members included.
|
|
373
|
+
*
|
|
374
|
+
* ADDITIVE MEMBERS ARE READ FROM HERE, at the consuming layer, AFTER
|
|
375
|
+
* verification — the signature already covers them, and the canonical member
|
|
376
|
+
* set stays closed. `jti` is the case this exists for: the envelope verifier
|
|
377
|
+
* ignores it per MUST-ignore-unknown, and a write-gating deployment reads it
|
|
378
|
+
* off this object and applies its own replay discipline.
|
|
379
|
+
*/
|
|
380
|
+
rawPayload: Record<string, unknown>;
|
|
381
|
+
/** THE PRINCIPAL — the `kid`'s DID. */
|
|
382
|
+
presenterDID: string;
|
|
383
|
+
/** The full `kid` DID URL that signed, key fragment included. */
|
|
384
|
+
kid: string;
|
|
385
|
+
/** The integer unix seconds the freshness check used. */
|
|
386
|
+
now: number;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Verify an IDENTITY proof's envelope — for this artifact steps 1–7 ARE the whole
|
|
390
|
+
* algorithm. Steps 8–11 do not exist: there is no credential to walk, so there is
|
|
391
|
+
* no chain, no revocation lookup, and no attenuation coverage.
|
|
392
|
+
*
|
|
393
|
+
* Verdicts are two, not three: `invalid` → 401 and `unverifiable` → 503, plus
|
|
394
|
+
* `config` → 500 for a deployment whose `W + S` is out of bounds. There is no 403
|
|
395
|
+
* tier — nothing credential-shaped can fail.
|
|
396
|
+
*
|
|
397
|
+
* A request proof presented here is rejected at the header gate, and the reverse
|
|
398
|
+
* holds for `verifyRequestProofEnvelope`.
|
|
399
|
+
*/
|
|
400
|
+
declare const verifyIdentityProofEnvelope: (input: ProofEnvelopeInput, resolvePresenter: ResolveProofPresenter) => Promise<VerifiedProofEnvelope>;
|
|
401
|
+
/**
|
|
402
|
+
* Verify a REQUEST proof's envelope — API-AUTH.md steps 1–7 with the request
|
|
403
|
+
* `typ`. The caller then performs steps 8–11 (the credential walk), for which a
|
|
404
|
+
* verified proof signature is the gate.
|
|
405
|
+
*/
|
|
406
|
+
declare const verifyRequestProofEnvelope: (input: ProofEnvelopeInput, resolvePresenter: ResolveProofPresenter) => Promise<VerifiedProofEnvelope>;
|
|
53
407
|
|
|
54
|
-
export { type
|
|
408
|
+
export { ApiRequestVerifyError, DEFAULT_PROOF_SKEW_SECONDS, DEFAULT_PROOF_WINDOW_SECONDS, DFOS_AUTH_SCHEME, EMPTY_BODY_SHA256, IDENTITY_PROOF_JWS_TYP, type IdentityProofPayload, MAX_BODY_BYTES, MAX_PROOF_FRESHNESS_SPAN_SECONDS, MAX_REQUEST_PROOF_SIZE, type ParsedProofPayload, type ProofEnvelopeInput, type ProofExtraMembers, type ProofPresenterState, REQUEST_PROOF_JWS_TYP, type RequestProofFailurePhase, type RequestProofFailureReason, type RequestProofPayload, type ResolveProofPresenter, type SignApiIdentityRequestInput, type SignApiRequestInput, type VerifiedProofEnvelope, apiIdentitySigningInput, apiRequestSigningInput, assertProofVerifierConfig, buildApiAuthHeaders, buildApiIdentityHeaders, canonicalExtraMembers, invalidProof, misconfiguredProof, parseDfosAuthorization, sha256BodyHash, signApiIdentityRequest, signApiRequest, unverifiableProof, verifyIdentityProofEnvelope, verifyRequestProofEnvelope };
|
|
@@ -1,33 +1,75 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ApiRequestVerifyError,
|
|
2
3
|
Attenuation,
|
|
3
|
-
AuthTokenClaims,
|
|
4
|
-
AuthTokenVerificationError,
|
|
5
4
|
CredentialVerificationError,
|
|
5
|
+
DEFAULT_PROOF_SKEW_SECONDS,
|
|
6
|
+
DEFAULT_PROOF_WINDOW_SECONDS,
|
|
6
7
|
DFOSCredentialPayload,
|
|
8
|
+
DFOS_AUTH_SCHEME,
|
|
9
|
+
EMPTY_BODY_SHA256,
|
|
10
|
+
IDENTITY_PROOF_JWS_TYP,
|
|
11
|
+
MAX_BODY_BYTES,
|
|
7
12
|
MAX_CREDENTIAL_SIZE,
|
|
8
|
-
|
|
13
|
+
MAX_PROOF_FRESHNESS_SPAN_SECONDS,
|
|
14
|
+
MAX_REQUEST_PROOF_SIZE,
|
|
15
|
+
REQUEST_PROOF_JWS_TYP,
|
|
16
|
+
apiIdentitySigningInput,
|
|
17
|
+
apiRequestSigningInput,
|
|
18
|
+
assertProofVerifierConfig,
|
|
19
|
+
buildApiAuthHeaders,
|
|
20
|
+
buildApiIdentityHeaders,
|
|
21
|
+
canonicalExtraMembers,
|
|
9
22
|
createDFOSCredential,
|
|
10
23
|
decodeDFOSCredentialUnsafe,
|
|
24
|
+
invalidProof,
|
|
11
25
|
isAttenuated,
|
|
12
26
|
matchesResource,
|
|
13
|
-
|
|
27
|
+
misconfiguredProof,
|
|
28
|
+
parseDfosAuthorization,
|
|
29
|
+
sha256BodyHash,
|
|
30
|
+
signApiIdentityRequest,
|
|
31
|
+
signApiRequest,
|
|
32
|
+
unverifiableProof,
|
|
14
33
|
verifyDFOSCredential,
|
|
15
|
-
verifyDelegationChain
|
|
16
|
-
|
|
34
|
+
verifyDelegationChain,
|
|
35
|
+
verifyIdentityProofEnvelope,
|
|
36
|
+
verifyRequestProofEnvelope
|
|
37
|
+
} from "../chunk-NXQW6EBF.js";
|
|
17
38
|
import "../chunk-4LG2GEB2.js";
|
|
18
39
|
export {
|
|
40
|
+
ApiRequestVerifyError,
|
|
19
41
|
Attenuation,
|
|
20
|
-
AuthTokenClaims,
|
|
21
|
-
AuthTokenVerificationError,
|
|
22
42
|
CredentialVerificationError,
|
|
43
|
+
DEFAULT_PROOF_SKEW_SECONDS,
|
|
44
|
+
DEFAULT_PROOF_WINDOW_SECONDS,
|
|
23
45
|
DFOSCredentialPayload,
|
|
46
|
+
DFOS_AUTH_SCHEME,
|
|
47
|
+
EMPTY_BODY_SHA256,
|
|
48
|
+
IDENTITY_PROOF_JWS_TYP,
|
|
49
|
+
MAX_BODY_BYTES,
|
|
24
50
|
MAX_CREDENTIAL_SIZE,
|
|
25
|
-
|
|
51
|
+
MAX_PROOF_FRESHNESS_SPAN_SECONDS,
|
|
52
|
+
MAX_REQUEST_PROOF_SIZE,
|
|
53
|
+
REQUEST_PROOF_JWS_TYP,
|
|
54
|
+
apiIdentitySigningInput,
|
|
55
|
+
apiRequestSigningInput,
|
|
56
|
+
assertProofVerifierConfig,
|
|
57
|
+
buildApiAuthHeaders,
|
|
58
|
+
buildApiIdentityHeaders,
|
|
59
|
+
canonicalExtraMembers,
|
|
26
60
|
createDFOSCredential,
|
|
27
61
|
decodeDFOSCredentialUnsafe,
|
|
62
|
+
invalidProof,
|
|
28
63
|
isAttenuated,
|
|
29
64
|
matchesResource,
|
|
30
|
-
|
|
65
|
+
misconfiguredProof,
|
|
66
|
+
parseDfosAuthorization,
|
|
67
|
+
sha256BodyHash,
|
|
68
|
+
signApiIdentityRequest,
|
|
69
|
+
signApiRequest,
|
|
70
|
+
unverifiableProof,
|
|
31
71
|
verifyDFOSCredential,
|
|
32
|
-
verifyDelegationChain
|
|
72
|
+
verifyDelegationChain,
|
|
73
|
+
verifyIdentityProofEnvelope,
|
|
74
|
+
verifyRequestProofEnvelope
|
|
33
75
|
};
|
|
@@ -364,15 +364,6 @@ declare const DFOSCredentialPayload: z.ZodObject<{
|
|
|
364
364
|
iat: z.ZodNumber;
|
|
365
365
|
}, z.core.$loose>;
|
|
366
366
|
type DFOSCredentialPayload = z.infer<typeof DFOSCredentialPayload>;
|
|
367
|
-
/** Claims for a DID-signed auth token (relay AuthN) */
|
|
368
|
-
declare const AuthTokenClaims: z.ZodObject<{
|
|
369
|
-
iss: z.ZodString;
|
|
370
|
-
sub: z.ZodString;
|
|
371
|
-
aud: z.ZodString;
|
|
372
|
-
exp: z.ZodNumber;
|
|
373
|
-
iat: z.ZodNumber;
|
|
374
|
-
}, z.core.$loose>;
|
|
375
|
-
type AuthTokenClaims = z.infer<typeof AuthTokenClaims>;
|
|
376
367
|
|
|
377
368
|
interface VerifiedDFOSCredential {
|
|
378
369
|
/** Issuer DID */
|
|
@@ -531,4 +522,4 @@ declare class CredentialVerificationError extends Error {
|
|
|
531
522
|
constructor(message: string);
|
|
532
523
|
}
|
|
533
524
|
|
|
534
|
-
export { ARTIFACT_CID_ANCHOR_RE as A,
|
|
525
|
+
export { ARTIFACT_CID_ANCHOR_RE as A, verifyDFOSCredential as B, CONTENT_ID_ANCHOR_RE as C, DFOSCredentialPayload as D, verifyDelegationChain as E, IdentityOperation as I, MAX_ARTIFACT_PAYLOAD_SIZE as M, type RevocationChecker as R, ServiceEntry as S, type VerifiedDFOSCredential as V, ArtifactPayload as a, Attenuation as b, ContentOperation as c, CountersignPayload as d, CredentialVerificationError as e, CreditClaimPayload as f, Iso8601 as g, MAX_CREDENTIAL_SIZE as h, MAX_CREDIT_CLAIM_SIZE as i, MAX_OPERATION_SIZE as j, MAX_SERVICES_ENTRIES as k, MAX_SERVICES_PAYLOAD_SIZE as l, MAX_SIGN_REQUEST_PAYLOAD_SIZE as m, MAX_SIGN_REQUEST_SIZE as n, MultikeyPublicKey as o, RevocationPayload as p, ServicesArray as q, SignRequestPayload as r, type Signer as s, type VerifiedDelegationChain as t, VerifiedIdentity as u, createDFOSCredential as v, decodeDFOSCredentialUnsafe as w, isAttenuated as x, matchesResource as y, parseProtocolTimestampUnix as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { JwsHeader, JwsVerificationError, JwtClaims, JwtCreateOptions, JwtHeader, JwtVerificationError, JwtVerifyOptions, PrefixedID, assertJwsProfile, base64urlDecode, base64urlEncode, createJws, createJwt, createNewEd25519Keypair, dagCborCanonicalEncode, decodeJwsUnsafe, decodeJwtUnsafe, generateId, generateIdNoPrefix, importEd25519Keypair, isCanonicallyEqual, isValidEd25519Signature, isValidId, normalizedId, parseDagCborCID, sha256, signPayloadEd25519, verifyJws, verifyJwt } from './crypto/index.js';
|
|
2
|
-
export { A as ARTIFACT_CID_ANCHOR_RE, a as ArtifactPayload, b as Attenuation,
|
|
2
|
+
export { A as ARTIFACT_CID_ANCHOR_RE, a as ArtifactPayload, b as Attenuation, C as CONTENT_ID_ANCHOR_RE, c as ContentOperation, d as CountersignPayload, e as CredentialVerificationError, f as CreditClaimPayload, D as DFOSCredentialPayload, I as IdentityOperation, g as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, h as MAX_CREDENTIAL_SIZE, i as MAX_CREDIT_CLAIM_SIZE, j as MAX_OPERATION_SIZE, k as MAX_SERVICES_ENTRIES, l as MAX_SERVICES_PAYLOAD_SIZE, m as MAX_SIGN_REQUEST_PAYLOAD_SIZE, n as MAX_SIGN_REQUEST_SIZE, o as MultikeyPublicKey, R as RevocationChecker, p as RevocationPayload, S as ServiceEntry, q as ServicesArray, r as SignRequestPayload, s as Signer, V as VerifiedDFOSCredential, t as VerifiedDelegationChain, u as VerifiedIdentity, v as createDFOSCredential, w as decodeDFOSCredentialUnsafe, x as isAttenuated, y as matchesResource, z as parseProtocolTimestampUnix, B as verifyDFOSCredential, E as verifyDelegationChain } from './dfos-credential-X6uvPIth.js';
|
|
3
3
|
export { AnchorKind, CreditClaimFailureReason, CreditClaimVerifyError, CreditEntry, CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, RECOGNIZED_SERVICE_TYPES, SignRequestFailureReason, SignRequestVerifyError, VerifiedArtifact, VerifiedContentChain, VerifiedCountersignature, VerifiedCreditClaim, VerifiedCreditEntry, VerifiedRevocation, VerifiedSignRequest, anchorsByLabel, assertCanonicalSignRequestPayload, assertServicesWithinCap, buildSignRequest, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation, verifySignRequest } from './chain/index.js';
|
|
4
|
-
export {
|
|
4
|
+
export { ApiRequestVerifyError, DEFAULT_PROOF_SKEW_SECONDS, DEFAULT_PROOF_WINDOW_SECONDS, DFOS_AUTH_SCHEME, EMPTY_BODY_SHA256, IDENTITY_PROOF_JWS_TYP, IdentityProofPayload, MAX_BODY_BYTES, MAX_PROOF_FRESHNESS_SPAN_SECONDS, MAX_REQUEST_PROOF_SIZE, ParsedProofPayload, ProofEnvelopeInput, ProofExtraMembers, ProofPresenterState, REQUEST_PROOF_JWS_TYP, RequestProofFailurePhase, RequestProofFailureReason, RequestProofPayload, ResolveProofPresenter, SignApiIdentityRequestInput, SignApiRequestInput, VerifiedProofEnvelope, apiIdentitySigningInput, apiRequestSigningInput, assertProofVerifierConfig, buildApiAuthHeaders, buildApiIdentityHeaders, canonicalExtraMembers, invalidProof, misconfiguredProof, parseDfosAuthorization, sha256BodyHash, signApiIdentityRequest, signApiRequest, unverifiableProof, verifyIdentityProofEnvelope, verifyRequestProofEnvelope } from './credentials/index.js';
|
|
5
5
|
export { FoldOperation, INDEX_V1_SCHEMA, IndexDelta, IndexDocument, IndexEntry, LwwDelta, OrderKey, byteCompare, compareHeadPreference, compareLinear, foldIndexV1, foldLwwMap, linearize } from './fold/index.js';
|
|
6
6
|
import 'multiformats';
|
|
7
7
|
import 'multiformats/cid';
|