@request-seal/core 0.1.0 → 0.3.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/CHANGELOG.md +49 -1
- package/README.md +342 -114
- package/dist/accept-signature.d.ts +11 -0
- package/dist/accept-signature.js +7 -0
- package/dist/adapters/fetch/index.d.ts +10 -0
- package/dist/adapters/fetch/index.js +21 -4
- package/dist/adapters/fetch/runtime.d.ts +1 -0
- package/dist/adapters/fetch/runtime.js +1 -0
- package/dist/adapters/node-http/index.d.ts +23 -0
- package/dist/adapters/node-http/index.js +28 -8
- package/dist/brand.d.ts +5 -0
- package/dist/brand.js +12 -0
- package/dist/bytes.d.ts +4 -0
- package/dist/bytes.js +5 -0
- package/dist/constants.d.ts +64 -4
- package/dist/constants.js +62 -2
- package/dist/context.d.ts +4 -0
- package/dist/context.js +3 -0
- package/dist/crypto/algorithm.d.ts +9 -0
- package/dist/crypto/algorithm.js +12 -0
- package/dist/crypto/index.d.ts +12 -2
- package/dist/crypto/index.js +34 -11
- package/dist/crypto/options.d.ts +3 -0
- package/dist/crypto/options.js +15 -0
- package/dist/crypto/primitive.d.ts +7 -3
- package/dist/crypto/primitive.js +36 -10
- package/dist/custody/content_key.d.ts +4 -0
- package/dist/custody/content_key.js +4 -2
- package/dist/custody/index.d.ts +2 -0
- package/dist/custody/index.js +5 -1
- package/dist/custody/local.d.ts +17 -1
- package/dist/custody/local.js +10 -5
- package/dist/custody/ssh-agent/index.d.ts +2 -0
- package/dist/custody/ssh-agent/index.js +11 -181
- package/dist/custody/ssh-agent/port.d.ts +19 -0
- package/dist/custody/ssh-agent/port.js +183 -0
- package/dist/digest.d.ts +22 -0
- package/dist/digest.js +15 -0
- package/dist/discovery/body.d.ts +19 -2
- package/dist/discovery/body.js +36 -11
- package/dist/discovery/cache.d.ts +21 -2
- package/dist/discovery/cache.js +105 -39
- package/dist/discovery/headers.d.ts +3 -0
- package/dist/discovery/headers.js +27 -1
- package/dist/discovery/index.d.ts +13 -1
- package/dist/discovery/index.js +31 -7
- package/dist/discovery/node-connection.d.ts +1 -1
- package/dist/discovery/node-connection.js +2 -2
- package/dist/discovery/node-trust.d.ts +2 -0
- package/dist/discovery/node-trust.js +9 -0
- package/dist/discovery/node.d.ts +9 -1
- package/dist/discovery/node.js +150 -26
- package/dist/discovery/proof.js +2 -2
- package/dist/discovery/snapshot.js +3 -0
- package/dist/discovery/source.d.ts +7 -0
- package/dist/discovery/source.js +5 -0
- package/dist/discovery/support.js +2 -3
- package/dist/errors/parity.d.ts +44 -3
- package/dist/errors/parity.js +45 -4
- package/dist/errors/types.d.ts +17 -3
- package/dist/errors/types.js +16 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/jose/header.d.ts +1 -0
- package/dist/jose/jwe.d.ts +9 -0
- package/dist/jose/jwe.js +17 -3
- package/dist/jose/jws.d.ts +11 -0
- package/dist/jose/jws.js +14 -2
- package/dist/jose/key-management.d.ts +11 -0
- package/dist/jose/key-management.js +13 -2
- package/dist/jose/nested.d.ts +6 -0
- package/dist/jose/nested.js +32 -2
- package/dist/json.d.ts +7 -0
- package/dist/key_handle.d.ts +12 -3
- package/dist/key_handle.js +32 -25
- package/dist/key_identity.d.ts +7 -0
- package/dist/key_identity.js +10 -2
- package/dist/message/index.d.ts +24 -0
- package/dist/message/index.js +22 -1
- package/dist/numbers.d.ts +6 -0
- package/dist/numbers.js +5 -0
- package/dist/policy.d.ts +27 -0
- package/dist/policy.js +42 -21
- package/dist/profile.d.ts +36 -0
- package/dist/profile.js +215 -0
- package/dist/public_key.d.ts +11 -2
- package/dist/public_key.js +31 -8
- package/dist/quorum/evaluation.d.ts +1 -1
- package/dist/quorum/evaluation.js +18 -4
- package/dist/quorum/verification.d.ts +2 -0
- package/dist/quorum/verification.js +1 -0
- package/dist/quorum.d.ts +9 -0
- package/dist/quorum.js +7 -1
- package/dist/replay/claim.d.ts +5 -0
- package/dist/replay/claim.js +9 -1
- package/dist/replay/index.d.ts +6 -0
- package/dist/replay/index.js +13 -1
- package/dist/replay/postgres.d.ts +3 -0
- package/dist/replay/postgres.js +7 -0
- package/dist/replay/receipt.d.ts +1 -0
- package/dist/replay/receipt.js +1 -0
- package/dist/replay/store.d.ts +1 -0
- package/dist/replay/store.js +1 -0
- package/dist/replay-port.d.ts +6 -1
- package/dist/result.d.ts +3 -0
- package/dist/result.js +2 -0
- package/dist/sign.d.ts +26 -0
- package/dist/sign.js +25 -3
- package/dist/signature-base/index.d.ts +2 -0
- package/dist/signature-base/index.js +5 -1
- package/dist/signature-fields.d.ts +5 -1
- package/dist/signature-fields.js +9 -1
- package/dist/structured-fields/index.d.ts +21 -0
- package/dist/structured-fields/index.js +14 -1
- package/dist/verification.d.ts +5 -1
- package/dist/verification.js +9 -6
- package/dist/verify-quorum.d.ts +1 -0
- package/dist/verify-quorum.js +30 -8
- package/dist/verify.d.ts +23 -0
- package/dist/verify.js +46 -14
- package/dist/web-bot-auth/index.d.ts +3 -0
- package/dist/web-bot-auth/index.js +3 -0
- package/dist/web-bot-auth/policy.d.ts +8 -0
- package/dist/web-bot-auth/policy.js +8 -4
- package/dist/web-bot-auth/verification.d.ts +8 -0
- package/dist/web-bot-auth/verification.js +4 -2
- package/dist/web-bot-auth/verify.js +2 -2
- package/package.json +29 -6
package/dist/jose/nested.js
CHANGED
|
@@ -7,6 +7,7 @@ import { compact, headerValue, need, take } from "./header.js";
|
|
|
7
7
|
import { joseError } from "../errors/types.js";
|
|
8
8
|
import { publicSafe, ok } from "./support.js";
|
|
9
9
|
const branded = new WeakSet();
|
|
10
|
+
/** Check the private brand of a nested JOSE result. */
|
|
10
11
|
export function isNestedResult(value) {
|
|
11
12
|
return typeof value === "object" && value !== null && branded.has(value);
|
|
12
13
|
}
|
|
@@ -14,6 +15,29 @@ export function innerCompact(input) {
|
|
|
14
15
|
const framed = compact(input, 3, false);
|
|
15
16
|
return !framed.ok && framed.error.reason === 'invalid_serialization' ? err(joseError('nesting_depth', 'nesting')) : framed;
|
|
16
17
|
}
|
|
18
|
+
// RFC 7515 Section 4.1.10: a cty value with no "/" is read with "application/"
|
|
19
|
+
// prepended. The recursion-implying set is the registered JOSE media types
|
|
20
|
+
// (Section 9.2.1: application/jose and application/jose+json), their
|
|
21
|
+
// per-structure spellings application/jws and application/jwe, and RFC 7519's
|
|
22
|
+
// application/jwt (abbreviated "JWT"): each declares the payload is another
|
|
23
|
+
// JOSE envelope, which this one-level module refuses. Any other cty names
|
|
24
|
+
// ordinary typed payload content and is the application's business.
|
|
25
|
+
function nestingCty(cty) {
|
|
26
|
+
if (typeof cty !== "string")
|
|
27
|
+
return false;
|
|
28
|
+
// Media-type parameters do not change the type/subtype classification, so
|
|
29
|
+
// strip them before the abbreviation rule.
|
|
30
|
+
const base = cty.split(";", 1)[0].trim();
|
|
31
|
+
const expanded = base.includes("/") ? base : `application/${base}`;
|
|
32
|
+
return [
|
|
33
|
+
"application/jose",
|
|
34
|
+
"application/jose+json",
|
|
35
|
+
"application/jws",
|
|
36
|
+
"application/jwe",
|
|
37
|
+
"application/jwt",
|
|
38
|
+
].includes(expanded.toLowerCase());
|
|
39
|
+
}
|
|
40
|
+
/** Authenticate an outer JWE and verify its inner compact JWS. */
|
|
17
41
|
export async function decrypt(input, policy, options) {
|
|
18
42
|
return publicSafe(async () => {
|
|
19
43
|
const opts = snapshotOptions(options, ["content_types", "context"]);
|
|
@@ -42,7 +66,7 @@ export async function decrypt(input, policy, options) {
|
|
|
42
66
|
const inner = await JWS.verify(plaintext, p.jws, stageOptions);
|
|
43
67
|
if (!inner.ok)
|
|
44
68
|
return inner;
|
|
45
|
-
need(!inner.value.header
|
|
69
|
+
need(!nestingCty(headerValue(inner.value.header, "cty")), "nesting_depth", "nesting");
|
|
46
70
|
const result = Object.freeze({ jwe: outer.value, jws: inner.value });
|
|
47
71
|
branded.add(result);
|
|
48
72
|
return ok(result);
|
|
@@ -52,4 +76,10 @@ export async function decrypt(input, policy, options) {
|
|
|
52
76
|
}
|
|
53
77
|
});
|
|
54
78
|
}
|
|
55
|
-
|
|
79
|
+
/** One-level nested JWE decryption and JWS verification operations. */
|
|
80
|
+
export const Nested = Object.freeze({
|
|
81
|
+
/** Authenticate an outer JWE and verify its inner compact JWS. */
|
|
82
|
+
decrypt,
|
|
83
|
+
/** Check the private brand of the operation result. */
|
|
84
|
+
isResult: isNestedResult
|
|
85
|
+
});
|
package/dist/json.d.ts
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { type Result } from './result.ts';
|
|
2
|
+
/** An ordered JSON tree that retains numeric source text. */
|
|
2
3
|
export type JsonNode = null | boolean | string | JsonNumber | JsonObject | JsonArray;
|
|
4
|
+
/** A JSON number represented by its original lexeme. */
|
|
3
5
|
export type JsonNumber = {
|
|
4
6
|
readonly kind: 'number';
|
|
5
7
|
readonly lexeme: string;
|
|
6
8
|
};
|
|
9
|
+
/** A JSON object represented by ordered key-value pairs. */
|
|
7
10
|
export type JsonObject = {
|
|
8
11
|
readonly kind: 'object';
|
|
9
12
|
readonly pairs: readonly (readonly [string, JsonNode])[];
|
|
10
13
|
};
|
|
14
|
+
/** A JSON array represented by an ordered sequence of nodes. */
|
|
11
15
|
export type JsonArray = {
|
|
12
16
|
readonly kind: 'array';
|
|
13
17
|
readonly items: readonly JsonNode[];
|
|
14
18
|
};
|
|
19
|
+
/** Byte, depth, and container limits for JSON decoding. */
|
|
15
20
|
export type JsonLimits = {
|
|
16
21
|
maxBytes: number;
|
|
17
22
|
maxDepth: number;
|
|
@@ -19,10 +24,12 @@ export type JsonLimits = {
|
|
|
19
24
|
maxArrayLength: number;
|
|
20
25
|
maxStringBytes: number;
|
|
21
26
|
};
|
|
27
|
+
/** JSON limits and explicit duplicate and noncharacter policies. */
|
|
22
28
|
export type JsonDecodeOptions = Partial<JsonLimits> & {
|
|
23
29
|
rejectDuplicates?: boolean;
|
|
24
30
|
acceptNoncharacters?: boolean;
|
|
25
31
|
};
|
|
32
|
+
/** A decoded JSON tree and its duplicate member names. */
|
|
26
33
|
export type DecodedJson = {
|
|
27
34
|
readonly node: JsonNode;
|
|
28
35
|
readonly duplicates: readonly string[];
|
package/dist/key_handle.d.ts
CHANGED
|
@@ -4,18 +4,27 @@ import { type CustodyAlgorithm } from './crypto/algorithm.ts';
|
|
|
4
4
|
import { type PublicKey } from './public_key.ts';
|
|
5
5
|
import { type KeyIdentity } from './key_identity.ts';
|
|
6
6
|
import { type UnwrappedKey } from './custody/content_key.ts';
|
|
7
|
+
/** A branded algorithm-bound capability that confines private key operations. */
|
|
7
8
|
export type KeyHandle = Readonly<{
|
|
8
9
|
algorithm: CustodyAlgorithm;
|
|
9
10
|
capabilities: readonly ('sign' | 'verify' | 'unwrap')[];
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
/** Sign bounded bytes with the algorithm-bound custody capability. */
|
|
12
|
+
sign: (algorithm: unknown, data: unknown, context: Context, options?: unknown) => Promise<Result<Uint8Array<ArrayBuffer>>>;
|
|
13
|
+
/** Verify a signature through the algorithm-bound custody capability. */
|
|
14
|
+
verify: (algorithm: unknown, signature: unknown, data: unknown, context: Context, options?: unknown) => Promise<Result<true>>;
|
|
15
|
+
/** Return the handle's branded public key. */
|
|
12
16
|
publicKey: (context?: Context) => Promise<Result<PublicKey>>;
|
|
17
|
+
/** Return the handle's branded key identity. */
|
|
13
18
|
identity: (context?: Context) => Promise<Result<KeyIdentity>>;
|
|
19
|
+
/** Unwrap an encrypted key into a confined decryption capability. */
|
|
14
20
|
unwrap: (algorithm: unknown, wrappedKey: unknown, context: Context, options?: unknown) => Promise<Result<UnwrappedKey>>;
|
|
21
|
+
/** Release retained custody and invalidate the capability. */
|
|
15
22
|
release: () => Promise<Result<true>>;
|
|
16
23
|
}>;
|
|
24
|
+
/** The caller-provided operation port wrapped by a branded key handle. */
|
|
17
25
|
export type Custodian = Pick<KeyHandle, 'sign' | 'verify' | 'publicKey' | 'identity' | 'unwrap' | 'release'>;
|
|
26
|
+
/** Check the private brand of a custody handle. */
|
|
18
27
|
export declare function isKeyHandle(value: unknown): value is KeyHandle;
|
|
19
28
|
/** Wrap trusted custodian code under deadline, result validation, and fault containment. */
|
|
20
29
|
export declare function createKeyHandle(algorithm: unknown, port: Custodian, capabilities?: KeyHandle['capabilities']): Result<KeyHandle>;
|
|
21
|
-
export declare function verifyHandle(key: KeyHandle, algorithm: unknown, signature: unknown, data: unknown, context: Context): Promise<Result<true>>;
|
|
30
|
+
export declare function verifyHandle(key: KeyHandle, algorithm: unknown, signature: unknown, data: unknown, context: Context, options?: unknown): Promise<Result<true>>;
|
package/dist/key_handle.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
import { denoInspection } from './brand.js';
|
|
2
|
+
import { byteLimit } from './crypto/options.js';
|
|
1
3
|
import { snapshotOptions } from './brand.js';
|
|
2
4
|
import { withDeadline, isContext, remainingMs, run, } from './context.js';
|
|
3
|
-
import { SIGNATURE_MAX_BYTES, CUSTODY_SIGNATURE_MAX_BYTES } from './constants.js';
|
|
5
|
+
import { CRYPTO_MAX_BYTES_CEILING, SIGNATURE_MAX_BYTES, CUSTODY_SIGNATURE_MAX_BYTES } from './constants.js';
|
|
4
6
|
import { custodyError, isRequestSealError } from './errors/types.js';
|
|
5
7
|
import { ok, err } from './result.js';
|
|
6
8
|
import { resolveAlgorithm, selection, } from './crypto/algorithm.js';
|
|
7
|
-
import { dataBytes } from './crypto/primitive.js';
|
|
9
|
+
import { dataBytes, boundedBinary, binaryByteLength } from './crypto/primitive.js';
|
|
8
10
|
import { isPublicKey } from './public_key.js';
|
|
9
11
|
import { isKeyIdentity } from './key_identity.js';
|
|
10
12
|
import { isUnwrappedKey } from './custody/content_key.js';
|
|
11
13
|
const handles = new WeakSet();
|
|
12
14
|
const token = Object.freeze({});
|
|
15
|
+
/** Check the private brand of a custody handle. */
|
|
13
16
|
export function isKeyHandle(value) {
|
|
14
17
|
return typeof value === 'object' && value !== null && handles.has(value);
|
|
15
18
|
}
|
|
@@ -71,7 +74,10 @@ class ManagedHandle {
|
|
|
71
74
|
const resolved = resolveAlgorithm(algorithm, true);
|
|
72
75
|
return resolved.ok && resolved.value.id === this.#spec.id;
|
|
73
76
|
}
|
|
74
|
-
async sign(algorithm, data, context) {
|
|
77
|
+
async sign(algorithm, data, context, options = {}) {
|
|
78
|
+
const maximum = byteLimit(options);
|
|
79
|
+
if (!maximum.ok)
|
|
80
|
+
return err(custodyError('invalid_options'));
|
|
75
81
|
try {
|
|
76
82
|
if (!this.#port)
|
|
77
83
|
return err(custodyError('key_not_found'));
|
|
@@ -81,25 +87,27 @@ class ManagedHandle {
|
|
|
81
87
|
return err(custodyError('key_mismatch'));
|
|
82
88
|
if (!this.capabilities.includes('sign'))
|
|
83
89
|
return err(custodyError('unsupported_operation'));
|
|
84
|
-
const bytes = dataBytes(data);
|
|
90
|
+
const bytes = dataBytes(data, maximum.value);
|
|
85
91
|
if (!bytes.ok)
|
|
86
92
|
return err(custodyError('invalid_data'));
|
|
87
93
|
return this.#invoke('sign', context, async (p, c) => {
|
|
88
94
|
try {
|
|
89
|
-
return await p.sign(this.algorithm, bytes.value, c);
|
|
95
|
+
return await p.sign(this.algorithm, bytes.value, c, { maxBytes: CRYPTO_MAX_BYTES_CEILING });
|
|
90
96
|
}
|
|
91
97
|
finally {
|
|
92
98
|
bytes.value.fill(0);
|
|
93
99
|
}
|
|
94
|
-
}, (v) => v
|
|
95
|
-
v
|
|
96
|
-
v.length <= CUSTODY_SIGNATURE_MAX_BYTES);
|
|
100
|
+
}, (v) => boundedBinary(v, CUSTODY_SIGNATURE_MAX_BYTES) &&
|
|
101
|
+
binaryByteLength(v) > 0);
|
|
97
102
|
}
|
|
98
103
|
catch {
|
|
99
104
|
return err(custodyError('invalid_data'));
|
|
100
105
|
}
|
|
101
106
|
}
|
|
102
|
-
async verify(algorithm, signature, data, context) {
|
|
107
|
+
async verify(algorithm, signature, data, context, options = {}) {
|
|
108
|
+
const maximum = byteLimit(options);
|
|
109
|
+
if (!maximum.ok)
|
|
110
|
+
return err(custodyError('invalid_options'));
|
|
103
111
|
try {
|
|
104
112
|
if (!this.#port)
|
|
105
113
|
return err(custodyError('key_not_found'));
|
|
@@ -109,17 +117,17 @@ class ManagedHandle {
|
|
|
109
117
|
return err(custodyError('key_mismatch'));
|
|
110
118
|
if (!this.capabilities.includes('verify'))
|
|
111
119
|
return err(custodyError('unsupported_operation'));
|
|
112
|
-
const bytes = dataBytes(data);
|
|
120
|
+
const bytes = dataBytes(data, maximum.value);
|
|
113
121
|
if (!bytes.ok)
|
|
114
122
|
return err(custodyError('invalid_data'));
|
|
115
123
|
if (!(signature instanceof Uint8Array))
|
|
116
124
|
return err(custodyError('invalid_signature'));
|
|
117
|
-
if (signature
|
|
125
|
+
if (!boundedBinary(signature, CUSTODY_SIGNATURE_MAX_BYTES))
|
|
118
126
|
return err(custodyError('limit'));
|
|
119
127
|
const copied = new Uint8Array(signature);
|
|
120
128
|
return this.#invoke('verify', context, async (p, c) => {
|
|
121
129
|
try {
|
|
122
|
-
return await p.verify(this.algorithm, copied, bytes.value, c);
|
|
130
|
+
return await p.verify(this.algorithm, copied, bytes.value, c, { maxBytes: CRYPTO_MAX_BYTES_CEILING });
|
|
123
131
|
}
|
|
124
132
|
finally {
|
|
125
133
|
copied.fill(0);
|
|
@@ -138,6 +146,12 @@ class ManagedHandle {
|
|
|
138
146
|
return this.#invoke('identity', context, (p, c) => p.identity(c), isKeyIdentity);
|
|
139
147
|
}
|
|
140
148
|
async unwrap(algorithm, wrappedKey, context, options = {}) {
|
|
149
|
+
const opts = snapshotOptions(options, ['length']);
|
|
150
|
+
if (!opts.ok ||
|
|
151
|
+
(Object.hasOwn(opts.value, 'length') &&
|
|
152
|
+
opts.value.length !== 128 &&
|
|
153
|
+
opts.value.length !== 256))
|
|
154
|
+
return err(custodyError('invalid_options'));
|
|
141
155
|
try {
|
|
142
156
|
if (!this.#port)
|
|
143
157
|
return err(custodyError('key_not_found'));
|
|
@@ -147,16 +161,9 @@ class ManagedHandle {
|
|
|
147
161
|
return err(custodyError('key_mismatch'));
|
|
148
162
|
if (!this.capabilities.includes('unwrap'))
|
|
149
163
|
return err(custodyError('unsupported_operation'));
|
|
150
|
-
if (!(wrappedKey
|
|
151
|
-
wrappedKey
|
|
152
|
-
wrappedKey.length > SIGNATURE_MAX_BYTES)
|
|
164
|
+
if (!boundedBinary(wrappedKey, SIGNATURE_MAX_BYTES) ||
|
|
165
|
+
binaryByteLength(wrappedKey) === 0)
|
|
153
166
|
return err(custodyError('invalid_data'));
|
|
154
|
-
const opts = snapshotOptions(options, ['length']);
|
|
155
|
-
if (!opts.ok ||
|
|
156
|
-
(Object.hasOwn(opts.value, 'length') &&
|
|
157
|
-
opts.value.length !== 128 &&
|
|
158
|
-
opts.value.length !== 256))
|
|
159
|
-
return err(custodyError('invalid_options'));
|
|
160
167
|
const copied = new Uint8Array(wrappedKey);
|
|
161
168
|
return this.#invoke('unwrap', context, async (p, c) => {
|
|
162
169
|
try {
|
|
@@ -196,8 +203,8 @@ class ManagedHandle {
|
|
|
196
203
|
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
197
204
|
return this.toJSON();
|
|
198
205
|
}
|
|
199
|
-
[Symbol.for('Deno.customInspect')]() {
|
|
200
|
-
return this.toJSON();
|
|
206
|
+
[Symbol.for('Deno.customInspect')](render) {
|
|
207
|
+
return denoInspection(render, this.toJSON());
|
|
201
208
|
}
|
|
202
209
|
}
|
|
203
210
|
/** Wrap trusted custodian code under deadline, result validation, and fault containment. */
|
|
@@ -251,6 +258,6 @@ export function createKeyHandle(algorithm, port, capabilities) {
|
|
|
251
258
|
Object.freeze(ManagedHandle.prototype);
|
|
252
259
|
Object.freeze(ManagedHandle);
|
|
253
260
|
const managedVerify = Function.prototype.call.bind(ManagedHandle.prototype.verify);
|
|
254
|
-
export function verifyHandle(key, algorithm, signature, data, context) {
|
|
255
|
-
return managedVerify(key, algorithm, signature, data, context);
|
|
261
|
+
export function verifyHandle(key, algorithm, signature, data, context, options = {}) {
|
|
262
|
+
return managedVerify(key, algorithm, signature, data, context, options);
|
|
256
263
|
}
|
package/dist/key_identity.d.ts
CHANGED
|
@@ -2,15 +2,22 @@ import { type Result } from './result.ts';
|
|
|
2
2
|
import { type PublicKey } from './public_key.ts';
|
|
3
3
|
/** Internal, nonserialized canonical equivalence key for scoped identity merging. */
|
|
4
4
|
export declare function identityClassKey(identity: KeyIdentity): string | undefined;
|
|
5
|
+
/** Check the private brand of a key identity. */
|
|
5
6
|
export declare function isKeyIdentity(value: unknown): value is KeyIdentity;
|
|
7
|
+
/** A branded public, symmetric, or unknown key identity. */
|
|
6
8
|
export declare class KeyIdentity {
|
|
7
9
|
#private;
|
|
8
10
|
readonly kind: 'public' | 'symmetric' | 'unknown';
|
|
9
11
|
private constructor();
|
|
12
|
+
/** Derive an identity from a branded public key's canonical components. */
|
|
10
13
|
static fromPublic(key: PublicKey): Result<KeyIdentity>;
|
|
14
|
+
/** Create a symmetric identity from caller-supplied nonsecret bytes. */
|
|
11
15
|
static symmetric(value: unknown): Result<KeyIdentity>;
|
|
16
|
+
/** Create an identity that cannot establish key equivalence. */
|
|
12
17
|
static unknown(): Result<KeyIdentity>;
|
|
18
|
+
/** Compare branded key identities using their canonical identity bytes. */
|
|
13
19
|
static same(a: unknown, b: unknown): Result<boolean>;
|
|
20
|
+
/** Return a bounded public inspection view without retained cryptographic bytes. */
|
|
14
21
|
toJSON(): Readonly<{
|
|
15
22
|
kind: KeyIdentity['kind'];
|
|
16
23
|
}>;
|
package/dist/key_identity.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { denoInspection } from './brand.js';
|
|
1
2
|
import { ok, err } from './result.js';
|
|
2
3
|
import { custodyError } from './errors/types.js';
|
|
3
4
|
import { KEY_IDENTITY_MAX_BYTES } from './constants.js';
|
|
@@ -8,9 +9,11 @@ const classKeys = new WeakMap();
|
|
|
8
9
|
/** Internal, nonserialized canonical equivalence key for scoped identity merging. */
|
|
9
10
|
export function identityClassKey(identity) { return classKeys.get(identity); }
|
|
10
11
|
const token = Object.freeze({});
|
|
12
|
+
/** Check the private brand of a key identity. */
|
|
11
13
|
export function isKeyIdentity(value) {
|
|
12
14
|
return typeof value === 'object' && value !== null && identities.has(value);
|
|
13
15
|
}
|
|
16
|
+
/** A branded public, symmetric, or unknown key identity. */
|
|
14
17
|
export class KeyIdentity {
|
|
15
18
|
kind;
|
|
16
19
|
#bytes;
|
|
@@ -24,6 +27,7 @@ export class KeyIdentity {
|
|
|
24
27
|
identities.add(this);
|
|
25
28
|
Object.freeze(this);
|
|
26
29
|
}
|
|
30
|
+
/** Derive an identity from a branded public key's canonical components. */
|
|
27
31
|
static fromPublic(key) {
|
|
28
32
|
if (!isPublicKey(key))
|
|
29
33
|
return err(custodyError('invalid_key'));
|
|
@@ -32,6 +36,7 @@ export class KeyIdentity {
|
|
|
32
36
|
? ok(new KeyIdentity(token, 'public', r.value))
|
|
33
37
|
: err(custodyError('invalid_key'));
|
|
34
38
|
}
|
|
39
|
+
/** Create a symmetric identity from caller-supplied nonsecret bytes. */
|
|
35
40
|
static symmetric(value) {
|
|
36
41
|
try {
|
|
37
42
|
if ((!(value instanceof Uint8Array) && typeof value !== 'string') ||
|
|
@@ -48,9 +53,11 @@ export class KeyIdentity {
|
|
|
48
53
|
return err(custodyError('invalid_options'));
|
|
49
54
|
}
|
|
50
55
|
}
|
|
56
|
+
/** Create an identity that cannot establish key equivalence. */
|
|
51
57
|
static unknown() {
|
|
52
58
|
return ok(new KeyIdentity(token, 'unknown'));
|
|
53
59
|
}
|
|
60
|
+
/** Compare branded key identities using their canonical identity bytes. */
|
|
54
61
|
static same(a, b) {
|
|
55
62
|
if (!isKeyIdentity(a) || !isKeyIdentity(b))
|
|
56
63
|
return err(custodyError('invalid_key'));
|
|
@@ -63,14 +70,15 @@ export class KeyIdentity {
|
|
|
63
70
|
diff |= a.#bytes[i] ^ b.#bytes[i];
|
|
64
71
|
return ok(diff === 0);
|
|
65
72
|
}
|
|
73
|
+
/** Return a bounded public inspection view without retained cryptographic bytes. */
|
|
66
74
|
toJSON() {
|
|
67
75
|
return Object.freeze({ kind: this.kind });
|
|
68
76
|
}
|
|
69
77
|
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
70
78
|
return this.toJSON();
|
|
71
79
|
}
|
|
72
|
-
[Symbol.for('Deno.customInspect')]() {
|
|
73
|
-
return this.toJSON();
|
|
80
|
+
[Symbol.for('Deno.customInspect')](render) {
|
|
81
|
+
return denoInspection(render, this.toJSON());
|
|
74
82
|
}
|
|
75
83
|
}
|
|
76
84
|
Object.freeze(KeyIdentity.prototype);
|
package/dist/message/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type Result } from '../result.ts';
|
|
2
|
+
/** An owned HTTP field occurrence with its section and byte value. */
|
|
2
3
|
export type FieldOccurrence = Readonly<{
|
|
3
4
|
name: string;
|
|
4
5
|
value: Uint8Array;
|
|
5
6
|
section: 'headers' | 'trailers';
|
|
6
7
|
provenance: 'caller' | 'http1' | 'http2' | 'http3';
|
|
7
8
|
}>;
|
|
9
|
+
/** Owned or unavailable body bytes with explicit retention and completeness facts. */
|
|
8
10
|
export type Body = Readonly<{
|
|
9
11
|
state: 'retained' | 'streaming' | 'consumed' | 'unavailable';
|
|
10
12
|
bytes: Uint8Array | null;
|
|
@@ -12,11 +14,13 @@ export type Body = Readonly<{
|
|
|
12
14
|
ownership: 'caller';
|
|
13
15
|
maxBytes: number;
|
|
14
16
|
}>;
|
|
17
|
+
/** Branded TLS and peer-certificate facts captured by an adapter. */
|
|
15
18
|
export type TransportFacts = Readonly<{
|
|
16
19
|
httpVersion: 'unknown' | 'http1_0' | 'http1_1' | 'http2' | 'http3';
|
|
17
20
|
tls: 'unknown' | 'plain' | 'tls';
|
|
18
21
|
evidence: 'declared';
|
|
19
22
|
}>;
|
|
23
|
+
/** A branded HTTP request or response preserving target and field bytes. */
|
|
20
24
|
export type Message = Readonly<{
|
|
21
25
|
kind: 'request' | 'response';
|
|
22
26
|
method: string | null;
|
|
@@ -31,30 +35,50 @@ export type Message = Readonly<{
|
|
|
31
35
|
relatedRequest: Message | null;
|
|
32
36
|
transport: TransportFacts;
|
|
33
37
|
}>;
|
|
38
|
+
/** Check the private brand of an HTTP message. */
|
|
34
39
|
export declare function isMessage(value: unknown): value is Message;
|
|
40
|
+
/** Check the private brand of a field occurrence. */
|
|
35
41
|
export declare function isFieldOccurrence(value: unknown): value is FieldOccurrence;
|
|
42
|
+
/** Check the private brand of a body snapshot. */
|
|
36
43
|
export declare function isBody(value: unknown): value is Body;
|
|
44
|
+
/** Check the private brand of captured transport facts. */
|
|
37
45
|
export declare function isTransportFacts(value: unknown): value is TransportFacts;
|
|
38
46
|
export declare function token(value: unknown, max?: number): value is string;
|
|
39
47
|
export declare function uriBytes(s: string): boolean;
|
|
40
48
|
export declare function authority(value: unknown, requirePort?: boolean): value is string;
|
|
49
|
+
/** Field occurrence construction and validation. */
|
|
41
50
|
export declare const FieldOccurrence: Readonly<{
|
|
51
|
+
/** Validate and brand the supplied HTTP snapshot. */
|
|
42
52
|
create: (a: unknown) => Result<FieldOccurrence>;
|
|
53
|
+
/** Validate the snapshot using the same boundary as construction. */
|
|
43
54
|
validate: (a: unknown) => Result<FieldOccurrence>;
|
|
44
55
|
}>;
|
|
56
|
+
/** Body snapshot construction and validation. */
|
|
45
57
|
export declare const Body: Readonly<{
|
|
58
|
+
/** Validate and brand the supplied HTTP snapshot. */
|
|
46
59
|
create: (a: unknown) => Result<Body>;
|
|
60
|
+
/** Validate the snapshot using the same boundary as construction. */
|
|
47
61
|
validate: (a: unknown) => Result<Body>;
|
|
48
62
|
}>;
|
|
63
|
+
/** Transport snapshot construction and validation. */
|
|
49
64
|
export declare const TransportFacts: Readonly<{
|
|
65
|
+
/** Validate and brand the supplied HTTP snapshot. */
|
|
50
66
|
create: (a: unknown) => Result<TransportFacts>;
|
|
67
|
+
/** Validate the snapshot using the same boundary as construction. */
|
|
51
68
|
validate: (a: unknown) => Result<TransportFacts>;
|
|
52
69
|
}>;
|
|
70
|
+
/** Validate and brand a lossless HTTP message snapshot. */
|
|
53
71
|
export declare function createMessage(a: unknown): Result<Message>;
|
|
72
|
+
/** Validate a message snapshot through the same constructor boundary. */
|
|
54
73
|
export declare const validateMessage: typeof createMessage;
|
|
74
|
+
/** Lossless HTTP message construction and validation. */
|
|
55
75
|
export declare const Message: Readonly<{
|
|
76
|
+
/** Validate and brand the supplied HTTP snapshot. */
|
|
56
77
|
create: typeof createMessage;
|
|
78
|
+
/** Validate the snapshot using the same boundary as construction. */
|
|
57
79
|
validate: typeof createMessage;
|
|
80
|
+
/** Build a branded HTTP request with owned field and body bytes. */
|
|
58
81
|
request: (method: unknown, target: unknown, fields: unknown, bytes: unknown, options?: unknown) => Promise<Result<Message>>;
|
|
82
|
+
/** Build a branded HTTP response with owned field and body bytes. */
|
|
59
83
|
response: (status: unknown, fields: unknown, bytes: unknown, options?: unknown) => Promise<Result<Message>>;
|
|
60
84
|
}>;
|
package/dist/message/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { byteString, encodeBase64 } from '../bytes.js';
|
|
2
|
+
import { digest as capturedDigest } from '../crypto/subtle.js';
|
|
2
3
|
import { snapshotOptions } from '../brand.js';
|
|
3
4
|
import { BODY_MAX_BYTES, MESSAGE_MAX_TARGET_BYTES, MESSAGE_MAX_FIELD_BYTES, MESSAGE_MAX_FIELDS_BYTES, MESSAGE_MAX_OCCURRENCES, MESSAGE_MAX_TOKEN_BYTES, MESSAGE_MAX_SCHEME_BYTES, MESSAGE_MAX_AUTHORITY_BYTES, MESSAGE_MAX_URL_BYTES, } from '../constants.js';
|
|
4
5
|
import { messageError, isRequestSealError } from '../errors/types.js';
|
|
@@ -7,15 +8,19 @@ const messages = new WeakSet();
|
|
|
7
8
|
const fieldOccurrences = new WeakSet();
|
|
8
9
|
const bodies = new WeakSet();
|
|
9
10
|
const transportFacts = new WeakSet();
|
|
11
|
+
/** Check the private brand of an HTTP message. */
|
|
10
12
|
export function isMessage(value) {
|
|
11
13
|
return typeof value === 'object' && value !== null && messages.has(value);
|
|
12
14
|
}
|
|
15
|
+
/** Check the private brand of a field occurrence. */
|
|
13
16
|
export function isFieldOccurrence(value) {
|
|
14
17
|
return typeof value === 'object' && value !== null && fieldOccurrences.has(value);
|
|
15
18
|
}
|
|
19
|
+
/** Check the private brand of a body snapshot. */
|
|
16
20
|
export function isBody(value) {
|
|
17
21
|
return typeof value === 'object' && value !== null && bodies.has(value);
|
|
18
22
|
}
|
|
23
|
+
/** Check the private brand of captured transport facts. */
|
|
19
24
|
export function isTransportFacts(value) {
|
|
20
25
|
return typeof value === 'object' && value !== null && transportFacts.has(value);
|
|
21
26
|
}
|
|
@@ -265,21 +270,32 @@ function message(input, related = false) {
|
|
|
265
270
|
relatedRequest: request,
|
|
266
271
|
}, messages);
|
|
267
272
|
}
|
|
273
|
+
/** Field occurrence construction and validation. */
|
|
268
274
|
export const FieldOccurrence = Object.freeze({
|
|
275
|
+
/** Validate and brand the supplied HTTP snapshot. */
|
|
269
276
|
create: (a) => protect(() => field(a), 'invalid_field'),
|
|
277
|
+
/** Validate the snapshot using the same boundary as construction. */
|
|
270
278
|
validate: (a) => protect(() => field(a), 'invalid_field'),
|
|
271
279
|
});
|
|
280
|
+
/** Body snapshot construction and validation. */
|
|
272
281
|
export const Body = Object.freeze({
|
|
282
|
+
/** Validate and brand the supplied HTTP snapshot. */
|
|
273
283
|
create: (a) => protect(() => body(a), 'invalid_body'),
|
|
284
|
+
/** Validate the snapshot using the same boundary as construction. */
|
|
274
285
|
validate: (a) => protect(() => body(a), 'invalid_body'),
|
|
275
286
|
});
|
|
287
|
+
/** Transport snapshot construction and validation. */
|
|
276
288
|
export const TransportFacts = Object.freeze({
|
|
289
|
+
/** Validate and brand the supplied HTTP snapshot. */
|
|
277
290
|
create: (a) => protect(() => transport(a), 'invalid_transport'),
|
|
291
|
+
/** Validate the snapshot using the same boundary as construction. */
|
|
278
292
|
validate: (a) => protect(() => transport(a), 'invalid_transport'),
|
|
279
293
|
});
|
|
294
|
+
/** Validate and brand a lossless HTTP message snapshot. */
|
|
280
295
|
export function createMessage(a) {
|
|
281
296
|
return protect(() => message(a), 'invalid_message');
|
|
282
297
|
}
|
|
298
|
+
/** Validate a message snapshot through the same constructor boundary. */
|
|
283
299
|
export const validateMessage = createMessage;
|
|
284
300
|
async function builder(kind, first, target, headers, bytes, options) {
|
|
285
301
|
try {
|
|
@@ -314,7 +330,7 @@ async function builder(kind, first, target, headers, bytes, options) {
|
|
|
314
330
|
const digests = [];
|
|
315
331
|
for (const alg of algorithms) {
|
|
316
332
|
try {
|
|
317
|
-
const hash = await
|
|
333
|
+
const hash = await capturedDigest(alg === 'sha-256' ? 'SHA-256' : 'SHA-512', new Uint8Array(content.bytes));
|
|
318
334
|
digests.push(alg + '=:' + encodeBase64(new Uint8Array(hash)) + ':');
|
|
319
335
|
}
|
|
320
336
|
catch {
|
|
@@ -347,9 +363,14 @@ async function builder(kind, first, target, headers, bytes, options) {
|
|
|
347
363
|
: messageError('invalid_message'));
|
|
348
364
|
}
|
|
349
365
|
}
|
|
366
|
+
/** Lossless HTTP message construction and validation. */
|
|
350
367
|
export const Message = Object.freeze({
|
|
368
|
+
/** Validate and brand the supplied HTTP snapshot. */
|
|
351
369
|
create: createMessage,
|
|
370
|
+
/** Validate the snapshot using the same boundary as construction. */
|
|
352
371
|
validate: validateMessage,
|
|
372
|
+
/** Build a branded HTTP request with owned field and body bytes. */
|
|
353
373
|
request: (method, target, fields, bytes, options = {}) => builder('request', method, target, fields, bytes, options),
|
|
374
|
+
/** Build a branded HTTP response with owned field and body bytes. */
|
|
354
375
|
response: (status, fields, bytes, options = {}) => builder('response', status, null, fields, bytes, options),
|
|
355
376
|
});
|
package/dist/numbers.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { type Result } from './result.ts';
|
|
2
|
+
/** Check whether a value is a JavaScript safe integer. */
|
|
2
3
|
export declare const safeInteger: (value: unknown) => value is number;
|
|
4
|
+
/** Validate the Structured Fields integer range and reject negative zero. */
|
|
3
5
|
export declare function structuredInteger(value: unknown): Result<number>;
|
|
6
|
+
/** Validate a Structured Fields date using the integer range. */
|
|
4
7
|
export declare const structuredDate: typeof structuredInteger;
|
|
8
|
+
/** A decimal stored as an integer scaled by one thousand. */
|
|
5
9
|
export type Decimal = Readonly<{
|
|
6
10
|
scaled: number;
|
|
7
11
|
scale: 3;
|
|
8
12
|
}>;
|
|
9
13
|
/** Parse decimal source text without rounding or a floating-point conversion. */
|
|
10
14
|
export declare function parseDecimal(value: unknown): Result<Decimal>;
|
|
15
|
+
/** Validate a nonnegative Unix clock value within the supported range. */
|
|
11
16
|
export declare function clockSeconds(value: unknown): Result<number>;
|
|
17
|
+
/** Validate a positive timeout within the custody time limit. */
|
|
12
18
|
export declare function timeoutMs(value: unknown): Result<number>;
|
package/dist/numbers.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { SF_MAX_INTEGER, CLOCK_MAX_SECONDS, TIMEOUT_MAX_MS } from './constants.js';
|
|
2
2
|
import { ok, err } from './result.js';
|
|
3
3
|
import { structuredFieldsError, coreError, custodyError } from './errors/types.js';
|
|
4
|
+
/** Check whether a value is a JavaScript safe integer. */
|
|
4
5
|
export const safeInteger = (value) => typeof value === 'number' && Number.isSafeInteger(value);
|
|
6
|
+
/** Validate the Structured Fields integer range and reject negative zero. */
|
|
5
7
|
export function structuredInteger(value) {
|
|
6
8
|
return safeInteger(value) && !Object.is(value, -0) && Math.abs(value) <= SF_MAX_INTEGER ? ok(value) : err(structuredFieldsError('invalid_value'));
|
|
7
9
|
}
|
|
10
|
+
/** Validate a Structured Fields date using the integer range. */
|
|
8
11
|
export const structuredDate = structuredInteger;
|
|
9
12
|
/** Parse decimal source text without rounding or a floating-point conversion. */
|
|
10
13
|
export function parseDecimal(value) {
|
|
@@ -16,9 +19,11 @@ export function parseDecimal(value) {
|
|
|
16
19
|
const magnitude = Number(match[2]) * 1000 + Number(match[3].padEnd(3, '0'));
|
|
17
20
|
return ok(Object.freeze({ scaled: match[1] === '-' && magnitude !== 0 ? -magnitude : magnitude, scale: 3 }));
|
|
18
21
|
}
|
|
22
|
+
/** Validate a nonnegative Unix clock value within the supported range. */
|
|
19
23
|
export function clockSeconds(value) {
|
|
20
24
|
return safeInteger(value) && value >= 0 && value <= CLOCK_MAX_SECONDS ? ok(value) : err(coreError('invalid_clock', 'freshness'));
|
|
21
25
|
}
|
|
26
|
+
/** Validate a positive timeout within the custody time limit. */
|
|
22
27
|
export function timeoutMs(value) {
|
|
23
28
|
return safeInteger(value) && value >= 1 && value <= TIMEOUT_MAX_MS ? ok(value) : err(custodyError('invalid_options'));
|
|
24
29
|
}
|
package/dist/policy.d.ts
CHANGED
|
@@ -6,36 +6,45 @@ import type { KeyIdentity } from "./key_identity.ts";
|
|
|
6
6
|
import type { KeyHandle } from "./key_handle.ts";
|
|
7
7
|
import type { PublicKey } from "./public_key.ts";
|
|
8
8
|
import type { ReplayStore, ReplayFacts } from "./replay-port.ts";
|
|
9
|
+
/** A caller-owned signature verification callback receiving a bounded context. */
|
|
9
10
|
export type Verifier = (algorithm: SigningAlgorithm, base: Uint8Array, signature: Uint8Array, context: Context) => Result<boolean> | Promise<Result<boolean>>;
|
|
11
|
+
/** A resolved algorithm and key or verification capability with optional identity. */
|
|
10
12
|
export type ResolvedKey = Readonly<{
|
|
11
13
|
algorithm: SigningAlgorithm;
|
|
12
14
|
key?: PublicKey | KeyHandle | Verifier;
|
|
13
15
|
verify?: Verifier;
|
|
14
16
|
identity?: KeyIdentity;
|
|
15
17
|
}>;
|
|
18
|
+
/** Resolve a verification key from signature facts and an operation context. */
|
|
16
19
|
export type KeyResolver = (facts: Readonly<{
|
|
17
20
|
keyid: string | null;
|
|
18
21
|
label: string;
|
|
19
22
|
tag: string | null;
|
|
20
23
|
}>, context: Context) => Result<ResolvedKey | null> | Promise<Result<ResolvedKey | null>>;
|
|
24
|
+
/** Clock, age, skew, and expiration rules for signature freshness. */
|
|
21
25
|
export type Freshness = Readonly<{
|
|
26
|
+
/** Return the current Unix time in seconds. */
|
|
22
27
|
clock: () => number;
|
|
23
28
|
maxAge: number | null;
|
|
24
29
|
skew: number;
|
|
25
30
|
requireExpires: boolean;
|
|
26
31
|
}>;
|
|
32
|
+
/** Digest algorithms and field section required for content verification. */
|
|
27
33
|
export type ContentPolicy = Readonly<{
|
|
28
34
|
kind: "content" | "representation";
|
|
29
35
|
algorithms: readonly string[];
|
|
30
36
|
section: "headers" | "trailers";
|
|
31
37
|
}>;
|
|
38
|
+
/** Nonce namespace, commitment, atomic store, and timeout rules. */
|
|
32
39
|
export type ReplayPolicy = Readonly<{
|
|
33
40
|
identifier: "nonce";
|
|
34
41
|
namespace: Uint8Array;
|
|
42
|
+
/** Derive caller-owned replay commitment bytes from verified facts. */
|
|
35
43
|
commitment: (facts: ReplayFacts, context: Context) => Result<Uint8Array> | Promise<Result<Uint8Array>>;
|
|
36
44
|
store: ReplayStore;
|
|
37
45
|
timeoutMs: number;
|
|
38
46
|
}>;
|
|
47
|
+
/** A branded verification policy with explicit key, freshness, content, and replay rules. */
|
|
39
48
|
export type Policy = Readonly<{
|
|
40
49
|
algorithms: readonly SigningAlgorithm[];
|
|
41
50
|
components: InnerList;
|
|
@@ -48,8 +57,26 @@ export type Policy = Readonly<{
|
|
|
48
57
|
maxSignatures: number;
|
|
49
58
|
}>;
|
|
50
59
|
export declare function fieldSchemas(input: unknown): Result<Readonly<Record<string, Schema>>>;
|
|
60
|
+
/** Check the private brand of a verification policy. */
|
|
51
61
|
export declare function isPolicy(value: unknown): value is Policy;
|
|
62
|
+
/** Internal shared freshness boundary for policies and extension preflight. */
|
|
63
|
+
export declare function normalizeFreshness(input: unknown): Freshness | "not_evaluated";
|
|
64
|
+
/** Snapshot, validate, and brand an explicit verification policy. */
|
|
52
65
|
export declare function createPolicy(input: unknown): Result<Policy>;
|
|
66
|
+
/** Verification policy construction. */
|
|
53
67
|
export declare const Policy: Readonly<{
|
|
68
|
+
/**
|
|
69
|
+
* Snapshot, validate, and brand an explicit verification policy.
|
|
70
|
+
*
|
|
71
|
+
* Six choices are required and none is defaulted: `algorithms`, `components`,
|
|
72
|
+
* `keyResolver`, `freshness`, `content`, and `replay`. Optional members are
|
|
73
|
+
* `extraComponents` (`"allow"` or `"reject"`), `maxSignatures` (1 through 64, default 16),
|
|
74
|
+
* and `fieldSchemas`.
|
|
75
|
+
*
|
|
76
|
+
* @returns `ok(policy)`, or `core` `input.invalid_policy` when any choice is missing,
|
|
77
|
+
* unknown, or malformed.
|
|
78
|
+
* @see [Signing and verifying guide](https://github.com/baselabs/request-seal-typescript/blob/main/docs/guides/signing-and-verifying.md#verify) and
|
|
79
|
+
* [reference](https://github.com/baselabs/request-seal-typescript/blob/main/docs/reference/sign-and-verify.md).
|
|
80
|
+
*/
|
|
54
81
|
create: typeof createPolicy;
|
|
55
82
|
}>;
|