@byok-sdk/core 0.30.0 → 0.30.2
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/blob.ts","../../src/attestation.ts","../../src/time.ts","../../src/total-parse.ts","../../src/webcrypto.ts","../../src/hpke.ts","../../src/sealed-provider-secret.ts","../../src/sealed-payload/primitives.ts","../../src/sealed-payload/member-chain.ts","../../src/sealed-payload/scope-key.ts","../../src/sealed-payload/sealed-json.ts","../../src/sealed-payload/sealed-content.ts","../../src/sealed-payload/member-bundle.ts","../../src/sealed-payload/member-fingerprint.ts","../../src/sealed-payload/pairing-verification.ts","../../src/sealed-payload/member-chain-walk.ts"],"names":["ByokCoreError","parts","z","utf8","copy","concat","hmacSha256","AEAD_TAG_BYTES"],"mappings":"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","file":"index.js","sourcesContent":["import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Content addressing and the object manifest (§12.7.4, §12.7.8).\n *\n * This module is **metadata only**. No byte transport, no presigning, no\n * hashing: R2/S3 URL signing and digest computation are composition concerns\n * that need platform crypto, and core stays Node-free. What core owns is the\n * shape everyone must agree on — the hash format, the manifest state machine,\n * and reference counting — so that Postgres, D1, and the in-memory reference\n * cannot disagree about when an object is safe to delete.\n *\n * Object keys are tenant-scoped by construction ({@link tenantObjectKey}).\n * A global `sha256/<hex>` key space would turn object existence into a\n * cross-tenant oracle, which is why §12.7.4 forbids it even though it would\n * deduplicate better.\n */\nimport { ByokCoreError } from './errors';\nimport type { TenantId } from './tenant';\n\n/** `sha256:<64 lowercase hex>`. The only content-address form core accepts. */\nexport const CONTENT_HASH_PATTERN = /^sha256:[0-9a-f]{64}$/;\n\n/** A validated content address. Branded so an unvalidated digest cannot stand in for one. */\nexport type ContentHash = string & { readonly __byokContentHash: unique symbol };\n\n/**\n * The single mint point for {@link ContentHash}.\n *\n * Fail-closed on uppercase hex: accepting both cases would make the same bytes\n * addressable under two keys, which breaks per-tenant deduplication and the\n * \"count each hash once\" billing rule (§12.7.6).\n *\n * @throws {ByokCoreError} code `content_hash_invalid`.\n */\nexport function contentHash(value: string): ContentHash {\n if (!CONTENT_HASH_PATTERN.test(value)) {\n throw new ByokCoreError(\n 'content_hash_invalid',\n `Content hash must match ${CONTENT_HASH_PATTERN.source}, received ${JSON.stringify(value)}.`,\n );\n }\n return value as ContentHash;\n}\n\n/** Non-throwing form of {@link contentHash}. */\nexport function isContentHash(value: unknown): value is ContentHash {\n return typeof value === 'string' && CONTENT_HASH_PATTERN.test(value);\n}\n\n/**\n * What a deployment-level key namespace may look like: slash-joined segments of\n * lowercase alphanumerics, `.`, `_`, and `-`, each starting with an\n * alphanumeric. No leading or trailing slash, and therefore no empty segment.\n *\n * Narrow on purpose, and narrower than S3 keys allow. A prefix is spliced into\n * every key this SDK ever writes, so the only prefixes worth accepting are the\n * ones that reach the object store spelled exactly as configured: anything\n * requiring percent-encoding would give the deployment's objects two names, and\n * anything with an empty segment would make `a//b` and `a/b` the same key at\n * rest but different strings in config. Case is folded out for the same reason\n * {@link contentHash} refuses uppercase hex — one address, one spelling.\n */\nexport const OBJECT_KEY_PREFIX_PATTERN = /^[a-z0-9][a-z0-9._-]*(\\/[a-z0-9][a-z0-9._-]*)*$/;\n\n/** A validated deployment key namespace. Branded, so only the mint point below can produce one. */\nexport type ObjectKeyPrefix = string & { readonly __byokObjectKeyPrefix: unique symbol };\n\n/**\n * The single mint point for {@link ObjectKeyPrefix}.\n *\n * There is no \"empty means no prefix\" spelling here: a composition that has no\n * prefix omits the option, and one that passes `''` has misconfigured something\n * (an unset environment variable is the usual way). Accepting it silently would\n * make the two indistinguishable at exactly the moment the difference decides\n * where a deployment's objects live.\n *\n * @throws {ByokCoreError} code `object_key_prefix_invalid`.\n */\nexport function objectKeyPrefix(value: string): ObjectKeyPrefix {\n if (!OBJECT_KEY_PREFIX_PATTERN.test(value)) {\n throw new ByokCoreError(\n 'object_key_prefix_invalid',\n `Object key prefix must match ${OBJECT_KEY_PREFIX_PATTERN.source}, received ${JSON.stringify(value)}.`,\n );\n }\n return value as ObjectKeyPrefix;\n}\n\n/**\n * Tenant-scoped object key, e.g.\n * `tenants/<tenantId>/objects/sha256/<hex>` (§12.7.4).\n *\n * `prefix` namespaces the whole layout — `<prefix>/tenants/...` — so one bucket\n * can hold several deployments without either of them owning the bucket root.\n * Omitting it produces the unprefixed key verbatim, which is what makes the\n * option safe to add: every object already at rest was written without one.\n *\n * The prefix is an IMMUTABLE property of a deployment. It is spliced in here\n * and nowhere else, and nothing reads a key back under a second layout: change\n * a live deployment's prefix and its existing objects become unaddressable.\n * See `R2BlobStoreOptions.keyPrefix` in `@byok-sdk/cloud-dataplane` for the full\n * operational contract.\n */\nexport function tenantObjectKey(\n tenant: TenantId,\n hash: ContentHash,\n prefix?: ObjectKeyPrefix,\n): string {\n const hex = hash.slice('sha256:'.length);\n const key = `tenants/${tenant as string}/objects/sha256/${hex}`;\n return prefix === undefined ? key : `${prefix as string}/${key}`;\n}\n\n/**\n * Object manifest lifecycle (§12.7.8).\n *\n * `pending` exists because Postgres and R2 have no shared transaction: the row\n * is written before the bytes land, and only `committed` rows may be referenced\n * by a truth record. `delete_pending` is the tombstone the GC worker drives, so\n * a failed R2 delete is retryable instead of leaving usage silently wrong.\n */\nexport const OBJECT_STATES = ['pending', 'committed', 'delete_pending', 'deleted'] as const;\nexport type ObjectState = (typeof OBJECT_STATES)[number];\n\n/** Legal manifest transitions. Anything else raises `object_state_invalid`. */\nexport const OBJECT_STATE_TRANSITIONS: Readonly<Record<ObjectState, readonly ObjectState[]>> = {\n pending: ['committed', 'delete_pending'],\n committed: ['delete_pending'],\n delete_pending: ['deleted', 'committed'],\n deleted: [],\n};\n\nexport function isLegalObjectTransition(from: ObjectState, to: ObjectState): boolean {\n return OBJECT_STATE_TRANSITIONS[from].includes(to);\n}\n\n/** One row of `object_manifest` (§12.7.6). */\nexport interface ObjectManifestEntry {\n readonly tenantId: TenantId;\n readonly hash: ContentHash;\n /** Declared at reservation time, re-verified at commit against the store's `HEAD`. */\n readonly byteSize: bigint;\n readonly contentType: string;\n readonly state: ObjectState;\n /** Number of live {@link ObjectReference} rows. `0` makes the object GC-eligible after grace. */\n readonly refCount: number;\n readonly createdAt: string;\n readonly updatedAt: string;\n /** Set when the row entered `delete_pending`; the grace window is measured from here. */\n readonly deletePendingAt?: string;\n}\n\n/** What references an object. `refKind`/`refId` are opaque to core. */\nexport interface ObjectReference {\n readonly tenantId: TenantId;\n readonly hash: ContentHash;\n readonly refKind: string;\n readonly refId: string;\n readonly createdAt: string;\n}\n\nexport interface ObjectManifestInput {\n readonly hash: ContentHash;\n readonly byteSize: bigint;\n readonly contentType: string;\n}\n\n/**\n * Finalize input. `byteSize`/`contentType` are what the composition actually\n * observed on the object store, not what the client declared — the whole point\n * of the check is that the two can differ (§12.7.7 step 4).\n */\nexport interface ObjectCommitInput {\n readonly hash: ContentHash;\n readonly observedByteSize: bigint;\n readonly observedContentType: string;\n}\n\nexport interface ObjectReferenceInput {\n readonly hash: ContentHash;\n readonly refKind: string;\n readonly refId: string;\n}\n\nexport interface ObjectListQuery {\n readonly state?: ObjectState;\n /**\n * Only rows whose `deletePendingAt` is at or before this instant.\n *\n * Must be a **canonical ISO-8601 UTC instant** (`YYYY-MM-DDTHH:mm:ss.sssZ`);\n * anything else is rejected with `timestamp_not_canonical`, because the\n * in-memory composition compares it as a string and a SQL composition\n * compares it as a `timestamptz` — see `time.ts`.\n */\n readonly deletePendingBefore?: string;\n readonly limit?: number;\n}\n\n/**\n * Object manifest port. Tenant-first, async, metadata only.\n *\n * Raises: `object_not_found`, `object_state_invalid`,\n * `storage_integrity_mismatch` (commit observed size/type disagreeing with the\n * declared manifest row), `timestamp_not_canonical` (a `list` query whose\n * `deletePendingBefore` is not a canonical ISO-8601 UTC instant).\n */\nexport interface ObjectStore {\n collectExpired(tenant: TenantId, input: ObjectCollectExpiredInput): Promise<CollectExpiredResult>;\n /** Creates or returns the `pending` row for `hash`. Idempotent per (tenant, hash). */\n putManifest(tenant: TenantId, input: ObjectManifestInput): Promise<ObjectManifestEntry>;\n /** `pending` → `committed` after verifying observed size/type. */\n commit(tenant: TenantId, input: ObjectCommitInput): Promise<ObjectManifestEntry>;\n get(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry | undefined>;\n list(tenant: TenantId, query: ObjectListQuery): Promise<readonly ObjectManifestEntry[]>;\n /** Idempotent per (tenant, hash, refKind, refId) — re-adding does not double-count. */\n addReference(tenant: TenantId, input: ObjectReferenceInput): Promise<ObjectManifestEntry>;\n removeReference(tenant: TenantId, input: ObjectReferenceInput): Promise<ObjectManifestEntry>;\n /** Tombstone step 1: only legal at `refCount === 0`. */\n markDeletePending(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;\n /** Tombstone step 3: the object store delete succeeded. */\n markDeleted(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;\n}\n\nexport interface ObjectCollectExpiredInput extends CollectExpiredInput { readonly orphanBefore: string; }\n","/**\n * Device proof envelope and canonical signing bytes (§12.6.3, sprint §S6.2).\n *\n * Three things live here and nothing else:\n *\n * 1. **The protected-claims schema.** Every field a signature must cover so the\n * proof binds a *specific request*: tenant, product, device, key + epoch,\n * request id, operation, resource, the request line (method+path or a stable\n * operation id), and the body's hash *and* size. Signing only the body is\n * forbidden — it would let a valid proof be replayed against a different\n * operation or resource.\n * 2. **A dependency-free deterministic canonicalizer.** RFC 8785 (JCS) in the\n * narrow subset the envelope allows. Node and Workers must produce\n * byte-identical output, so the accepted value space is deliberately small:\n * strings, booleans, null, safe integers, plain objects, arrays. Floats,\n * non-safe integers, `NaN`, `Infinity`, `undefined`, `bigint`, dates and\n * class instances throw instead of being coerced — a signature over a value\n * whose serialization is implementation-defined is not a signature.\n * 3. **The verify port.** An interface, never an implementation: core is\n * Node-free and Workers-safe, and `node:crypto` and WebCrypto disagree about\n * key handling. The composition brings its own verifier.\n *\n * Claims are **untrusted input**. `tenantId` here is a plain string, not a\n * branded `TenantId`, because a device asserting a tenant proves nothing: the\n * claim is a lookup key used to load the device row, and the row is the\n * authority (§12.6.2 layer 5). Branding happens after that lookup, not here.\n */\nimport { z } from 'zod';\nimport { CONTENT_HASH_PATTERN } from './blob';\nimport { ByokCoreError } from './errors';\n\n/** Envelope schema id, self-consistent with the domain prefix below. */\nexport const DEVICE_PROOF_SCHEMA_ID = 'byok-device-proof-v1';\n\n/**\n * Domain separation prefix (§12.6.3). Prepended to the canonical claim bytes\n * before signing so a device-proof signature can never be replayed as a nonce\n * signature (`byok-nonce-v1\\n`) or a record attestation.\n */\nexport const DEVICE_PROOF_DOMAIN_PREFIX = 'byok-device-proof-v1\\n';\n\nexport const DEVICE_PROOF_VERSION = 1;\n\n/** Signature algorithms this envelope version admits. */\nexport const DEVICE_PROOF_ALGORITHMS = ['ed25519'] as const;\nexport type DeviceProofAlgorithm = (typeof DEVICE_PROOF_ALGORITHMS)[number];\n\n/**\n * HTTP header carrying the base64url device-proof envelope on a truth-route\n * request (§12.6.3). Both the daemon that mints the proof and the host that\n * decodes it must name the exact same header, so it is a single wire constant\n * here rather than a string re-spelled on each side.\n */\nexport const DEVICE_PROOF_HEADER = 'x-byok-device-proof';\n\nconst BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;\nconst HTTP_METHOD_PATTERN = /^[A-Z]+$/;\n\n// ---------------------------------------------------------------------------\n// Canonicalization (RFC 8785 subset)\n// ---------------------------------------------------------------------------\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | readonly JsonValue[] | { readonly [key: string]: JsonValue };\nexport type JsonObject = { readonly [key: string]: JsonValue };\n\nfunction canonicalizationFailure(path: string, reason: string): ByokCoreError {\n return new ByokCoreError(\n 'proof_canonicalization_failed',\n `Cannot canonicalize ${path}: ${reason}`,\n );\n}\n\nfunction isPlainObject(value: object): boolean {\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction canonicalizeValue(value: unknown, path: string, seen: Set<object>): string {\n if (value === null) return 'null';\n\n switch (typeof value) {\n case 'boolean':\n return value ? 'true' : 'false';\n case 'string':\n // JSON.stringify implements exactly the ECMAScript string serialization\n // RFC 8785 mandates, including well-formed escaping of lone surrogates.\n return JSON.stringify(value);\n case 'number': {\n if (!Number.isSafeInteger(value)) {\n throw canonicalizationFailure(\n path,\n `only safe integers are canonicalizable, received ${String(value)}`,\n );\n }\n // Normalizes -0 to 0; RFC 8785 has no signed zero.\n return String(value === 0 ? 0 : value);\n }\n case 'undefined':\n throw canonicalizationFailure(path, 'undefined has no canonical form');\n case 'bigint':\n throw canonicalizationFailure(path, 'bigint is not a JSON type');\n case 'function':\n case 'symbol':\n throw canonicalizationFailure(path, `${typeof value} is not a JSON type`);\n case 'object':\n break;\n default:\n throw canonicalizationFailure(path, `unsupported type ${typeof value}`);\n }\n\n const objectValue = value as object;\n if (seen.has(objectValue)) {\n throw canonicalizationFailure(path, 'circular reference');\n }\n seen.add(objectValue);\n try {\n if (Array.isArray(objectValue)) {\n const parts = objectValue.map((entry, index) =>\n canonicalizeValue(entry, `${path}[${index}]`, seen),\n );\n return `[${parts.join(',')}]`;\n }\n if (!isPlainObject(objectValue)) {\n throw canonicalizationFailure(\n path,\n 'only plain objects and arrays are canonicalizable',\n );\n }\n // Default string sort compares UTF-16 code units, which is what RFC 8785\n // specifies for member ordering.\n const keys = Object.keys(objectValue).sort();\n const record = objectValue as Record<string, unknown>;\n const parts = keys.map((key) => {\n const encodedKey = JSON.stringify(key);\n const encodedValue = canonicalizeValue(record[key], `${path}.${key}`, seen);\n return `${encodedKey}:${encodedValue}`;\n });\n return `{${parts.join(',')}}`;\n } finally {\n seen.delete(objectValue);\n }\n}\n\n/**\n * Canonical JSON text for `value`, per RFC 8785 restricted to the value space\n * above. Key insertion order never affects the output; anything outside the\n * accepted space throws `proof_canonicalization_failed`.\n */\nexport function canonicalizeJson(value: JsonValue): string {\n return canonicalizeValue(value, '<root>', new Set());\n}\n\n/** UTF-8 bytes of {@link canonicalizeJson}. `TextEncoder` is a platform global on Node and Workers. */\nexport function canonicalizeJsonBytes(value: JsonValue): Uint8Array {\n return new TextEncoder().encode(canonicalizeJson(value));\n}\n\n// ---------------------------------------------------------------------------\n// Protected claims\n// ---------------------------------------------------------------------------\n\n/**\n * The signed claim set (§S6.2).\n *\n * The request line is expressible two ways — `method` + `path`, or a stable\n * `operationId` — and exactly one form must be present. Allowing both at once\n * would create two different canonical byte strings for one request; allowing\n * neither would drop the operation binding the whole design rests on.\n */\nexport const DeviceProofProtectedClaimsSchema = z\n .strictObject({\n version: z.literal(DEVICE_PROOF_VERSION),\n tenantId: z.string().min(1),\n productId: z.string().min(1),\n deviceId: z.string().min(1),\n /** Identity of the signing key, resolved against the device row at verify time. */\n keyId: z.string().min(1),\n /** Rotation generation. An older epoch is rejected by the verifier, not here. */\n keyEpoch: z.number().int().nonnegative(),\n /** Idempotency key: exact replay returns the original result, reuse with a different body is a conflict. */\n requestId: z.string().min(1),\n /** Logical operation, e.g. `truth.write`. */\n operation: z.string().min(1),\n /** Tenant-scoped resource the operation targets. */\n resource: z.string().min(1),\n method: z.string().regex(HTTP_METHOD_PATTERN).optional(),\n path: z.string().startsWith('/').optional(),\n operationId: z.string().min(1).optional(),\n bodySha256: z.string().regex(CONTENT_HASH_PATTERN),\n /** Bound alongside the hash so a truncation attack cannot hide behind a hash collision claim. */\n bodySize: z.number().int().nonnegative(),\n issuedAt: z.iso.datetime(),\n expiresAt: z.iso.datetime().optional(),\n nonce: z.string().min(1).optional(),\n })\n .superRefine((claims, ctx) => {\n const hasRequestLine = claims.method !== undefined && claims.path !== undefined;\n const hasOperationId = claims.operationId !== undefined;\n if (hasRequestLine === hasOperationId) {\n ctx.addIssue({\n code: 'custom',\n message:\n 'Claims must carry exactly one request binding: both `method` and `path`, or `operationId`.',\n });\n }\n if (!hasRequestLine && (claims.method !== undefined || claims.path !== undefined)) {\n ctx.addIssue({\n code: 'custom',\n message: '`method` and `path` must be supplied together.',\n });\n }\n });\n\nexport type DeviceProofProtectedClaims = z.infer<typeof DeviceProofProtectedClaimsSchema>;\n\nexport const DeviceProofEnvelopeV1Schema = z.strictObject({\n schema: z.literal(DEVICE_PROOF_SCHEMA_ID),\n algorithm: z.enum(DEVICE_PROOF_ALGORITHMS),\n protected: DeviceProofProtectedClaimsSchema,\n /** base64url, unpadded. */\n signature: z.string().regex(BASE64URL_PATTERN),\n});\n\nexport type DeviceProofEnvelopeV1 = z.infer<typeof DeviceProofEnvelopeV1Schema>;\n\n/**\n * Parses an envelope fail-closed.\n *\n * @throws {ByokCoreError} code `proof_envelope_invalid`.\n */\nexport function parseDeviceProofEnvelope(input: unknown): DeviceProofEnvelopeV1 {\n const result = DeviceProofEnvelopeV1Schema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'proof_envelope_invalid',\n `Invalid device proof envelope: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\n/**\n * Projects claims into the exact JSON object that gets canonicalized.\n *\n * Built field by field rather than by spreading the parsed object: an absent\n * optional must be an *absent key*, never a key holding `undefined`, or\n * `{nonce: undefined}` and `{}` would be the same request with two different\n * signatures. The canonicalizer refuses `undefined` outright, so this\n * projection is where absence is decided.\n */\nexport function deviceProofCanonicalClaims(claims: DeviceProofProtectedClaims): JsonObject {\n const canonical: Record<string, JsonValue> = {\n version: claims.version,\n tenantId: claims.tenantId,\n productId: claims.productId,\n deviceId: claims.deviceId,\n keyId: claims.keyId,\n keyEpoch: claims.keyEpoch,\n requestId: claims.requestId,\n operation: claims.operation,\n resource: claims.resource,\n bodySha256: claims.bodySha256,\n bodySize: claims.bodySize,\n issuedAt: claims.issuedAt,\n };\n if (claims.method !== undefined) canonical['method'] = claims.method;\n if (claims.path !== undefined) canonical['path'] = claims.path;\n if (claims.operationId !== undefined) canonical['operationId'] = claims.operationId;\n if (claims.expiresAt !== undefined) canonical['expiresAt'] = claims.expiresAt;\n if (claims.nonce !== undefined) canonical['nonce'] = claims.nonce;\n return canonical;\n}\n\n/** Canonical JSON text of the protected claim set, without the domain prefix. */\nexport function deviceProofCanonicalJson(claims: DeviceProofProtectedClaims): string {\n return canonicalizeJson(deviceProofCanonicalClaims(claims));\n}\n\n/**\n * The exact bytes a device signs and a verifier reconstructs:\n * `byok-device-proof-v1\\n` followed by the canonical claim JSON, UTF-8 encoded.\n *\n * Frozen by `src/__tests__/golden/device-proof-v1.canonical.json`.\n */\nexport function deviceProofSigningInput(claims: DeviceProofProtectedClaims): Uint8Array {\n return new TextEncoder().encode(\n DEVICE_PROOF_DOMAIN_PREFIX + deviceProofCanonicalJson(claims),\n );\n}\n\n// ---------------------------------------------------------------------------\n// Verify port\n// ---------------------------------------------------------------------------\n\nexport interface DeviceProofVerifyInput {\n readonly algorithm: DeviceProofAlgorithm;\n /** Raw public key, base64url — the JWK `x` encoding the device registry stores. */\n readonly publicKey: string;\n readonly signature: string;\n readonly signingInput: Uint8Array;\n}\n\n/**\n * Injected signature verification.\n *\n * Not a store port, so it has no tenant parameter: it answers a pure\n * cryptographic question about bytes. Deciding *which* key to check against is\n * the caller's tenant-scoped device-row lookup, and keeping that out of here is\n * what stops a verifier from becoming a second authority on device identity.\n */\nexport interface DeviceProofVerifier {\n verify(input: DeviceProofVerifyInput): Promise<boolean>;\n}\n","/**\n * The one timestamp format this package accepts across every composition.\n *\n * Every instant that crosses a store port is an ISO-8601 UTC string, and the\n * in-memory reference compares those strings with `<` / `>=` — a downgrade\n * grace deadline, a retention cutoff, a reservation expiry. Lexicographic\n * order equals chronological order **only** for the canonical\n * `YYYY-MM-DDTHH:mm:ss.sssZ` shape that `Date.prototype.toISOString` emits.\n * Feed the same store `2026-08-08T00:00:00+08:00` and the string comparison\n * silently answers a different question than a SQL `timestamptz` comparison\n * would, so the in-memory and Postgres compositions would diverge on an input\n * the conformance suite never sees.\n *\n * The fix is a format contract rather than a normalizer: a caller-supplied\n * timestamp that is not already canonical is **rejected**, not rewritten.\n * Rewriting would make this module a second authority on what instant the\n * caller meant, and an offset-bearing or second-precision string is exactly the\n * case where that guess is worth refusing.\n *\n * Store-produced timestamps are canonical by construction (they come from\n * `Clock.now().toISOString()`); this module guards the *inbound* direction —\n * `downgradeGraceUntil`, `deletePendingBefore`, `ackedBefore`,\n * `expireUnackedBefore`.\n *\n * No `node:` import and no clock read: validation is pure, so a Workers\n * composition and the constraint test (`Date.now()` is banned package-wide)\n * both stay happy. `Date.parse` is used for *calendar validity only* — the\n * pattern is what pins the shape.\n */\nimport { ByokCoreError } from './errors';\n\n/**\n * Exactly what `toISOString()` produces: four-digit year, `T` separator,\n * millisecond precision, literal `Z`. No offsets, no omitted milliseconds, no\n * expanded-year form — each of those breaks the lexicographic-order property.\n */\nexport const CANONICAL_TIMESTAMP_PATTERN =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n\n/**\n * True when `value` is a canonical ISO-8601 UTC instant.\n *\n * Two checks, in order: the pattern pins the *shape*, then a round trip\n * through `Date` pins *calendar validity* — `2026-02-30T00:00:00.000Z` matches\n * the pattern and is not an instant.\n */\nexport function isCanonicalTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') return false;\n if (!CANONICAL_TIMESTAMP_PATTERN.test(value)) return false;\n const parsed = Date.parse(value);\n if (!Number.isFinite(parsed)) return false;\n return new Date(parsed).toISOString() === value;\n}\n\n/**\n * Fail-closed gate for a caller-supplied instant.\n *\n * @param value The timestamp as received from the caller.\n * @param field Field name, so the failure names the contract that was missed\n * rather than just the bad string.\n * @returns The same string, so call sites can validate and assign in one step.\n * @throws {ByokCoreError} code `timestamp_not_canonical`.\n */\nexport function assertCanonicalTimestamp(value: string, field: string): string {\n if (!isCanonicalTimestamp(value)) {\n throw new ByokCoreError(\n 'timestamp_not_canonical',\n `${field} must be a canonical ISO-8601 UTC instant (YYYY-MM-DDTHH:mm:ss.sssZ), received ${JSON.stringify(value)}.`,\n );\n }\n return value;\n}\n","/**\n * A zod parse that never throws.\n *\n * `safeParse` returns a failure for invalid data, but it does not catch an\n * error that a getter or a proxy trap throws while zod reads the value, and a\n * revoked proxy throws on any read. A receiver that promises a typed result\n * for hostile input, or a typed error for bad caller input, parses through\n * this. Wire input from `JSON.parse` cannot hold getters or proxies; this\n * closes the same gap for in-process callers.\n */\nimport type { z } from 'zod';\n\nexport type TotalParseResult<T> =\n | { readonly success: true; readonly data: T }\n | { readonly success: false; readonly error?: z.ZodError };\n\n/** `schema.safeParse(value)`, with a throw while reading `value` as a failure without issues. */\nexport function safeParseTotal<S extends z.ZodType>(schema: S, value: unknown): TotalParseResult<z.output<S>> {\n try {\n return schema.safeParse(value);\n } catch {\n return { success: false };\n }\n}\n","/**\n * The WebCrypto surface core relies on, declared structurally so core's\n * published types need neither the DOM lib nor Node's types, and resolved\n * from `globalThis.crypto.subtle` so the browser, Node, and Bun share one\n * code path. No `node:crypto`.\n */\nimport { ByokCoreError } from './errors';\n\n/**\n * A WebCrypto `CryptoKey`, declared structurally so core's published types\n * need neither the DOM lib nor Node's types. Every runtime's native\n * `CryptoKey` satisfies it.\n */\nexport interface WebCryptoKey {\n readonly type: string;\n readonly extractable: boolean;\n readonly algorithm: object;\n readonly usages: readonly string[];\n}\n\n/** The subset of `SubtleCrypto` this package calls, typed loosely on purpose (see {@link WebCryptoKey}). */\nexport interface WebCryptoSubtle {\n importKey(format: 'raw' | 'jwk', keyData: object, algorithm: object, extractable: boolean, usages: string[]): Promise<WebCryptoKey>;\n exportKey(format: 'raw', key: WebCryptoKey): Promise<ArrayBuffer>;\n generateKey(algorithm: object, extractable: boolean, usages: string[]): Promise<{ publicKey: WebCryptoKey; privateKey: WebCryptoKey }>;\n deriveBits(algorithm: object, baseKey: WebCryptoKey, length: number): Promise<ArrayBuffer>;\n sign(algorithm: string, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n encrypt(algorithm: object, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n decrypt(algorithm: object, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n digest(algorithm: string, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n}\n\n/** The WebCrypto subtle interface, or a closed-set failure when the runtime lacks it. */\nexport function webCryptoSubtle(): WebCryptoSubtle {\n const subtle = (globalThis as { crypto?: { subtle?: WebCryptoSubtle } }).crypto?.subtle;\n if (subtle === undefined) {\n throw new ByokCoreError('webcrypto_unavailable', 'WebCrypto subtle is unavailable in this runtime');\n }\n return subtle;\n}\n","/**\n * RFC 9180 HPKE, base mode, exactly one cipher suite:\n * `DHKEM(P-256, HKDF-SHA256) / HKDF-SHA256 / AES-128-GCM`\n * (KEM `0x0010`, KDF `0x0001`, AEAD `0x0001`).\n *\n * Why this module exists instead of a dependency: the same bytes must be\n * produced in a browser (the Web seals a provider key), in Node, and in a\n * Bun-compiled device daemon (which opens it). Every primitive used here —\n * P-256 ECDH, HMAC-SHA-256, AES-GCM, SHA-256, random key generation — is a\n * WebCrypto primitive all three runtimes ship, so the suite needs no\n * third-party code and no `node:` import (core must stay Workers/browser\n * safe). There is no algorithm negotiation: one suite, one mode, and anything\n * else is rejected by the envelope schema before this module is reached.\n *\n * Only one-shot seal/open is reachable from the package root. The key\n * schedule and sequence-numbered nonces are exported from this module for the\n * RFC 9180 Appendix A.3 conformance tests only; `index.ts` never re-exports a\n * reusable encryption context.\n *\n * Self-implemented HPKE: RFC vectors and an independent implementation\n * interoperate in the test suite, but passing vectors is not an audit. A\n * dedicated security review is required before a release is published.\n */\nimport { ByokCoreError } from './errors';\nimport { webCryptoSubtle, type WebCryptoKey } from './webcrypto';\n\nconst KEM_ID = 0x0010;\nconst KDF_ID = 0x0001;\nconst AEAD_ID = 0x0001;\n\n/** Encoded P-256 public key and encapsulation length (uncompressed SEC1). */\nexport const HPKE_P256_PUBLIC_KEY_BYTES = 65;\nconst N_SECRET = 32;\nconst N_K = 16;\nconst N_N = 12;\nconst N_H = 32;\n/** AES-GCM authentication tag length. */\nexport const HPKE_AEAD_TAG_BYTES = 16;\n\nconst MODE_BASE = 0x00;\nconst HPKE_V1 = utf8('HPKE-v1');\nconst KEM_SUITE_ID = concat(utf8('KEM'), i2osp(KEM_ID, 2));\nconst HPKE_SUITE_ID = concat(utf8('HPKE'), i2osp(KEM_ID, 2), i2osp(KDF_ID, 2), i2osp(AEAD_ID, 2));\nconst EMPTY = new Uint8Array(0);\n/** HMAC pads its key with zeros to the block size, so an empty salt equals HashLen zeros. */\nconst ZERO_SALT = new Uint8Array(N_H);\n\ntype Bytes = Uint8Array<ArrayBuffer>;\n\nfunction utf8(value: string): Bytes {\n return new TextEncoder().encode(value) as Bytes;\n}\n\nfunction concat(...parts: readonly Uint8Array[]): Bytes {\n const length = parts.reduce((total, part) => total + part.byteLength, 0);\n const out = new Uint8Array(length);\n let offset = 0;\n for (const part of parts) {\n out.set(part, offset);\n offset += part.byteLength;\n }\n return out;\n}\n\nfunction i2osp(value: number, length: number): Bytes {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE integer encoding requires a non-negative safe integer');\n }\n const out = new Uint8Array(length);\n let remaining = value;\n for (let index = length - 1; index >= 0; index -= 1) {\n out[index] = remaining % 256;\n remaining = Math.floor(remaining / 256);\n }\n if (remaining !== 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE integer does not fit the requested width');\n }\n return out;\n}\n\nfunction copy(bytes: Uint8Array): Bytes {\n return new Uint8Array(bytes) as Bytes;\n}\n\nasync function hmacSha256(key: Uint8Array, data: Uint8Array): Promise<Bytes> {\n const subtle = webCryptoSubtle();\n const hmacKey = await subtle.importKey('raw', copy(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n return new Uint8Array(await subtle.sign('HMAC', hmacKey, copy(data))) as Bytes;\n}\n\nasync function hkdfExpand(prk: Uint8Array, info: Uint8Array, length: number): Promise<Bytes> {\n if (length > 255 * N_H) {\n throw new ByokCoreError('sealed_secret_invalid', 'HKDF output length exceeds its limit');\n }\n const out = new Uint8Array(length);\n let previous: Uint8Array = EMPTY;\n let offset = 0;\n for (let counter = 1; offset < length; counter += 1) {\n previous = await hmacSha256(prk, concat(previous, info, Uint8Array.of(counter)));\n const take = Math.min(previous.byteLength, length - offset);\n out.set(previous.subarray(0, take), offset);\n offset += take;\n }\n return out as Bytes;\n}\n\nasync function labeledExtract(suiteId: Uint8Array, salt: Uint8Array, label: string, ikm: Uint8Array): Promise<Bytes> {\n return hmacSha256(salt.byteLength === 0 ? ZERO_SALT : salt, concat(HPKE_V1, suiteId, utf8(label), ikm));\n}\n\nasync function labeledExpand(\n suiteId: Uint8Array,\n prk: Uint8Array,\n label: string,\n info: Uint8Array,\n length: number,\n): Promise<Bytes> {\n return hkdfExpand(prk, concat(i2osp(length, 2), HPKE_V1, suiteId, utf8(label), info), length);\n}\n\n/**\n * Import an uncompressed SEC1 P-256 public key for ECDH.\n *\n * The length and `0x04` prefix are checked here; the on-curve check is the\n * WebCrypto import itself, which rejects a point that is not on P-256.\n */\nexport async function importP256PublicKey(raw: Uint8Array): Promise<WebCryptoKey> {\n if (raw.byteLength !== HPKE_P256_PUBLIC_KEY_BYTES || raw[0] !== 0x04) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 public key must be a 65-byte uncompressed point');\n }\n try {\n return await webCryptoSubtle().importKey('raw', copy(raw), { name: 'ECDH', namedCurve: 'P-256' }, true, []);\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 public key is not a valid curve point', { cause });\n }\n}\n\nasync function ecdhP256(privateKey: WebCryptoKey, publicKey: WebCryptoKey): Promise<Bytes> {\n const bits = await webCryptoSubtle().deriveBits({ name: 'ECDH', public: publicKey }, privateKey, N_SECRET * 8);\n return new Uint8Array(bits) as Bytes;\n}\n\nasync function extractAndExpand(dh: Uint8Array, kemContext: Uint8Array): Promise<Bytes> {\n const eaePrk = await labeledExtract(KEM_SUITE_ID, EMPTY, 'eae_prk', dh);\n return labeledExpand(KEM_SUITE_ID, eaePrk, 'shared_secret', kemContext, N_SECRET);\n}\n\n/** Key schedule output for base mode. Exported for the RFC 9180 conformance tests only. */\nexport interface HpkeBaseKeySchedule {\n readonly sharedSecret: Uint8Array;\n readonly key: Uint8Array;\n readonly baseNonce: Uint8Array;\n readonly exporterSecret: Uint8Array;\n}\n\nasync function keyScheduleBase(sharedSecret: Uint8Array, info: Uint8Array): Promise<HpkeBaseKeySchedule> {\n const pskIdHash = await labeledExtract(HPKE_SUITE_ID, EMPTY, 'psk_id_hash', EMPTY);\n const infoHash = await labeledExtract(HPKE_SUITE_ID, EMPTY, 'info_hash', info);\n const context = concat(Uint8Array.of(MODE_BASE), pskIdHash, infoHash);\n const secret = await labeledExtract(HPKE_SUITE_ID, sharedSecret, 'secret', EMPTY);\n return {\n sharedSecret,\n key: await labeledExpand(HPKE_SUITE_ID, secret, 'key', context, N_K),\n baseNonce: await labeledExpand(HPKE_SUITE_ID, secret, 'base_nonce', context, N_N),\n exporterSecret: await labeledExpand(HPKE_SUITE_ID, secret, 'exp', context, N_H),\n };\n}\n\n/** A caller-fixed ephemeral key pair. Conformance tests only; production always generates one. */\nexport interface HpkeEphemeralKeyPair {\n readonly privateKey: WebCryptoKey;\n readonly publicKey: Uint8Array;\n}\n\n/** `SetupBaseS`. Exported for the RFC 9180 conformance tests only. */\nexport async function setupBaseSender(\n recipientPublicKey: Uint8Array,\n info: Uint8Array,\n ephemeral?: HpkeEphemeralKeyPair,\n): Promise<{ enc: Uint8Array; schedule: HpkeBaseKeySchedule }> {\n const pkR = await importP256PublicKey(recipientPublicKey);\n let pair = ephemeral;\n if (pair === undefined) {\n const subtle = webCryptoSubtle();\n const generated = await subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveBits']);\n pair = {\n privateKey: generated.privateKey,\n publicKey: new Uint8Array(await subtle.exportKey('raw', generated.publicKey)),\n };\n }\n const enc = copy(pair.publicKey);\n const dh = await ecdhP256(pair.privateKey, pkR);\n const sharedSecret = await extractAndExpand(dh, concat(enc, recipientPublicKey));\n return { enc, schedule: await keyScheduleBase(sharedSecret, info) };\n}\n\n/** `SetupBaseR`. Exported for the RFC 9180 conformance tests only. */\nexport async function setupBaseRecipient(\n enc: Uint8Array,\n recipientPrivateKey: WebCryptoKey,\n recipientPublicKey: Uint8Array,\n info: Uint8Array,\n): Promise<HpkeBaseKeySchedule> {\n if (recipientPublicKey.byteLength !== HPKE_P256_PUBLIC_KEY_BYTES || recipientPublicKey[0] !== 0x04) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 recipient public key must be a 65-byte uncompressed point');\n }\n const pkE = await importP256PublicKey(enc);\n let dh: Bytes;\n try {\n dh = await ecdhP256(recipientPrivateKey, pkE);\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_open_failed', 'HPKE decapsulation failed', { cause });\n }\n const sharedSecret = await extractAndExpand(dh, concat(enc, recipientPublicKey));\n return keyScheduleBase(sharedSecret, info);\n}\n\n/** `ComputeNonce(seq)`. Exported for the RFC 9180 conformance tests only. */\nexport function hpkeNonce(baseNonce: Uint8Array, sequence: number): Bytes {\n const seq = i2osp(sequence, N_N);\n const out = new Uint8Array(N_N);\n for (let index = 0; index < N_N; index += 1) out[index] = baseNonce[index]! ^ seq[index]!;\n return out as Bytes;\n}\n\nasync function aesGcmKey(key: Uint8Array, usage: 'encrypt' | 'decrypt'): Promise<WebCryptoKey> {\n return webCryptoSubtle().importKey('raw', copy(key), { name: 'AES-GCM' }, false, [usage]);\n}\n\n/** AEAD seal at an explicit sequence number. Exported for the RFC 9180 conformance tests only. */\nexport async function hpkeAeadSeal(\n schedule: HpkeBaseKeySchedule,\n sequence: number,\n aad: Uint8Array,\n plaintext: Uint8Array,\n): Promise<Bytes> {\n const ciphertext = await webCryptoSubtle().encrypt(\n { name: 'AES-GCM', iv: hpkeNonce(schedule.baseNonce, sequence), additionalData: copy(aad), tagLength: 128 },\n await aesGcmKey(schedule.key, 'encrypt'),\n copy(plaintext),\n );\n return new Uint8Array(ciphertext) as Bytes;\n}\n\n/** AEAD open at an explicit sequence number. Exported for the RFC 9180 conformance tests only. */\nexport async function hpkeAeadOpen(\n schedule: HpkeBaseKeySchedule,\n sequence: number,\n aad: Uint8Array,\n ciphertext: Uint8Array,\n): Promise<Bytes> {\n if (ciphertext.byteLength < HPKE_AEAD_TAG_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE ciphertext is shorter than its authentication tag');\n }\n try {\n const plaintext = await webCryptoSubtle().decrypt(\n { name: 'AES-GCM', iv: hpkeNonce(schedule.baseNonce, sequence), additionalData: copy(aad), tagLength: 128 },\n await aesGcmKey(schedule.key, 'decrypt'),\n copy(ciphertext),\n );\n return new Uint8Array(plaintext) as Bytes;\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_open_failed', 'HPKE ciphertext failed authentication', { cause });\n }\n}\n\n/** One-shot `SealBase`: a fresh ephemeral key, sequence 0, never reused. */\nexport async function hpkeSealBase(input: {\n readonly recipientPublicKey: Uint8Array;\n readonly info: Uint8Array;\n readonly aad: Uint8Array;\n readonly plaintext: Uint8Array;\n}): Promise<{ enc: Uint8Array; ciphertext: Uint8Array }> {\n const { enc, schedule } = await setupBaseSender(input.recipientPublicKey, input.info);\n return { enc, ciphertext: await hpkeAeadSeal(schedule, 0, input.aad, input.plaintext) };\n}\n\n/** One-shot `OpenBase`, sequence 0. */\nexport async function hpkeOpenBase(input: {\n readonly recipientPrivateKey: WebCryptoKey;\n readonly recipientPublicKey: Uint8Array;\n readonly enc: Uint8Array;\n readonly info: Uint8Array;\n readonly aad: Uint8Array;\n readonly ciphertext: Uint8Array;\n}): Promise<Uint8Array> {\n const schedule = await setupBaseRecipient(input.enc, input.recipientPrivateKey, input.recipientPublicKey, input.info);\n return hpkeAeadOpen(schedule, 0, input.aad, input.ciphertext);\n}\n","/**\n * Sealed provider provisioning v1 (plan web-sealed-provisioning §3).\n *\n * A browser seals a provider API key to one device's long-lived P-256\n * sealing key; the cloud relays only ciphertext; the device opens it in\n * memory. This module is the single byte authority both ends share:\n *\n * - the request schema (header + non-secret config + optional sealed secret),\n * - canonical AAD bytes, config digest, and request digest,\n * - the sealing-key claim canonical bytes a device signs at registration,\n * - plaintext padding (2-byte length prefix, zero-padded to 256-byte blocks),\n * - one-shot seal/open on top of `hpke.ts`.\n *\n * Every function is WebCrypto-only and `node:`-free so the Web bundle and the\n * device use literally the same code. Nothing here reads a clock, a network,\n * or a store; time windows, replay ledgers, placement and enrollment are the\n * device's (`@byok-sdk/keys`) decisions.\n *\n * Error messages never include plaintext, ciphertext, or key material.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson, canonicalizeJsonBytes, type JsonObject, type JsonValue } from './attestation';\nimport { CONTENT_HASH_PATTERN } from './blob';\nimport { ByokCoreError } from './errors';\nimport {\n HPKE_AEAD_TAG_BYTES,\n HPKE_P256_PUBLIC_KEY_BYTES,\n hpkeOpenBase,\n hpkeSealBase,\n importP256PublicKey,\n} from './hpke';\nimport { isCanonicalTimestamp } from './time';\nimport { safeParseTotal } from './total-parse';\nimport { webCryptoSubtle, type WebCryptoKey } from './webcrypto';\n\nexport type { WebCryptoKey } from './webcrypto';\n\n/** The only HPKE suite v1 admits. There is no negotiation and no second value. */\nexport const PROVIDER_SECRET_HPKE_SUITE = 'hpke-base.dhkem-p256-hkdf-sha256.hkdf-sha256.aes-128-gcm';\n\n/** HPKE `info`, versioned; a v2 is a new constant, never a parser branch. */\nexport const PROVIDER_SECRET_HPKE_INFO = 'byok-sdk.provider-secret.v1';\n\nexport const PROVIDER_PROVISIONING_REQUEST_VERSION = 1;\n\nexport const PROVIDER_PROVISIONING_OPERATIONS = ['configure', 'update_model', 'replace_secret', 'delete'] as const;\nexport type ProviderProvisioningOperation = (typeof PROVIDER_PROVISIONING_OPERATIONS)[number];\n\n/** Operations whose request must carry exactly one sealed secret. */\nexport const PROVIDER_PROVISIONING_SECRET_OPERATIONS = ['configure', 'replace_secret'] as const;\n\n/** Upper bound for `expiresAt - issuedAt` (plan D11). */\nexport const PROVIDER_PROVISIONING_MAX_TTL_MS = 15 * 60 * 1000;\n\n/** Plaintext is padded to a multiple of this many bytes so ciphertext length hides key length. */\nexport const PROVIDER_SECRET_PAD_BLOCK_BYTES = 256;\n\n/** Largest padded plaintext v1 accepts; the secret itself is at most this minus the 2-byte prefix. */\nexport const PROVIDER_SECRET_MAX_PADDED_BYTES = 4096;\n\nexport const PROVIDER_SECRET_MAX_BYTES = PROVIDER_SECRET_MAX_PADDED_BYTES - 2;\n\n/** Length of a sealing key id: base64url(sha256(raw public key)) truncated to 22 characters. */\nexport const SEALING_KEY_ID_LENGTH = 22;\n\n// ---------------------------------------------------------------------------\n// base64url (strict, unpadded, canonical)\n// ---------------------------------------------------------------------------\n\nconst B64URL_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\nconst B64URL_PATTERN = /^[A-Za-z0-9_-]*$/;\n\nexport function encodeBase64Url(bytes: Uint8Array): string {\n let out = '';\n let index = 0;\n for (; index + 3 <= bytes.length; index += 3) {\n const value = (bytes[index]! << 16) | (bytes[index + 1]! << 8) | bytes[index + 2]!;\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!\n + B64URL_ALPHABET[(value >> 6) & 63]! + B64URL_ALPHABET[value & 63]!;\n }\n const rest = bytes.length - index;\n if (rest === 1) {\n const value = bytes[index]! << 16;\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!;\n } else if (rest === 2) {\n const value = (bytes[index]! << 16) | (bytes[index + 1]! << 8);\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!\n + B64URL_ALPHABET[(value >> 6) & 63]!;\n }\n return out;\n}\n\n/** Decode canonical unpadded base64url, or throw — never a repaired approximation. */\nexport function decodeBase64Url(value: string, field: string): Uint8Array<ArrayBuffer> {\n if (!B64URL_PATTERN.test(value) || value.length % 4 === 1) {\n throw new ByokCoreError('sealed_secret_invalid', `${field} is not canonical base64url`);\n }\n const out = new Uint8Array(Math.floor((value.length * 3) / 4));\n let buffer = 0;\n let bits = 0;\n let offset = 0;\n for (const char of value) {\n buffer = (buffer << 6) | B64URL_ALPHABET.indexOf(char);\n bits += 6;\n if (bits >= 8) {\n bits -= 8;\n out[offset] = (buffer >> bits) & 0xff;\n offset += 1;\n }\n }\n if (encodeBase64Url(out) !== value) {\n throw new ByokCoreError('sealed_secret_invalid', `${field} is not canonical base64url`);\n }\n return out;\n}\n\nfunction base64UrlField(bytes: { exact?: number; max?: number }) {\n return z.string().superRefine((value, ctx) => {\n try {\n const decoded = decodeBase64Url(value, 'field');\n if (bytes.exact !== undefined && decoded.byteLength !== bytes.exact) {\n ctx.addIssue({ code: 'custom', message: `must decode to exactly ${bytes.exact} bytes` });\n }\n if (bytes.max !== undefined && decoded.byteLength > bytes.max) {\n ctx.addIssue({ code: 'custom', message: `must decode to at most ${bytes.max} bytes` });\n }\n } catch {\n ctx.addIssue({ code: 'custom', message: 'must be canonical unpadded base64url' });\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Hashing\n// ---------------------------------------------------------------------------\n\nasync function sha256(bytes: Uint8Array): Promise<Uint8Array> {\n return new Uint8Array(await webCryptoSubtle().digest('SHA-256', new Uint8Array(bytes)));\n}\n\nfunction hex(bytes: Uint8Array): string {\n let out = '';\n for (const byte of bytes) out += byte.toString(16).padStart(2, '0');\n return out;\n}\n\nasync function contentDigest(value: JsonValue): Promise<string> {\n return `sha256:${hex(await sha256(canonicalizeJsonBytes(value)))}`;\n}\n\n// ---------------------------------------------------------------------------\n// Sealing key (public JWK + claim)\n// ---------------------------------------------------------------------------\n\n/**\n * The only public-key shape v1 accepts. Strict: a `d` (private) member, an\n * `alg`, `use`, `key_ops` or any other extra member is rejected rather than\n * ignored, so a private JWK can never be published by mistake.\n */\nexport const SealingPublicJwkSchema = z.strictObject({\n kty: z.literal('EC'),\n crv: z.literal('P-256'),\n x: base64UrlField({ exact: 32 }),\n y: base64UrlField({ exact: 32 }),\n});\nexport type SealingPublicJwk = z.infer<typeof SealingPublicJwkSchema>;\n\nexport const SealingKeyIdSchema = z.string().regex(new RegExp(`^[A-Za-z0-9_-]{${SEALING_KEY_ID_LENGTH}}$`));\n\nfunction parseSealingPublicJwk(input: unknown): SealingPublicJwk {\n const result = safeParseTotal(SealingPublicJwkSchema, input);\n if (!result.success) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing public key must be a strict P-256 EC public JWK');\n }\n return result.data;\n}\n\n/** Uncompressed SEC1 bytes (`0x04 || x || y`) of a sealing public JWK. */\nexport function sealingPublicKeyBytes(publicJwk: SealingPublicJwk): Uint8Array<ArrayBuffer> {\n const jwk = parseSealingPublicJwk(publicJwk);\n const raw = new Uint8Array(HPKE_P256_PUBLIC_KEY_BYTES);\n raw[0] = 0x04;\n raw.set(decodeBase64Url(jwk.x, 'x'), 1);\n raw.set(decodeBase64Url(jwk.y, 'y'), 33);\n return raw;\n}\n\n/** `base64url(sha256(0x04 || x || y))[0..22]` — the device's and the browser's shared key id rule. */\nexport async function deriveSealingKeyId(publicJwk: SealingPublicJwk): Promise<string> {\n const raw = sealingPublicKeyBytes(publicJwk);\n await importP256PublicKey(raw);\n return encodeBase64Url(await sha256(raw)).slice(0, SEALING_KEY_ID_LENGTH);\n}\n\n/**\n * The claim a device signs (through its device-proof signer, host glue) when\n * it registers its sealing key. The proof body is these canonical bytes.\n */\nexport const SealingKeyClaimV1Schema = z.strictObject({\n version: z.literal(1),\n keyId: SealingKeyIdSchema,\n epoch: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n publicJwk: SealingPublicJwkSchema,\n});\nexport type SealingKeyClaimV1 = z.infer<typeof SealingKeyClaimV1Schema>;\n\n/** Canonical UTF-8 bytes of a sealing-key claim. */\nexport function sealingKeyClaimCanonicalBytes(claim: SealingKeyClaimV1): Uint8Array {\n const result = safeParseTotal(SealingKeyClaimV1Schema, claim);\n if (!result.success) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing key claim is invalid');\n }\n const parsed = result.data;\n return canonicalizeJsonBytes({\n version: parsed.version,\n keyId: parsed.keyId,\n epoch: parsed.epoch,\n publicJwk: { kty: parsed.publicJwk.kty, crv: parsed.publicJwk.crv, x: parsed.publicJwk.x, y: parsed.publicJwk.y },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Request schema\n// ---------------------------------------------------------------------------\n\n/** Opaque identifier: non-empty, bounded, no surrounding whitespace, no control characters. */\nconst OpaqueIdSchema = z.string().min(1).max(200).superRefine((value, ctx) => {\n if (value.trim() !== value || /[\\u0000-\\u001f\\u007f]/u.test(value)) {\n ctx.addIssue({ code: 'custom', message: 'must not carry surrounding whitespace or control characters' });\n }\n});\n\nconst CanonicalTimestampSchema = z.string().refine(isCanonicalTimestamp, 'must be a canonical ISO-8601 UTC instant');\n\nconst ProfileRefSchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/u);\nconst ProviderKindSchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/u);\nconst ModelIdSchema = z.string().min(1).max(160).refine((value) => value.trim() === value && !/[\\u0000-\\u001f\\u007f]/u.test(value), 'model id is invalid');\nconst CapabilitySchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/u);\n\n/**\n * `pi_model` travels as an opaque canonicalizable JSON object; the device\n * validates it against `@byok-sdk/keys`' strict `PiModelConfigSchema`. Core\n * only guarantees it has one canonical byte form.\n */\nconst PiModelJsonSchema = z.custom<JsonObject>((value) => {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return false;\n try {\n canonicalizeJson(value as JsonObject);\n return true;\n } catch {\n return false;\n }\n}, 'piModel must be a canonical JSON object');\n\nconst ModelConfigFields = {\n agentId: OpaqueIdSchema,\n providerKind: ProviderKindSchema,\n modelId: ModelIdSchema,\n piModel: PiModelJsonSchema,\n capabilities: z.array(CapabilitySchema).max(8).refine((values) => new Set(values).size === values.length, 'capabilities must be unique'),\n};\n\n/**\n * The non-secret configuration, one exact shape per operation. An operation\n * carries only the fields it acts on — `delete` has no model, `replace_secret`\n * declares only the provider kind its key is scoped to — so nothing is\n * accepted and silently ignored.\n */\nexport const ProviderProvisioningConfigV1Schema = z.discriminatedUnion('operation', [\n z.strictObject({ operation: z.literal('configure'), ...ModelConfigFields }),\n z.strictObject({ operation: z.literal('update_model'), ...ModelConfigFields }),\n z.strictObject({ operation: z.literal('replace_secret'), agentId: OpaqueIdSchema, providerKind: ProviderKindSchema }),\n z.strictObject({ operation: z.literal('delete'), agentId: OpaqueIdSchema }),\n]);\nexport type ProviderProvisioningConfigV1 = z.infer<typeof ProviderProvisioningConfigV1Schema>;\n\n/** The credential-free provider triple the Host believes is current (A3), or `null` for none. */\nexport const ProviderProvisioningExpectedProfileSchema = z.union([\n z.null(),\n z.strictObject({\n profileRef: ProfileRefSchema,\n profileRevision: z.string().regex(/^(?:0|[1-9][0-9]{0,19})$/u),\n profileHash: z.string().regex(CONTENT_HASH_PATTERN),\n }),\n]);\nexport type ProviderProvisioningExpectedProfile = z.infer<typeof ProviderProvisioningExpectedProfileSchema>;\n\n/**\n * Opaque, Host-issued identity version: the enrollment revision (changes on\n * re-pair / re-enrollment of the same device id) or the agent placement\n * revision. The device compares it byte-for-byte with its own snapshot.\n */\nexport const ProviderProvisioningIdentityRevisionSchema = z.string().min(1).max(128).regex(/^[A-Za-z0-9._:-]+$/u);\n\nexport const ProviderProvisioningHeaderV1Schema = z.strictObject({\n tenantId: OpaqueIdSchema,\n deviceId: OpaqueIdSchema,\n agentId: OpaqueIdSchema,\n requestId: OpaqueIdSchema,\n operation: z.enum(PROVIDER_PROVISIONING_OPERATIONS),\n /** Non-secret, strictly increasing per bot (A3); a device rejects anything not above its high-watermark. */\n operationGeneration: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n expectedProfile: ProviderProvisioningExpectedProfileSchema,\n /** The device enrollment revision the Host authorized against (F2). */\n expectedEnrollmentRevision: ProviderProvisioningIdentityRevisionSchema,\n /** The agent placement revision the Host authorized against (F2). */\n expectedPlacementRevision: ProviderProvisioningIdentityRevisionSchema,\n configDigest: z.string().regex(CONTENT_HASH_PATTERN),\n issuedAt: CanonicalTimestampSchema,\n expiresAt: CanonicalTimestampSchema,\n});\nexport type ProviderProvisioningHeaderV1 = z.infer<typeof ProviderProvisioningHeaderV1Schema>;\n\n/** Ciphertext bound: largest padded plaintext plus the AEAD tag. */\nconst MAX_CIPHERTEXT_BYTES = PROVIDER_SECRET_MAX_PADDED_BYTES + HPKE_AEAD_TAG_BYTES;\n\nexport const SealedProviderSecretV1Schema = z.strictObject({\n suite: z.literal(PROVIDER_SECRET_HPKE_SUITE),\n keyId: SealingKeyIdSchema,\n enc: base64UrlField({ exact: HPKE_P256_PUBLIC_KEY_BYTES }),\n ciphertext: base64UrlField({ max: MAX_CIPHERTEXT_BYTES }),\n});\nexport type SealedProviderSecretV1 = z.infer<typeof SealedProviderSecretV1Schema>;\n\nfunction isSecretOperation(operation: ProviderProvisioningOperation): boolean {\n return (PROVIDER_PROVISIONING_SECRET_OPERATIONS as readonly string[]).includes(operation);\n}\n\nexport const ProviderProvisioningRequestV1Schema = z\n .strictObject({\n version: z.literal(PROVIDER_PROVISIONING_REQUEST_VERSION),\n header: ProviderProvisioningHeaderV1Schema,\n config: ProviderProvisioningConfigV1Schema,\n sealed: SealedProviderSecretV1Schema.optional(),\n })\n .superRefine((request, ctx) => {\n if (request.header.operation !== request.config.operation) {\n ctx.addIssue({ code: 'custom', path: ['config', 'operation'], message: 'config operation must equal header operation' });\n }\n if (request.header.agentId !== request.config.agentId) {\n ctx.addIssue({ code: 'custom', path: ['config', 'agentId'], message: 'config agentId must equal header agentId' });\n }\n if (isSecretOperation(request.header.operation) !== (request.sealed !== undefined)) {\n ctx.addIssue({ code: 'custom', path: ['sealed'], message: 'a sealed secret is required exactly for configure and replace_secret' });\n }\n });\nexport type ProviderProvisioningRequestV1 = z.infer<typeof ProviderProvisioningRequestV1Schema>;\n\n/** Parse a request fail-closed. Issue text names paths and rules only, never values. */\nexport function parseProviderProvisioningRequest(input: unknown): ProviderProvisioningRequestV1 {\n const result = safeParseTotal(ProviderProvisioningRequestV1Schema, input);\n if (!result.success) {\n throw new ByokCoreError(\n 'provider_provisioning_request_invalid',\n `Invalid provider provisioning request: ${(result.error?.issues ?? [{ path: [], message: 'is not readable' }])\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n );\n }\n return result.data;\n}\n\n// ---------------------------------------------------------------------------\n// Canonical bytes and digests\n// ---------------------------------------------------------------------------\n\nfunction configJson(config: ProviderProvisioningConfigV1): JsonObject {\n return config as unknown as JsonObject;\n}\n\n/** `sha256:<hex>` over the canonical JSON of the non-secret config. */\nexport async function providerProvisioningConfigDigest(config: ProviderProvisioningConfigV1): Promise<string> {\n const result = safeParseTotal(ProviderProvisioningConfigV1Schema, config);\n if (!result.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config is invalid');\n }\n return contentDigest(configJson(result.data));\n}\n\n/**\n * Canonical AAD bytes. Every header field plus the sealing key id is bound,\n * so tampering with any of tenant, device, key, request, agent, operation,\n * generation, expected triple, expected enrollment and placement revisions,\n * config digest, or time window fails the AEAD.\n */\nexport function providerSecretAadBytes(header: ProviderProvisioningHeaderV1, keyId: string): Uint8Array {\n const parsed = safeParseTotal(ProviderProvisioningHeaderV1Schema, header);\n if (!parsed.success || !safeParseTotal(SealingKeyIdSchema, keyId).success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning AAD input is invalid');\n }\n const value = parsed.data;\n return canonicalizeJsonBytes({\n v: PROVIDER_PROVISIONING_REQUEST_VERSION,\n tenantId: value.tenantId,\n deviceId: value.deviceId,\n keyId,\n requestId: value.requestId,\n agentId: value.agentId,\n operation: value.operation,\n operationGeneration: value.operationGeneration,\n expectedProfile: value.expectedProfile === null\n ? null\n : {\n profileRef: value.expectedProfile.profileRef,\n profileRevision: value.expectedProfile.profileRevision,\n profileHash: value.expectedProfile.profileHash,\n },\n expectedEnrollmentRevision: value.expectedEnrollmentRevision,\n expectedPlacementRevision: value.expectedPlacementRevision,\n configDigest: value.configDigest,\n issuedAt: value.issuedAt,\n expiresAt: value.expiresAt,\n });\n}\n\n/**\n * `sha256:<hex>` over the canonical JSON of the complete request. A device\n * compares it for an already-seen `requestId`: equal returns the stored\n * result, different is a conflict.\n */\nexport async function providerProvisioningRequestDigest(request: ProviderProvisioningRequestV1): Promise<string> {\n const parsed = parseProviderProvisioningRequest(request);\n return contentDigest(parsed as unknown as JsonObject);\n}\n\n/** Fail closed unless `header.configDigest` is the digest of `config`. */\nexport async function assertProviderProvisioningConfigDigest(request: ProviderProvisioningRequestV1): Promise<void> {\n const parsed = parseProviderProvisioningRequest(request);\n if ((await providerProvisioningConfigDigest(parsed.config)) !== parsed.header.configDigest) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config digest does not match its header');\n }\n}\n\n// ---------------------------------------------------------------------------\n// Padding\n// ---------------------------------------------------------------------------\n\n/** `u16be(len) || utf8(secret) || zeros`, total a multiple of 256 bytes. */\nexport function padProviderSecret(secret: string): Uint8Array<ArrayBuffer> {\n const bytes = new TextEncoder().encode(secret);\n if (bytes.byteLength === 0 || bytes.byteLength > PROVIDER_SECRET_MAX_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', `Provider secret must be 1 to ${PROVIDER_SECRET_MAX_BYTES} UTF-8 bytes`);\n }\n const total = Math.ceil((bytes.byteLength + 2) / PROVIDER_SECRET_PAD_BLOCK_BYTES) * PROVIDER_SECRET_PAD_BLOCK_BYTES;\n const out = new Uint8Array(total);\n out[0] = bytes.byteLength >> 8;\n out[1] = bytes.byteLength & 0xff;\n out.set(bytes, 2);\n return out;\n}\n\n/** Strict inverse of {@link padProviderSecret}: block size, bounds, zero padding, and fatal UTF-8 are all checked. */\nexport function unpadProviderSecret(padded: Uint8Array): string {\n if (\n padded.byteLength < PROVIDER_SECRET_PAD_BLOCK_BYTES\n || padded.byteLength > PROVIDER_SECRET_MAX_PADDED_BYTES\n || padded.byteLength % PROVIDER_SECRET_PAD_BLOCK_BYTES !== 0\n ) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has an invalid length');\n }\n const length = (padded[0]! << 8) | padded[1]!;\n if (length === 0 || length + 2 > padded.byteLength || padded.byteLength - (length + 2) >= PROVIDER_SECRET_PAD_BLOCK_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has an invalid length prefix');\n }\n for (let index = length + 2; index < padded.byteLength; index += 1) {\n if (padded[index] !== 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has non-zero padding');\n }\n }\n try {\n return new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(padded.subarray(2, length + 2));\n } catch {\n throw new ByokCoreError('sealed_secret_invalid', 'Provider secret is not valid UTF-8');\n }\n}\n\n// ---------------------------------------------------------------------------\n// One-shot seal / open\n// ---------------------------------------------------------------------------\n\nconst INFO_BYTES = (): Uint8Array => new TextEncoder().encode(PROVIDER_SECRET_HPKE_INFO);\n\nexport interface SealProviderProvisioningRequestInput {\n /** The header without its digest; the digest is computed here from `config`. */\n readonly header: Omit<ProviderProvisioningHeaderV1, 'configDigest'>;\n readonly config: ProviderProvisioningConfigV1;\n /** Required exactly for secret-bearing operations. */\n readonly recipient?: { readonly keyId: string; readonly publicJwk: SealingPublicJwk };\n /** Required exactly for secret-bearing operations. */\n readonly secret?: string;\n}\n\n/**\n * Build one immutable provisioning request. Secret-bearing operations are\n * sealed once, to a freshly generated ephemeral key; the key id is re-derived\n * from the public JWK so a claim whose id does not match its key is refused\n * before anything is encrypted.\n */\nexport async function sealProviderProvisioningRequest(\n input: SealProviderProvisioningRequestInput,\n): Promise<ProviderProvisioningRequestV1> {\n const configResult = safeParseTotal(ProviderProvisioningConfigV1Schema, input.config);\n if (!configResult.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config is invalid');\n }\n const config = configResult.data;\n const headerResult = safeParseTotal(ProviderProvisioningHeaderV1Schema, {\n ...input.header,\n configDigest: await providerProvisioningConfigDigest(config),\n });\n if (!headerResult.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning header is invalid');\n }\n const header = headerResult.data;\n const needsSecret = isSecretOperation(header.operation);\n if (needsSecret !== (input.secret !== undefined) || needsSecret !== (input.recipient !== undefined)) {\n throw new ByokCoreError(\n 'provider_provisioning_request_invalid',\n 'A secret and recipient are required exactly for configure and replace_secret',\n );\n }\n let sealed: SealedProviderSecretV1 | undefined;\n if (needsSecret) {\n const recipient = input.recipient!;\n const publicJwk = parseSealingPublicJwk(recipient.publicJwk);\n if ((await deriveSealingKeyId(publicJwk)) !== recipient.keyId) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing key id does not match its public key');\n }\n const { enc, ciphertext } = await hpkeSealBase({\n recipientPublicKey: sealingPublicKeyBytes(publicJwk),\n info: INFO_BYTES(),\n aad: providerSecretAadBytes(header, recipient.keyId),\n plaintext: padProviderSecret(input.secret!),\n });\n sealed = {\n suite: PROVIDER_SECRET_HPKE_SUITE,\n keyId: recipient.keyId,\n enc: encodeBase64Url(enc),\n ciphertext: encodeBase64Url(ciphertext),\n };\n }\n return parseProviderProvisioningRequest({\n version: PROVIDER_PROVISIONING_REQUEST_VERSION,\n header,\n config,\n ...(sealed === undefined ? {} : { sealed }),\n });\n}\n\nexport interface ProviderSecretRecipient {\n readonly keyId: string;\n readonly publicJwk: SealingPublicJwk;\n /** Non-extractable ECDH private key; never leaves the device. */\n readonly privateKey: WebCryptoKey;\n}\n\n/**\n * Open the sealed secret of a request, in memory. Checks, in order: request\n * schema, suite (schema literal), recipient key id, config digest, ciphertext\n * length against the padding grammar, HPKE open under the request's own AAD,\n * then strict unpadding. Time windows, replay, and placement are not checked\n * here — they are device state.\n */\nexport async function openProviderProvisioningSecret(input: {\n readonly request: ProviderProvisioningRequestV1;\n readonly recipient: ProviderSecretRecipient;\n}): Promise<string> {\n const request = parseProviderProvisioningRequest(input.request);\n const sealed = request.sealed;\n if (sealed === undefined) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning request carries no sealed secret');\n }\n const publicJwk = parseSealingPublicJwk(input.recipient.publicJwk);\n if (sealed.keyId !== input.recipient.keyId || (await deriveSealingKeyId(publicJwk)) !== input.recipient.keyId) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealed secret is not addressed to this sealing key');\n }\n await assertProviderProvisioningConfigDigest(request);\n const ciphertext = decodeBase64Url(sealed.ciphertext, 'ciphertext');\n const paddedLength = ciphertext.byteLength - HPKE_AEAD_TAG_BYTES;\n if (\n paddedLength < PROVIDER_SECRET_PAD_BLOCK_BYTES\n || paddedLength > PROVIDER_SECRET_MAX_PADDED_BYTES\n || paddedLength % PROVIDER_SECRET_PAD_BLOCK_BYTES !== 0\n ) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealed secret ciphertext has an invalid length');\n }\n const padded = await hpkeOpenBase({\n recipientPrivateKey: input.recipient.privateKey,\n recipientPublicKey: sealingPublicKeyBytes(publicJwk),\n enc: decodeBase64Url(sealed.enc, 'enc'),\n info: INFO_BYTES(),\n aad: providerSecretAadBytes(request.header, sealed.keyId),\n ciphertext,\n });\n try {\n return unpadProviderSecret(padded);\n } finally {\n padded.fill(0);\n }\n}\n","/**\n * Byte helpers shared by the sealed-payload modules (#654 E1a).\n *\n * Every function is WebCrypto-only and `node:`-free, so a browser, Workers,\n * Node and Bun run the same code. The subpath `@byok-sdk/core/sealed-payload`\n * exports the sealed-payload interface, but not these helpers. The package\n * root exports none of the sealed-payload modules.\n *\n * Caller input errors throw `sealed_secret_invalid`, the code `hpke.ts`\n * already raises for bad HPKE input. Receiver checks never throw for hostile\n * bytes; they return a typed failure.\n */\nimport { z } from 'zod';\n\nimport { ByokCoreError } from '../errors';\nimport {\n SealingPublicJwkSchema,\n decodeBase64Url,\n encodeBase64Url,\n sealingPublicKeyBytes,\n type SealingPublicJwk,\n} from '../sealed-provider-secret';\nimport { webCryptoSubtle, type WebCryptoKey } from '../webcrypto';\n\nexport type Bytes = Uint8Array<ArrayBuffer>;\n\n/**\n * The strict EC P-256 public JWK core already uses for sealing keys. Member\n * signing keys and member KEM keys use the same shape.\n */\nexport type P256PublicJwk = SealingPublicJwk;\nexport const P256PublicJwkSchema = SealingPublicJwkSchema;\n\n/** Raw P1363 (`r || s`) ECDSA P-256 signature length. */\nconst ECDSA_P256_SIGNATURE_BYTES = 64;\n\nexport function invalidInput(message: string): ByokCoreError {\n return new ByokCoreError('sealed_secret_invalid', message);\n}\n\nexport function utf8(value: string): Bytes {\n return new TextEncoder().encode(value) as Bytes;\n}\n\nexport function copy(bytes: Uint8Array): Bytes {\n return new Uint8Array(bytes) as Bytes;\n}\n\nexport function concat(...parts: readonly Uint8Array[]): Bytes {\n const out = new Uint8Array(parts.reduce((total, part) => total + part.byteLength, 0));\n let offset = 0;\n for (const part of parts) {\n out.set(part, offset);\n offset += part.byteLength;\n }\n return out as Bytes;\n}\n\nexport function hex(bytes: Uint8Array): string {\n let out = '';\n for (const byte of bytes) out += byte.toString(16).padStart(2, '0');\n return out;\n}\n\nexport { decodeBase64Url, encodeBase64Url };\n\n/** Fresh CSPRNG bytes from `globalThis.crypto`, the same source WebCrypto keys come from. */\nexport function randomBytes(length: number): Bytes {\n const source = (globalThis as { crypto?: { getRandomValues?: <T extends Uint8Array>(array: T) => T } }).crypto;\n if (source?.getRandomValues === undefined) {\n throw new ByokCoreError('webcrypto_unavailable', 'WebCrypto getRandomValues is unavailable in this runtime');\n }\n return source.getRandomValues(new Uint8Array(length)) as Bytes;\n}\n\nexport async function sha256(bytes: Uint8Array): Promise<Bytes> {\n return new Uint8Array(await webCryptoSubtle().digest('SHA-256', copy(bytes))) as Bytes;\n}\n\nexport async function hmacSha256(key: Uint8Array, data: Uint8Array): Promise<Bytes> {\n const subtle = webCryptoSubtle();\n const hmacKey = await subtle.importKey('raw', copy(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n return new Uint8Array(await subtle.sign('HMAC', hmacKey, copy(data))) as Bytes;\n}\n\n/** RFC 5869 HKDF-SHA-256 through WebCrypto's own HKDF. */\nexport async function hkdfSha256(ikm: Uint8Array, salt: Uint8Array, info: string, length: number): Promise<Bytes> {\n const subtle = webCryptoSubtle();\n const key = await subtle.importKey('raw', copy(ikm), { name: 'HKDF' }, false, ['deriveBits']);\n const bits = await subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt: copy(salt), info: utf8(info) }, key, length * 8);\n return new Uint8Array(bits) as Bytes;\n}\n\n/** A zod string that must be canonical unpadded base64url of exactly `bytes` bytes. */\nexport function base64UrlBytes(bytes: number) {\n return z.string().refine((value) => {\n try {\n return decodeBase64Url(value, 'field').byteLength === bytes;\n } catch {\n return false;\n }\n }, `must be canonical unpadded base64url of ${bytes} bytes`);\n}\n\n/**\n * ECDSA `sign` with an algorithm object, and `verify`. Core's public\n * `WebCryptoSubtle` interface declares neither, and widening it would change\n * the published API, so this module types the same runtime object locally.\n */\ninterface EcdsaSubtle {\n importKey(format: 'jwk', keyData: object, algorithm: object, extractable: boolean, usages: string[]): Promise<WebCryptoKey>;\n sign(algorithm: object, key: WebCryptoKey, data: Bytes): Promise<ArrayBuffer>;\n verify(algorithm: object, key: WebCryptoKey, signature: Bytes, data: Bytes): Promise<boolean>;\n}\n\nconst ECDSA_P256 = { name: 'ECDSA', namedCurve: 'P-256' } as const;\nconst ECDSA_SHA256 = { name: 'ECDSA', hash: 'SHA-256' } as const;\n\nfunction ecdsaSubtle(): EcdsaSubtle {\n return webCryptoSubtle() as unknown as EcdsaSubtle;\n}\n\n/** Uncompressed SEC1 bytes of a strict P-256 public JWK, checked to be a point on the curve. */\nexport async function p256PublicKeyBytes(publicJwk: P256PublicJwk): Promise<Bytes> {\n const raw = sealingPublicKeyBytes(publicJwk);\n await importEcdsaPublicKey(publicJwk);\n return raw;\n}\n\nasync function importEcdsaPublicKey(publicJwk: P256PublicJwk): Promise<WebCryptoKey> {\n const jwk = P256PublicJwkSchema.parse(publicJwk);\n try {\n return await ecdsaSubtle().importKey('jwk', { kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y }, ECDSA_P256, true, ['verify']);\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 public key is not a valid curve point', { cause });\n }\n}\n\n/**\n * ECDSA P-256 / SHA-256 signature over `data`, as base64url of the 64-byte\n * P1363 form. The signature must verify under `publicJwk`, so a private key\n * that does not pair with the caller's public key throws\n * `sealed_secret_invalid` and signs nothing under another key's id.\n */\nexport async function ecdsaSign(publicJwk: P256PublicJwk, privateKey: WebCryptoKey, data: Uint8Array): Promise<string> {\n let signature: string;\n try {\n signature = encodeBase64Url(new Uint8Array(await ecdsaSubtle().sign(ECDSA_SHA256, privateKey, copy(data))));\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_invalid', 'Signing key is not an ECDSA P-256 private key', { cause });\n }\n if (!(await ecdsaVerify(publicJwk, signature, data))) {\n throw invalidInput('Signing private key does not pair with the signing public key');\n }\n return signature;\n}\n\n/** True only for a canonical 64-byte P1363 signature that verifies under `publicJwk`. */\nexport async function ecdsaVerify(publicJwk: P256PublicJwk, signature: string, data: Uint8Array): Promise<boolean> {\n let signatureBytes: Bytes;\n try {\n signatureBytes = decodeBase64Url(signature, 'sig');\n } catch {\n return false;\n }\n if (signatureBytes.byteLength !== ECDSA_P256_SIGNATURE_BYTES) return false;\n const key = await importEcdsaPublicKey(publicJwk);\n return ecdsaSubtle().verify(ECDSA_SHA256, key, signatureBytes, copy(data));\n}\n","/**\n * Member ids and member chain entries (#654 design §7.1, §7.3).\n *\n * A member is one device or one client. It holds an ECDSA P-256 signing key\n * and a P-256 KEM key. Its id derives from the signing public key alone, so a\n * KEM rotation keeps the id, and no SDK device id or product identity enters\n * it. A device member names its SDK device id inside its chain entry instead.\n *\n * This module signs and verifies ONE entry. Walking a chain — the `prev`\n * links, removed signers, the pinned anchor — and the per-op `subject` shapes\n * belong to the chain verifier (E2), which builds on these bytes.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson, canonicalizeJsonBytes, type JsonObject } from '../attestation';\nimport { CONTENT_HASH_PATTERN } from '../blob';\nimport { safeParseTotal } from '../total-parse';\nimport type { WebCryptoKey } from '../webcrypto';\nimport {\n base64UrlBytes,\n concat,\n ecdsaSign,\n ecdsaVerify,\n encodeBase64Url,\n hex,\n invalidInput,\n p256PublicKeyBytes,\n sha256,\n utf8,\n type Bytes,\n type P256PublicJwk,\n} from './primitives';\n\n/** Domain separation for {@link deriveMemberId}. */\nexport const MEMBER_ID_DOMAIN = 'byok-member-id-v1\\n';\n\n/** `base64url(sha256(MEMBER_ID_DOMAIN || 0x04 || x || y))`: 43 characters, no padding. */\nexport const MEMBER_ID_PATTERN = /^[A-Za-z0-9_-]{43}$/u;\n\nexport const MEMBER_CHAIN_VERSION = 1;\n\n/** Prepended to the canonical entry bytes, so a chain signature never verifies as another signed object. */\nexport const MEMBER_CHAIN_DOMAIN_PREFIX = 'byok-member-chain-v1\\n';\n\nexport const MEMBER_CHAIN_OPS = ['add', 'remove', 'rotate', 'scope-policy', 'shred'] as const;\nexport type MemberChainOp = (typeof MEMBER_CHAIN_OPS)[number];\n\n/** One entry before it is signed. `seq` starts at 1; the first entry, and only it, has `prev: null`. */\nexport interface UnsignedMemberChainEntryV1 {\n readonly v: typeof MEMBER_CHAIN_VERSION;\n readonly tenantId: string;\n readonly seq: number;\n /** `sha256:<hex>` of the previous entry's signing input. */\n readonly prev: string | null;\n readonly op: MemberChainOp;\n readonly subject: JsonObject;\n /** Member id of the signer. */\n readonly signer: string;\n}\n\nexport interface MemberChainEntryV1 extends UnsignedMemberChainEntryV1 {\n /** ECDSA P-256 / SHA-256 over the signing input, base64url of the 64-byte P1363 form. */\n readonly sig: string;\n}\n\n/**\n * A plain JSON object that has exactly one canonical byte form. The output is\n * rebuilt from the canonical text, so no later step reads the caller's object\n * again: a getter or a proxy cannot change or throw after this check.\n */\nconst CanonicalJsonObjectSchema = z.unknown().transform((value, ctx): JsonObject => {\n try {\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return JSON.parse(canonicalizeJson(value as JsonObject)) as JsonObject;\n }\n } catch {\n // Not canonical JSON, or a read threw: the issue below reports it.\n }\n ctx.addIssue({ code: 'custom', message: 'must be a canonical JSON object' });\n return z.NEVER;\n});\n\nconst unsignedEntryShape = {\n v: z.literal(MEMBER_CHAIN_VERSION),\n tenantId: z.string().min(1),\n seq: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n prev: z.union([z.null(), z.string().regex(CONTENT_HASH_PATTERN)]),\n op: z.enum(MEMBER_CHAIN_OPS),\n subject: CanonicalJsonObjectSchema,\n signer: z.string().regex(MEMBER_ID_PATTERN),\n};\n\nfunction firstEntryHasNoPrev(entry: { readonly seq: number; readonly prev: string | null }, ctx: z.RefinementCtx): void {\n if ((entry.seq === 1) !== (entry.prev === null)) {\n ctx.addIssue({ code: 'custom', path: ['prev'], message: 'the first entry, and only the first, has no prev' });\n }\n}\n\nconst UnsignedMemberChainEntryV1Schema = z.strictObject(unsignedEntryShape).superRefine(firstEntryHasNoPrev);\nconst MemberChainEntryV1Schema = z\n .strictObject({ ...unsignedEntryShape, sig: base64UrlBytes(64) })\n .superRefine(firstEntryHasNoPrev);\n\n/** The member id of a signing public key. The key must be a point on P-256. */\nexport async function deriveMemberId(signingPublicJwk: P256PublicJwk): Promise<string> {\n const raw = await p256PublicKeyBytes(signingPublicJwk);\n return encodeBase64Url(await sha256(concat(utf8(MEMBER_ID_DOMAIN), raw)));\n}\n\nfunction parseUnsignedEntry(entry: UnsignedMemberChainEntryV1): UnsignedMemberChainEntryV1 {\n const parsed = safeParseTotal(UnsignedMemberChainEntryV1Schema, entry);\n if (!parsed.success) throw invalidInput('Member chain entry is invalid');\n return parsed.data;\n}\n\nfunction signingInput(entry: UnsignedMemberChainEntryV1): Bytes {\n return concat(\n utf8(MEMBER_CHAIN_DOMAIN_PREFIX),\n canonicalizeJsonBytes({\n v: entry.v,\n tenantId: entry.tenantId,\n seq: entry.seq,\n prev: entry.prev,\n op: entry.op,\n subject: entry.subject,\n signer: entry.signer,\n }),\n );\n}\n\n/** `MEMBER_CHAIN_DOMAIN_PREFIX || canonicalJson(entry without sig)`. */\nexport function memberChainSigningInput(entry: UnsignedMemberChainEntryV1): Bytes {\n return signingInput(parseUnsignedEntry(entry));\n}\n\n/** `sha256:<hex>` of the signing input. The signature is not hashed, so the hash names the entry's content. */\nexport async function memberChainEntryHash(entry: UnsignedMemberChainEntryV1): Promise<string> {\n return `sha256:${hex(await sha256(memberChainSigningInput(entry)))}`;\n}\n\n/**\n * Sign one entry. The signer's public key is required so an entry is never\n * signed under a member id that is not the signer's own. A private key that\n * does not pair with that public key throws `sealed_secret_invalid`.\n */\nexport async function signMemberChainEntry(\n entry: UnsignedMemberChainEntryV1,\n signer: { readonly publicJwk: P256PublicJwk; readonly privateKey: WebCryptoKey },\n): Promise<MemberChainEntryV1> {\n const unsigned = parseUnsignedEntry(entry);\n if ((await deriveMemberId(signer.publicJwk)) !== unsigned.signer) {\n throw invalidInput('Member chain entry signer does not match the signing key');\n }\n return { ...unsigned, sig: await ecdsaSign(signer.publicJwk, signer.privateKey, signingInput(unsigned)) };\n}\n\nexport type MemberChainEntryVerifyResult =\n | { readonly ok: true; readonly entry: MemberChainEntryV1; readonly hash: string }\n | { readonly ok: false; readonly reason: 'member_chain_entry_invalid' | 'member_chain_signature_invalid' };\n\n/**\n * Verify one received entry against the signing key the verifier already\n * pins for `entry.signer`. A malformed entry, or a key whose member id is not\n * the entry's signer, is `member_chain_entry_invalid`; a bad signature is\n * `member_chain_signature_invalid`. Nothing here throws for hostile input.\n */\nexport async function verifyMemberChainEntry(\n entry: unknown,\n signerPublicJwk: P256PublicJwk,\n): Promise<MemberChainEntryVerifyResult> {\n const parsed = safeParseTotal(MemberChainEntryV1Schema, entry);\n if (!parsed.success || (await deriveMemberId(signerPublicJwk)) !== parsed.data.signer) {\n return { ok: false, reason: 'member_chain_entry_invalid' };\n }\n const input = signingInput(parsed.data);\n if (!(await ecdsaVerify(signerPublicJwk, parsed.data.sig, input))) {\n return { ok: false, reason: 'member_chain_signature_invalid' };\n }\n return { ok: true, entry: parsed.data, hash: `sha256:${hex(await sha256(input))}` };\n}\n","/**\n * Scope keys and key packages (#654 design §7.4, §8.1, §9.1).\n *\n * A scope key `SK(scope, epoch)` is 32 random bytes one member generates.\n * Three values derive from it:\n *\n * - `keyId`: `base64url(HMAC-SHA-256(SK, \"byok-scope-key-id-v1\"))[0..22]`. It\n * commits to the key, and the Host cannot derive the key from it.\n * - the content key of one sealed content: `HKDF-SHA-256(SK, salt,\n * \"byok-sdk.sealed.v1.enc\")`, with a fresh 32-byte salt per content;\n * - the MAC key of the scope epoch: `HKDF-SHA-256(SK, empty salt,\n * \"byok-sdk.sealed.v1.mac\")`.\n *\n * A key package carries SK to one member: HPKE base mode with core's one suite\n * (`hpke.ts`), info `byok-sdk.scope-key.v1`, AAD the canonical JSON of the\n * package's identity fields. HPKE base mode does not authenticate the sender,\n * so the sender member also signs the package.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJsonBytes } from '../attestation';\nimport { ByokCoreError } from '../errors';\nimport { hpkeOpenBase, hpkeSealBase } from '../hpke';\nimport { safeParseTotal } from '../total-parse';\nimport type { WebCryptoKey } from '../webcrypto';\nimport { MEMBER_ID_PATTERN, deriveMemberId } from './member-chain';\nimport {\n base64UrlBytes,\n concat,\n decodeBase64Url,\n ecdsaSign,\n ecdsaVerify,\n encodeBase64Url,\n hkdfSha256,\n hmacSha256,\n invalidInput,\n p256PublicKeyBytes,\n randomBytes,\n utf8,\n type Bytes,\n type P256PublicJwk,\n} from './primitives';\n\nexport const SCOPE_KEY_BYTES = 32;\n\n/** 16 bytes of the key-id HMAC, as unpadded base64url. */\nexport const SCOPE_KEY_ID_LENGTH = 22;\nexport const SCOPE_KEY_ID_PATTERN = /^[A-Za-z0-9_-]{22}$/u;\n\nconst KEY_ID_MESSAGE = 'byok-scope-key-id-v1';\nconst CONTENT_KEY_INFO = 'byok-sdk.sealed.v1.enc';\nconst MAC_KEY_INFO = 'byok-sdk.sealed.v1.mac';\n\n/** Byte length of the per-content HKDF salt. */\nexport const SEALED_SALT_BYTES = 32;\n\nexport const SCOPE_KEY_PACKAGE_VERSION = 1;\nexport const SCOPE_KEY_HPKE_INFO = 'byok-sdk.scope-key.v1';\n\n/** Prepended to the canonical package bytes the sender signs. */\nexport const SCOPE_KEY_PACKAGE_DOMAIN_PREFIX = 'byok-scope-key-package-v1\\n';\n\nconst P256_POINT_BYTES = 65;\nconst AEAD_TAG_BYTES = 16;\n\nfunction assertScopeKey(scopeKey: Uint8Array): void {\n if (scopeKey.byteLength !== SCOPE_KEY_BYTES) throw invalidInput(`Scope key must be ${SCOPE_KEY_BYTES} bytes`);\n}\n\n/** A fresh scope key from the platform CSPRNG. */\nexport function generateScopeKey(): Bytes {\n return randomBytes(SCOPE_KEY_BYTES);\n}\n\nexport async function deriveScopeKeyId(scopeKey: Uint8Array): Promise<string> {\n assertScopeKey(scopeKey);\n const mac = await hmacSha256(scopeKey, utf8(KEY_ID_MESSAGE));\n return encodeBase64Url(mac.subarray(0, 16));\n}\n\n/** The AES-256-GCM key of one sealed content. Each content has its own salt, so each key encrypts once. */\nexport async function deriveSealedContentKey(scopeKey: Uint8Array, salt: Uint8Array): Promise<Bytes> {\n assertScopeKey(scopeKey);\n if (salt.byteLength !== SEALED_SALT_BYTES) throw invalidInput(`Sealed content salt must be ${SEALED_SALT_BYTES} bytes`);\n return hkdfSha256(scopeKey, salt, CONTENT_KEY_INFO, 32);\n}\n\n/**\n * The content-MAC key of one scope epoch. The design's salt is empty; HMAC\n * pads its key with zeros, so 32 zero bytes give the same output, and no\n * runtime has to accept a zero-length HKDF salt.\n */\nexport async function deriveSealedMacKey(scopeKey: Uint8Array): Promise<Bytes> {\n assertScopeKey(scopeKey);\n return hkdfSha256(scopeKey, new Uint8Array(32), MAC_KEY_INFO, 32);\n}\n\nexport interface ScopeKeyPackageV1 {\n readonly v: typeof SCOPE_KEY_PACKAGE_VERSION;\n readonly tenantId: string;\n readonly scopeId: string;\n readonly epoch: number;\n readonly keyId: string;\n /** Member id of the member that can open the package. */\n readonly recipient: string;\n /** Member id of the member that sealed and signed the package. */\n readonly sender: string;\n /** HPKE encapsulated key: base64url of a 65-byte uncompressed P-256 point. */\n readonly enc: string;\n /** HPKE ciphertext of the scope key: base64url of 48 bytes. */\n readonly ciphertext: string;\n /** Sender's ECDSA P-256 / SHA-256 signature, base64url of the 64-byte P1363 form. */\n readonly sig: string;\n}\n\nconst ScopeKeyPackageV1Schema = z.strictObject({\n v: z.literal(SCOPE_KEY_PACKAGE_VERSION),\n tenantId: z.string().min(1),\n scopeId: z.string().min(1),\n epoch: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n keyId: z.string().regex(SCOPE_KEY_ID_PATTERN),\n recipient: z.string().regex(MEMBER_ID_PATTERN),\n sender: z.string().regex(MEMBER_ID_PATTERN),\n enc: base64UrlBytes(P256_POINT_BYTES),\n ciphertext: base64UrlBytes(SCOPE_KEY_BYTES + AEAD_TAG_BYTES),\n sig: base64UrlBytes(64),\n});\n\ntype PackageIdentity = Pick<ScopeKeyPackageV1, 'v' | 'tenantId' | 'scopeId' | 'epoch' | 'keyId' | 'recipient' | 'sender'>;\n\n/** HPKE AAD: the canonical JSON of the package's identity fields. */\nfunction packageAad(identity: PackageIdentity): Uint8Array {\n return canonicalizeJsonBytes({\n v: identity.v,\n tenantId: identity.tenantId,\n scopeId: identity.scopeId,\n epoch: identity.epoch,\n keyId: identity.keyId,\n recipient: identity.recipient,\n sender: identity.sender,\n });\n}\n\n/** The bytes the sender signs: every field except `sig`. */\nfunction packageSigningInput(pkg: Omit<ScopeKeyPackageV1, 'sig'>): Bytes {\n return concat(\n utf8(SCOPE_KEY_PACKAGE_DOMAIN_PREFIX),\n canonicalizeJsonBytes({\n v: pkg.v,\n tenantId: pkg.tenantId,\n scopeId: pkg.scopeId,\n epoch: pkg.epoch,\n keyId: pkg.keyId,\n recipient: pkg.recipient,\n sender: pkg.sender,\n enc: pkg.enc,\n ciphertext: pkg.ciphertext,\n }),\n );\n}\n\nexport interface SealScopeKeyPackageInput {\n readonly scopeKey: Uint8Array;\n readonly tenantId: string;\n readonly scopeId: string;\n readonly epoch: number;\n readonly recipient: { readonly memberId: string; readonly kemPublicJwk: P256PublicJwk };\n readonly sender: { readonly signingPublicJwk: P256PublicJwk; readonly signingPrivateKey: WebCryptoKey };\n}\n\nconst PackageIdentitySchema = ScopeKeyPackageV1Schema.omit({ enc: true, ciphertext: true, sig: true });\n\n/**\n * Wrap one scope key to one member and sign the package. A signing private key\n * that does not pair with `sender.signingPublicJwk` throws\n * `sealed_secret_invalid`.\n */\nexport async function sealScopeKeyPackage(input: SealScopeKeyPackageInput): Promise<ScopeKeyPackageV1> {\n const parsed = safeParseTotal(PackageIdentitySchema, {\n v: SCOPE_KEY_PACKAGE_VERSION,\n tenantId: input.tenantId,\n scopeId: input.scopeId,\n epoch: input.epoch,\n keyId: await deriveScopeKeyId(input.scopeKey),\n recipient: input.recipient.memberId,\n sender: await deriveMemberId(input.sender.signingPublicJwk),\n });\n if (!parsed.success) throw invalidInput('Scope key package input is invalid');\n const identity = parsed.data;\n const { enc, ciphertext } = await hpkeSealBase({\n recipientPublicKey: await p256PublicKeyBytes(input.recipient.kemPublicJwk),\n info: utf8(SCOPE_KEY_HPKE_INFO),\n aad: packageAad(identity),\n plaintext: input.scopeKey,\n });\n const unsigned = { ...identity, enc: encodeBase64Url(enc), ciphertext: encodeBase64Url(ciphertext) };\n return { ...unsigned, sig: await ecdsaSign(input.sender.signingPublicJwk, input.sender.signingPrivateKey, packageSigningInput(unsigned)) };\n}\n\nexport interface OpenScopeKeyPackageInput {\n readonly package: unknown;\n /** What the caller asked the Host for. A package for anything else is refused. */\n readonly expected: { readonly tenantId: string; readonly scopeId: string; readonly epoch: number };\n readonly recipient: {\n readonly memberId: string;\n readonly kemPublicJwk: P256PublicJwk;\n readonly kemPrivateKey: WebCryptoKey;\n };\n /** The signing key the caller's verified chain holds for `package.sender`. */\n readonly senderSigningPublicJwk: P256PublicJwk;\n}\n\nexport type ScopeKeyPackageOpenResult =\n | { readonly ok: true; readonly scopeKey: Uint8Array; readonly keyId: string }\n | {\n readonly ok: false;\n readonly reason: 'key_package_invalid' | 'key_package_signature_invalid' | 'key_package_open_failed';\n };\n\n/**\n * Verify and open one key package, in this order: shape; addressed to this\n * recipient for the expected tenant, scope and epoch; sender key matches the\n * sender id; sender signature; HPKE open; key length; and `keyId` equal to\n * the opened key's own id. Nothing here throws for hostile input.\n */\nexport async function openScopeKeyPackage(input: OpenScopeKeyPackageInput): Promise<ScopeKeyPackageOpenResult> {\n const parsed = safeParseTotal(ScopeKeyPackageV1Schema, input.package);\n if (!parsed.success) return { ok: false, reason: 'key_package_invalid' };\n const pkg = parsed.data;\n if (\n pkg.recipient !== input.recipient.memberId\n || pkg.tenantId !== input.expected.tenantId\n || pkg.scopeId !== input.expected.scopeId\n || pkg.epoch !== input.expected.epoch\n || pkg.sender !== (await deriveMemberId(input.senderSigningPublicJwk))\n ) {\n return { ok: false, reason: 'key_package_invalid' };\n }\n if (!(await ecdsaVerify(input.senderSigningPublicJwk, pkg.sig, packageSigningInput(pkg)))) {\n return { ok: false, reason: 'key_package_signature_invalid' };\n }\n let scopeKey: Uint8Array;\n try {\n scopeKey = await hpkeOpenBase({\n recipientPrivateKey: input.recipient.kemPrivateKey,\n recipientPublicKey: await p256PublicKeyBytes(input.recipient.kemPublicJwk),\n enc: decodeBase64Url(pkg.enc, 'enc'),\n info: utf8(SCOPE_KEY_HPKE_INFO),\n aad: packageAad(pkg),\n ciphertext: decodeBase64Url(pkg.ciphertext, 'ciphertext'),\n });\n } catch (error) {\n if (error instanceof ByokCoreError) return { ok: false, reason: 'key_package_open_failed' };\n throw error;\n }\n // A signed package whose key does not match its own key id came from a\n // faulty or hostile member; it opens nothing.\n if (scopeKey.byteLength !== SCOPE_KEY_BYTES || (await deriveScopeKeyId(scopeKey)) !== pkg.keyId) {\n scopeKey.fill(0);\n return { ok: false, reason: 'key_package_open_failed' };\n }\n return { ok: true, scopeKey, keyId: pkg.keyId };\n}\n","/**\n * Canonical JSON of a sealed plaintext (#786): RFC 8785 with its full number\n * rule.\n *\n * Keys sort by UTF-16 code unit and strings use the ECMAScript serialization,\n * the same as `canonicalizeJson`. Numbers differ. A finite number serializes\n * as `Number.prototype.toString` (RFC 8785 §3.2.2.3), so a decimal, an\n * exponent and an integer above 2^53 are sealable. `-0` serializes as `0`.\n * NaN and the infinities have no JSON form and throw.\n *\n * Only the sealed plaintext uses this rule. The AAD, the MAC identity, member\n * chain entries and key packages keep `canonicalizeJson`, whose safe-integer\n * rule belongs to the attestation contract.\n */\nimport type { JsonValue } from '../attestation';\nimport { invalidInput } from './primitives';\n\nfunction canonicalValue(value: unknown, seen: Set<object>): string {\n if (value === null) return 'null';\n switch (typeof value) {\n case 'boolean':\n return value ? 'true' : 'false';\n case 'string':\n return JSON.stringify(value);\n case 'number':\n if (!Number.isFinite(value)) throw invalidInput('Sealed plaintext holds a number with no JSON form');\n return String(value);\n case 'object':\n break;\n default:\n throw invalidInput(`Sealed plaintext holds a ${typeof value}, which is not a JSON type`);\n }\n if (seen.has(value)) throw invalidInput('Sealed plaintext holds a circular reference');\n seen.add(value);\n try {\n if (Array.isArray(value)) return `[${Array.from(value, (entry) => canonicalValue(entry, seen)).join(',')}]`;\n const prototype: unknown = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) throw invalidInput('Sealed plaintext holds an object that is not plain');\n const record = value as Record<string, unknown>;\n const members = Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalValue(record[key], seen)}`);\n return `{${members.join(',')}}`;\n } finally {\n seen.delete(value);\n }\n}\n\n/** The canonical JSON text of a sealed plaintext value. Throws `sealed_secret_invalid` outside JSON. */\nexport function canonicalizeSealedJson(value: JsonValue): string {\n return canonicalValue(value, new Set());\n}\n","/**\n * Sealed content v1 (#654 design §8.1, §8.2, §8.6, §9.1).\n *\n * A member seals the fields one category moves out of a payload. The result is\n * a header the Host may read — version, suite, category, scope, chain head,\n * sender, salt, nonce, padded length and content MAC — and the ciphertext\n * bytes. Whether the ciphertext travels inline or by reference is the wire\n * schema's rule, not this module's.\n *\n * The plaintext is the canonical JSON of the moved fields. It is framed before\n * encryption: `u32be(contentLength) || content || zeros`, padded in 256-byte\n * steps up to 16 KiB and with Padmé above. The frame is inside the AEAD, so the\n * length and the padding are authenticated, and one content has exactly one\n * legal padded length.\n *\n * The AAD binds every identity the Host could otherwise swap: tenant, scope,\n * epoch, key id, chain head, sender, message family, direction, the write's\n * identity, target device, Agent, the task's sealing categories, padded length\n * and content MAC. Envelope `id`, `seq` and `ts` stay out, so an envelope that\n * a dead-letter replay re-encodes still opens.\n *\n * `contentMac` is a keyed MAC over category, family, identity and plaintext. The\n * Host compares two submissions of one identity by it, without a key.\n *\n * A blob field is sealed by the same frame and key rule, before its outer\n * content. Its AAD is the outer AAD without `paddedLength` and `contentMac`,\n * plus its own `paddedLength` and the JSON Pointer `fieldPath` to its BlobRef.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson, canonicalizeJsonBytes, type JsonObject } from '../attestation';\nimport { CONTENT_HASH_PATTERN } from '../blob';\nimport { ByokCoreError } from '../errors';\nimport { isCanonicalTimestamp } from '../time';\nimport { safeParseTotal } from '../total-parse';\nimport { webCryptoSubtle } from '../webcrypto';\nimport { MEMBER_ID_PATTERN } from './member-chain';\nimport {\n base64UrlBytes,\n copy,\n decodeBase64Url,\n encodeBase64Url,\n hex,\n hmacSha256,\n invalidInput,\n randomBytes,\n utf8,\n type Bytes,\n} from './primitives';\nimport {\n SCOPE_KEY_ID_PATTERN,\n SEALED_SALT_BYTES,\n deriveScopeKeyId,\n deriveSealedContentKey,\n deriveSealedMacKey,\n} from './scope-key';\nimport { canonicalizeSealedJson } from './sealed-json';\n\nexport const SEALED_CONTENT_VERSION = 1;\n\n/** The only suite v1 admits. A new suite is a new constant and a new capability, never a parser branch. */\nexport const SEALED_CONTENT_SUITE = 'byok-sealed-v1.hkdf-sha256.aes-256-gcm';\n\n/** C1–C4, in their canonical order. A task's sealing categories are listed in this order. */\nexport const SEALED_CATEGORIES = ['task-input', 'agent-message', 'task-output', 'memory-projection'] as const;\nexport type SealedCategory = (typeof SEALED_CATEGORIES)[number];\n\nexport const SEALED_DIRECTIONS = ['server-to-daemon', 'daemon-to-server'] as const;\nexport type SealedDirection = (typeof SEALED_DIRECTIONS)[number];\n\nexport const SEALED_NONCE_BYTES = 12;\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport const AEAD_TAG_BYTES = 16;\nconst FRAME_HEADER_BYTES = 4;\nconst ALIGNED_FRAME_LIMIT = 16 * 1024;\nconst FRAME_ALIGNMENT = 256;\nconst MAX_CONTENT_LENGTH = 0xffff_ffff;\n\nconst CONTENT_MAC_PREFIX = 'byok-content-mac-v1\\n';\nconst CONTENT_MAC_PATTERN = /^hmac-sha256:[0-9a-f]{64}$/u;\n\n/** Dot-separated lowercase words, e.g. `task.offer_for_agent`. It can never hold the MAC's `\\n` separator. */\nconst FAMILY_PATTERN = /^[a-z][a-z0-9_]*(?:\\.[a-z][a-z0-9_]*)+$/u;\nconst IDENTITY_FIELD_PATTERN = /^[a-z][A-Za-z0-9]*$/u;\n/** The one family that binds no device (design §6.3). */\nconst ROUTINE_TEMPLATE_FAMILY = 'routine.template';\n\n// ---------------------------------------------------------------------------\n// Padding and framing (§8.1, §8.6)\n// ---------------------------------------------------------------------------\n\n/** `floor(log2(value))` for a positive safe integer, without floating-point logarithms. */\nfunction floorLog2(value: number): number {\n let exponent = 0;\n for (let remaining = value; remaining >= 2; remaining = Math.floor(remaining / 2)) exponent += 1;\n return exponent;\n}\n\n/**\n * The one legal padded length of a frame whose unpadded length is\n * `frameLength` (`4 + contentLength`). Up to 16 KiB: the next multiple of 256.\n * Above: Padmé — `E = floor(log2 n)`, `S = floor(log2 E) + 1`, rounded up to a\n * multiple of `2^(E − S)`, which adds less than 6.25%.\n */\nexport function sealedPaddedLength(frameLength: number): number {\n if (!Number.isSafeInteger(frameLength) || frameLength < FRAME_HEADER_BYTES) {\n throw invalidInput('Sealed frame length must be a safe integer of at least 4');\n }\n if (frameLength <= ALIGNED_FRAME_LIMIT) return Math.ceil(frameLength / FRAME_ALIGNMENT) * FRAME_ALIGNMENT;\n const exponent = floorLog2(frameLength);\n const step = 2 ** (exponent - (floorLog2(exponent) + 1));\n return Math.ceil(frameLength / step) * step;\n}\n\n/**\n * Total on any number: zod runs this refinement even after the integer checks fail.\n * @internal Shared with `sealed-blob.ts`. Stripped from the published declarations.\n */\nexport function isLegalPaddedLength(paddedLength: number): boolean {\n return Number.isSafeInteger(paddedLength)\n && paddedLength >= FRAME_ALIGNMENT\n && sealedPaddedLength(paddedLength) === paddedLength;\n}\n\n/** `u32be(contentLength) || content || zeros`, as long as {@link sealedPaddedLength} says. */\nexport function encodeSealedFrame(content: Uint8Array): Bytes {\n if (content.byteLength > MAX_CONTENT_LENGTH) throw invalidInput('Sealed content exceeds the 32-bit frame length');\n const frame = new Uint8Array(sealedPaddedLength(FRAME_HEADER_BYTES + content.byteLength));\n new DataView(frame.buffer).setUint32(0, content.byteLength, false);\n frame.set(content, FRAME_HEADER_BYTES);\n return frame as Bytes;\n}\n\n/**\n * The content of a decrypted frame, or `undefined` when one of the five\n * receiver checks fails: frame length equals `paddedLength`; the content fits;\n * `paddedLength` is the padded length of exactly this content; every padding\n * byte is zero; the content is within the message type's plaintext limit.\n */\nexport function decodeSealedFrame(frame: Uint8Array, paddedLength: number, maxContentLength: number): Uint8Array | undefined {\n if (frame.byteLength !== paddedLength || paddedLength < FRAME_HEADER_BYTES) return undefined;\n const contentLength = new DataView(frame.buffer, frame.byteOffset, frame.byteLength).getUint32(0, false);\n if (contentLength > paddedLength - FRAME_HEADER_BYTES) return undefined;\n if (sealedPaddedLength(FRAME_HEADER_BYTES + contentLength) !== paddedLength) return undefined;\n if (contentLength > maxContentLength) return undefined;\n for (let index = FRAME_HEADER_BYTES + contentLength; index < paddedLength; index += 1) {\n if (frame[index] !== 0) return undefined;\n }\n return frame.subarray(FRAME_HEADER_BYTES, FRAME_HEADER_BYTES + contentLength);\n}\n\n// ---------------------------------------------------------------------------\n// Header and binding\n// ---------------------------------------------------------------------------\n\nconst NonEmptyStringSchema = z.string().min(1);\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport const PositiveIntegerSchema = z.number().int().positive().max(Number.MAX_SAFE_INTEGER);\n\n/** What the Host may read of one sealed content. The ciphertext travels next to it. */\nexport const SealedContentHeaderV1Schema = z.strictObject({\n v: z.literal(SEALED_CONTENT_VERSION),\n suite: z.literal(SEALED_CONTENT_SUITE),\n category: z.enum(SEALED_CATEGORIES),\n scope: z.strictObject({\n id: NonEmptyStringSchema,\n epoch: PositiveIntegerSchema,\n keyId: z.string().regex(SCOPE_KEY_ID_PATTERN),\n }),\n chainHead: z.strictObject({\n seq: PositiveIntegerSchema,\n hash: z.string().regex(CONTENT_HASH_PATTERN),\n }),\n sender: z.string().regex(MEMBER_ID_PATTERN),\n salt: base64UrlBytes(SEALED_SALT_BYTES),\n nonce: base64UrlBytes(SEALED_NONCE_BYTES),\n paddedLength: PositiveIntegerSchema.refine(isLegalPaddedLength, 'must be a legal padded frame length'),\n contentMac: z.string().regex(CONTENT_MAC_PATTERN),\n});\nexport type SealedContentHeaderV1 = z.infer<typeof SealedContentHeaderV1Schema>;\n\nfunction isCanonicalCategoryList(categories: readonly SealedCategory[]): boolean {\n return categories.every((category, index) =>\n index === 0 || SEALED_CATEGORIES.indexOf(categories[index - 1]!) < SEALED_CATEGORIES.indexOf(category));\n}\n\n/**\n * What the receiver knows from its own context and the payload's plaintext\n * fields. The receiver builds it; the sealed bytes never supply it.\n */\nexport interface SealedBinding {\n readonly tenantId: string;\n /** Message family, e.g. `task.offer_for_agent`, or `routine.template`. */\n readonly family: string;\n readonly direction: SealedDirection;\n /** The write's identity: `{ taskId }`, `{ messageId }`, … or `{ routineId, definitionVersion }`. */\n readonly identity: { readonly [field: string]: string | number };\n /** Target device. `null` only for the `routine.template` family, which binds no device. */\n readonly deviceId: string | null;\n readonly agentRef: { readonly agentId: string; readonly profileRevision: string } | null;\n /** The task's `sealing.categories`, unique and in {@link SEALED_CATEGORIES} order. */\n readonly categories: readonly SealedCategory[];\n /** A `routine.template`'s expiry; `null` for every other family. */\n readonly notAfter: string | null;\n}\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport const SealedBindingSchema = z\n .strictObject({\n tenantId: NonEmptyStringSchema,\n family: z.string().regex(FAMILY_PATTERN),\n direction: z.enum(SEALED_DIRECTIONS),\n identity: z\n .record(\n z.string().regex(IDENTITY_FIELD_PATTERN),\n z.union([NonEmptyStringSchema, z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER)]),\n )\n .refine((identity) => Object.keys(identity).length > 0, 'identity must name at least one field'),\n deviceId: z.union([z.null(), NonEmptyStringSchema]),\n agentRef: z.union([z.null(), z.strictObject({ agentId: NonEmptyStringSchema, profileRevision: NonEmptyStringSchema })]),\n categories: z.array(z.enum(SEALED_CATEGORIES)).min(1).refine(isCanonicalCategoryList, 'categories must be unique and in canonical order'),\n notAfter: z.union([z.null(), z.string().refine(isCanonicalTimestamp, 'must be a canonical UTC instant')]),\n })\n .superRefine((binding, ctx) => {\n const template = binding.family === ROUTINE_TEMPLATE_FAMILY;\n if ((binding.deviceId === null) !== template || (binding.notAfter === null) === template) {\n ctx.addIssue({\n code: 'custom',\n path: ['deviceId'],\n message: 'a routine template binds an expiry and no device; every other family binds a device and no expiry',\n });\n }\n });\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport type ParsedBinding = z.infer<typeof SealedBindingSchema>;\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport function parseBinding(binding: SealedBinding): ParsedBinding {\n const parsed = safeParseTotal(SealedBindingSchema, binding);\n if (!parsed.success) throw invalidInput('Sealed content binding is invalid');\n return parsed.data;\n}\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport function assertMaxContentLength(maxContentLength: number): void {\n if (!Number.isSafeInteger(maxContentLength) || maxContentLength < 0 || maxContentLength > MAX_CONTENT_LENGTH) {\n throw invalidInput('Sealed content limit must be a non-negative 32-bit integer');\n }\n}\n\n/**\n * The header fields that do not depend on the plaintext. A blob is sealed before its outer content, so it knows only these.\n * @internal Shared with `sealed-blob.ts`. Stripped from the published declarations.\n */\nexport type SealedAadContext = Pick<SealedContentHeaderV1, 'v' | 'suite' | 'category' | 'scope' | 'chainHead' | 'sender'>;\n\n/**\n * The 16 AAD members that the outer content and its blobs share (§8.2, §8.1).\n * @internal Shared with `sealed-blob.ts`. Stripped from the published declarations.\n */\nexport function bindingAad(header: SealedAadContext, binding: ParsedBinding) {\n return {\n v: header.v,\n suite: header.suite,\n category: header.category,\n tenantId: binding.tenantId,\n scopeId: header.scope.id,\n epoch: header.scope.epoch,\n keyId: header.scope.keyId,\n chainHead: { seq: header.chainHead.seq, hash: header.chainHead.hash },\n sender: header.sender,\n family: binding.family,\n direction: binding.direction,\n identity: binding.identity,\n deviceId: binding.deviceId,\n agentRef: binding.agentRef === null\n ? null\n : { agentId: binding.agentRef.agentId, profileRevision: binding.agentRef.profileRevision },\n categories: [...binding.categories],\n notAfter: binding.notAfter,\n };\n}\n\nfunction aadBytes(header: SealedContentHeaderV1, binding: ParsedBinding): Uint8Array {\n return canonicalizeJsonBytes({ ...bindingAad(header, binding), paddedLength: header.paddedLength, contentMac: header.contentMac });\n}\n\n/** The canonical AAD bytes of a header under a binding (§8.2). */\nexport function sealedContentAad(header: SealedContentHeaderV1, binding: SealedBinding): Uint8Array {\n const parsed = safeParseTotal(SealedContentHeaderV1Schema, header);\n if (!parsed.success) throw invalidInput('Sealed content header is invalid');\n return aadBytes(parsed.data, parseBinding(binding));\n}\n\n// ---------------------------------------------------------------------------\n// Plaintext and content MAC (§9.1)\n// ---------------------------------------------------------------------------\n\nfunction isNonEmptyPlainObject(value: unknown): boolean {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return false;\n const prototype: unknown = Object.getPrototypeOf(value);\n return (prototype === Object.prototype || prototype === null) && Object.keys(value).length > 0;\n}\n\n/** The plaintext text, with the RFC 8785 number rule (#786). The AAD and the MAC identity keep `canonicalizeJson`. */\nfunction canonicalPlaintext(plaintext: JsonObject): string {\n try {\n if (isNonEmptyPlainObject(plaintext)) return canonicalizeSealedJson(plaintext);\n } catch (cause) {\n // A throwing getter or proxy trap reaches here too, from either check; the caller sees one typed error.\n throw new ByokCoreError('sealed_secret_invalid', 'Sealed plaintext is not canonical JSON', { cause });\n }\n throw invalidInput('Sealed plaintext must be a non-empty plain JSON object');\n}\n\n/** Decoded content, only when it is the canonical JSON text of a non-empty plain object. */\nfunction parseCanonicalPlaintext(content: Uint8Array): { readonly value: JsonObject; readonly text: string } | undefined {\n let text: string;\n let value: unknown;\n try {\n text = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(content);\n value = JSON.parse(text);\n if (!isNonEmptyPlainObject(value) || canonicalizeSealedJson(value as JsonObject) !== text) return undefined;\n } catch {\n return undefined;\n }\n return { value: value as JsonObject, text };\n}\n\n/**\n * `\"hmac-sha256:\" + hex(HMAC-SHA-256(K_mac, \"byok-content-mac-v1\\n\" || category\n * || \"\\n\" || family || \"\\n\" || canonicalJson(identity) || \"\\n\" || plaintext))`.\n * No field before the plaintext can hold a raw `\\n`, so the input splits one way.\n */\nasync function contentMacOf(scopeKey: Uint8Array, category: SealedCategory, binding: ParsedBinding, plaintextText: string): Promise<string> {\n const macKey = await deriveSealedMacKey(scopeKey);\n try {\n const input = `${CONTENT_MAC_PREFIX}${category}\\n${binding.family}\\n${canonicalizeJson(binding.identity)}\\n${plaintextText}`;\n return `hmac-sha256:${hex(await hmacSha256(macKey, utf8(input)))}`;\n } finally {\n macKey.fill(0);\n }\n}\n\n/** The content MAC of one plaintext under one scope key (§9.1). */\nexport async function sealedContentMac(input: {\n readonly scopeKey: Uint8Array;\n readonly category: SealedCategory;\n readonly binding: SealedBinding;\n readonly plaintext: JsonObject;\n}): Promise<string> {\n return contentMacOf(input.scopeKey, input.category, parseBinding(input.binding), canonicalPlaintext(input.plaintext));\n}\n\n// ---------------------------------------------------------------------------\n// Seal and open\n// ---------------------------------------------------------------------------\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport async function aesGcm(\n mode: 'encrypt' | 'decrypt',\n key: Uint8Array,\n nonce: Uint8Array,\n aad: Uint8Array,\n data: Uint8Array,\n): Promise<Bytes> {\n const subtle = webCryptoSubtle();\n const cryptoKey = await subtle.importKey('raw', copy(key), { name: 'AES-GCM' }, false, [mode]);\n const params = { name: 'AES-GCM', iv: copy(nonce), additionalData: copy(aad), tagLength: 128 };\n const out = mode === 'encrypt'\n ? await subtle.encrypt(params, cryptoKey, copy(data))\n : await subtle.decrypt(params, cryptoKey, copy(data));\n return new Uint8Array(out) as Bytes;\n}\n\nexport interface SealContentInput {\n readonly scopeKey: Uint8Array;\n readonly scope: { readonly id: string; readonly epoch: number };\n /** The member chain head the sender verified before sealing. */\n readonly chainHead: { readonly seq: number; readonly hash: string };\n /** The sender's member id. */\n readonly sender: string;\n readonly category: SealedCategory;\n readonly binding: SealedBinding;\n /** The fields this category moves out of the payload. */\n readonly plaintext: JsonObject;\n /** The plaintext limit of this message type, in UTF-8 bytes of canonical JSON. */\n readonly maxContentLength: number;\n}\n\n/**\n * The salt and nonce of one seal, for test vectors only.\n * @internal Stripped from the published declarations.\n */\nexport interface SealedContentRandomness {\n readonly salt: Uint8Array;\n readonly nonce: Uint8Array;\n}\n\nexport interface SealedContent {\n readonly header: SealedContentHeaderV1;\n /** AES-256-GCM output: the padded frame followed by the 16-byte tag. */\n readonly ciphertext: Uint8Array;\n}\n\n/** Seal one category of a payload once. A retry must resend these bytes, never seal again (§9.2). */\nexport async function sealContent(input: SealContentInput): Promise<SealedContent> {\n return sealContentWithRandomness(input, { salt: randomBytes(SEALED_SALT_BYTES), nonce: randomBytes(SEALED_NONCE_BYTES) });\n}\n\n/**\n * {@link sealContent} with a caller-chosen salt and nonce, for test vectors\n * only. Neither the root nor the subpath exports it: a reused nonce under one\n * content key breaks AES-GCM.\n * @internal Stripped from the published declarations.\n */\nexport async function sealContentWithRandomness(input: SealContentInput, randomness: SealedContentRandomness): Promise<SealedContent> {\n const binding = parseBinding(input.binding);\n assertMaxContentLength(input.maxContentLength);\n if (!binding.categories.includes(input.category)) {\n throw invalidInput('Sealed content category is not one of the task sealing categories');\n }\n const plaintextText = canonicalPlaintext(input.plaintext);\n const content = utf8(plaintextText);\n if (content.byteLength > input.maxContentLength) throw invalidInput('Sealed content exceeds its plaintext limit');\n const frame = encodeSealedFrame(content);\n const { salt, nonce } = randomness;\n const parsed = safeParseTotal(SealedContentHeaderV1Schema, {\n v: SEALED_CONTENT_VERSION,\n suite: SEALED_CONTENT_SUITE,\n category: input.category,\n scope: { id: input.scope.id, epoch: input.scope.epoch, keyId: await deriveScopeKeyId(input.scopeKey) },\n chainHead: { seq: input.chainHead.seq, hash: input.chainHead.hash },\n sender: input.sender,\n salt: encodeBase64Url(salt),\n nonce: encodeBase64Url(nonce),\n paddedLength: frame.byteLength,\n contentMac: await contentMacOf(input.scopeKey, input.category, binding, plaintextText),\n });\n if (!parsed.success) throw invalidInput('Sealed content header input is invalid');\n const contentKey = await deriveSealedContentKey(input.scopeKey, salt);\n try {\n const ciphertext = await aesGcm('encrypt', contentKey, nonce, aadBytes(parsed.data, binding), frame);\n return { header: parsed.data, ciphertext };\n } finally {\n contentKey.fill(0);\n frame.fill(0);\n content.fill(0);\n }\n}\n\n/** The receiver failure codes of design §8.3. */\nexport type SealedContentOpenFailure =\n | 'sealed_key_unavailable'\n | 'sealed_open_failed'\n | 'sealed_content_mac_mismatch'\n | 'sealing_policy_mismatch';\n\n/**\n * An opened content, with the header that the AEAD authenticated. The caller\n * reads `chainHead` and `sender` from it for the sender-view check (§7.3).\n */\nexport type SealedContentOpenResult =\n | { readonly ok: true; readonly plaintext: JsonObject; readonly header: SealedContentHeaderV1 }\n | { readonly ok: false; readonly reason: SealedContentOpenFailure };\n\n/** The task's frozen `sealing` scope (§6.2). Its `categories` are {@link SealedBinding.categories}. */\nexport interface SealedScopePolicy {\n readonly scopeId: string;\n /** The lowest epoch the task accepts: the epoch of the offer's C1 content. */\n readonly epoch: number;\n}\n\nconst SealedScopePolicySchema = z.strictObject({ scopeId: NonEmptyStringSchema, epoch: PositiveIntegerSchema });\n\nexport interface OpenSealedContentInput {\n /** The header as received. It is untrusted. */\n readonly header: unknown;\n readonly ciphertext: Uint8Array;\n /** The scope key the receiver holds for `header.scope`. */\n readonly scopeKey: Uint8Array;\n /** Partly written by the Host (`sealing.categories`, `notAfter`), so it is untrusted too. */\n readonly binding: SealedBinding;\n /** From the task's `sealing`, which the Host writes. Untrusted. */\n readonly sealing: SealedScopePolicy;\n readonly maxContentLength: number;\n}\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport function failure(reason: SealedContentOpenFailure): { readonly ok: false; readonly reason: SealedContentOpenFailure } {\n return { ok: false, reason };\n}\n\n/**\n * Open one sealed content, fail closed. In order: a binding and a task scope\n * that parse (`sealing_policy_mismatch`); header shape (`sealed_open_failed`);\n * the category within the task's categories, and the header scope equal to\n * the task's scope at its epoch or later (both `sealing_policy_mismatch`); key\n * id of the held scope key (`sealed_key_unavailable`); ciphertext length; AEAD\n * under the rebuilt AAD; the five frame checks; canonical JSON of a plain\n * object (all `sealed_open_failed`); and the content MAC\n * (`sealed_content_mac_mismatch`).\n * There is no plaintext fallback, and nothing here throws for hostile input.\n */\nexport async function openSealedContent(input: OpenSealedContentInput): Promise<SealedContentOpenResult> {\n assertMaxContentLength(input.maxContentLength);\n const parsedBinding = safeParseTotal(SealedBindingSchema, input.binding);\n const parsedSealing = safeParseTotal(SealedScopePolicySchema, input.sealing);\n if (!parsedBinding.success || !parsedSealing.success) return failure('sealing_policy_mismatch');\n const binding = parsedBinding.data;\n const sealing = parsedSealing.data;\n const parsed = safeParseTotal(SealedContentHeaderV1Schema, input.header);\n if (!parsed.success) return failure('sealed_open_failed');\n const header = parsed.data;\n if (\n !binding.categories.includes(header.category)\n || header.scope.id !== sealing.scopeId\n || header.scope.epoch < sealing.epoch\n ) {\n return failure('sealing_policy_mismatch');\n }\n if ((await deriveScopeKeyId(input.scopeKey)) !== header.scope.keyId) return failure('sealed_key_unavailable');\n if (input.ciphertext.byteLength !== header.paddedLength + AEAD_TAG_BYTES) return failure('sealed_open_failed');\n\n const contentKey = await deriveSealedContentKey(input.scopeKey, decodeBase64Url(header.salt, 'salt'));\n let frame: Bytes;\n try {\n frame = await aesGcm('decrypt', contentKey, decodeBase64Url(header.nonce, 'nonce'), aadBytes(header, binding), input.ciphertext);\n } catch {\n return failure('sealed_open_failed');\n } finally {\n contentKey.fill(0);\n }\n try {\n const content = decodeSealedFrame(frame, header.paddedLength, input.maxContentLength);\n const plaintext = content === undefined ? undefined : parseCanonicalPlaintext(content);\n if (plaintext === undefined) return failure('sealed_open_failed');\n if ((await contentMacOf(input.scopeKey, header.category, binding, plaintext.text)) !== header.contentMac) {\n return failure('sealed_content_mac_mismatch');\n }\n return { ok: true, plaintext: plaintext.value, header };\n } finally {\n frame.fill(0);\n }\n}\n","/**\n * The member key bundle (#654 design §7.1, §7.2, E2b; owner decision 10a).\n *\n * A bundle is the public half of one member: its id, its ECDSA P-256 signing\n * key, its P-256 KEM key, the KEM epoch, and `kemSig`. A device member also\n * names its SDK device id. A client member does not.\n *\n * `kemSig` is the member's own signature over its KEM key and epoch. The\n * fingerprint covers only the signing key, so a KEM rotation keeps the member\n * id and the fingerprint. The self-signature binds the KEM key to the member:\n * a Host that swaps the KEM key breaks the signature.\n *\n * An `add` chain entry carries the bundle. The pairing MACs bind it. In a\n * later slice, the device registers it with device proof.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJsonBytes } from '../attestation';\nimport type { WebCryptoKey } from '../webcrypto';\nimport { safeParseTotal } from '../total-parse';\nimport { deriveMemberId, MEMBER_ID_PATTERN } from './member-chain';\nimport {\n P256PublicJwkSchema,\n base64UrlBytes,\n concat,\n ecdsaSign,\n ecdsaVerify,\n invalidInput,\n p256PublicKeyBytes,\n utf8,\n type Bytes,\n type P256PublicJwk,\n} from './primitives';\n\nexport const MEMBER_KEY_BUNDLE_VERSION = 1;\n\n/** Prepended to the canonical KEM statement, so `kemSig` never verifies as another signed object. */\nexport const MEMBER_KEM_DOMAIN_PREFIX = 'byok-member-kem-v1\\n';\n\nexport interface MemberKeyBundleV1 {\n readonly v: typeof MEMBER_KEY_BUNDLE_VERSION;\n readonly memberId: string;\n readonly signingPublicJwk: P256PublicJwk;\n readonly kemPublicJwk: P256PublicJwk;\n readonly kemEpoch: number;\n /** ECDSA P-256 / SHA-256 by the signing key over the KEM statement, base64url of the 64-byte P1363 form. */\n readonly kemSig: string;\n /** The SDK device id of a device member. A client member has none. */\n readonly deviceId?: string;\n}\n\nexport const KemEpochSchema = z.number().int().positive().max(Number.MAX_SAFE_INTEGER);\nexport const KemSigSchema = base64UrlBytes(64);\n\n/** @internal The strict bundle shape. Shared with `pairing-verification.ts`. */\nexport const MemberKeyBundleV1Schema = z.strictObject({\n v: z.literal(MEMBER_KEY_BUNDLE_VERSION),\n memberId: z.string().regex(MEMBER_ID_PATTERN),\n signingPublicJwk: P256PublicJwkSchema,\n kemPublicJwk: P256PublicJwkSchema,\n kemEpoch: KemEpochSchema,\n kemSig: KemSigSchema,\n deviceId: z.string().min(1).optional(),\n});\n\n/** The caller data of `createMemberKeyBundle`, read once. The private key is kept as given; `ecdsaSign` checks it. */\nconst CreateInputSchema = z.object({\n signingPublicJwk: P256PublicJwkSchema,\n signingPrivateKey: z.custom<WebCryptoKey>(),\n kemPublicJwk: P256PublicJwkSchema,\n kemEpoch: KemEpochSchema,\n deviceId: z.string().min(1).optional(),\n});\n\n/** The fields `verifyMemberKem` reads, as plain values. Other fields, such as the rest of a bundle, are ignored. */\nconst KemSignerSchema = z.object({ memberId: z.string().regex(MEMBER_ID_PATTERN), signingPublicJwk: P256PublicJwkSchema });\nconst KemStatementSchema = z.object({ kemPublicJwk: P256PublicJwkSchema, kemEpoch: KemEpochSchema, kemSig: KemSigSchema });\n\n/** `MEMBER_KEM_DOMAIN_PREFIX || canonicalJson({ memberId, kemPublicKey: { x, y }, kemEpoch })`. */\nexport function memberKemSigningInput(memberId: string, kemPublicJwk: P256PublicJwk, kemEpoch: number): Bytes {\n return concat(\n utf8(MEMBER_KEM_DOMAIN_PREFIX),\n canonicalizeJsonBytes({ memberId, kemPublicKey: { x: kemPublicJwk.x, y: kemPublicJwk.y }, kemEpoch }),\n );\n}\n\nexport interface CreateMemberKeyBundleInput {\n readonly signingPublicJwk: P256PublicJwk;\n readonly signingPrivateKey: WebCryptoKey;\n readonly kemPublicJwk: P256PublicJwk;\n readonly kemEpoch: number;\n readonly deviceId?: string;\n}\n\n/** Build a bundle: derive the member id and sign the KEM statement. Bad input throws `sealed_secret_invalid`. */\nexport async function createMemberKeyBundle(input: CreateMemberKeyBundleInput): Promise<MemberKeyBundleV1> {\n const parsed = safeParseTotal(CreateInputSchema, input);\n if (!parsed.success) throw invalidInput('Member key bundle input is invalid');\n const { signingPublicJwk, signingPrivateKey, kemPublicJwk, kemEpoch, deviceId } = parsed.data;\n const memberId = await deriveMemberId(signingPublicJwk);\n if (!(await isValidMemberKemKey(kemPublicJwk, signingPublicJwk))) throw invalidInput('Member KEM key is invalid');\n const kemSig = await ecdsaSign(signingPublicJwk, signingPrivateKey, memberKemSigningInput(memberId, kemPublicJwk, kemEpoch));\n return {\n v: MEMBER_KEY_BUNDLE_VERSION,\n memberId,\n signingPublicJwk,\n kemPublicJwk,\n kemEpoch,\n kemSig,\n ...(deviceId === undefined ? {} : { deviceId }),\n };\n}\n\n/** Both keys are points on P-256, and the KEM key is not the signing key. */\nexport async function isValidMemberKemKey(kemPublicJwk: P256PublicJwk, signingPublicJwk: P256PublicJwk): Promise<boolean> {\n if (kemPublicJwk.x === signingPublicJwk.x && kemPublicJwk.y === signingPublicJwk.y) return false;\n try {\n await p256PublicKeyBytes(kemPublicJwk);\n return true;\n } catch {\n return false;\n }\n}\n\n/** The KEM key is valid for the member, and `kemSig` is the member's signature over it. Never throws. */\nexport async function verifyMemberKem(\n member: { readonly memberId: string; readonly signingPublicJwk: P256PublicJwk },\n kem: { readonly kemPublicJwk: P256PublicJwk; readonly kemEpoch: number; readonly kemSig: string },\n): Promise<boolean> {\n const signer = safeParseTotal(KemSignerSchema, member);\n const statement = safeParseTotal(KemStatementSchema, kem);\n if (!signer.success || !statement.success) return false;\n const { memberId, signingPublicJwk } = signer.data;\n const { kemPublicJwk, kemEpoch, kemSig } = statement.data;\n if (!(await isValidMemberKemKey(kemPublicJwk, signingPublicJwk))) return false;\n try {\n return await ecdsaVerify(signingPublicJwk, kemSig, memberKemSigningInput(memberId, kemPublicJwk, kemEpoch));\n } catch {\n return false;\n }\n}\n\n/**\n * Parse a received bundle. It is valid when its shape is strict, `memberId`\n * is the id of `signingPublicJwk` (which also checks that key is on the\n * curve), the KEM key is a different point on the curve, and `kemSig`\n * verifies. Returns `undefined` for anything else; it never throws for\n * hostile input.\n */\nexport async function parseMemberKeyBundle(value: unknown): Promise<MemberKeyBundleV1 | undefined> {\n const parsed = safeParseTotal(MemberKeyBundleV1Schema, value);\n if (!parsed.success) return undefined;\n const bundle = parsed.data;\n try {\n if ((await deriveMemberId(bundle.signingPublicJwk)) !== bundle.memberId) return undefined;\n } catch {\n return undefined;\n }\n if (!(await verifyMemberKem(bundle, bundle))) return undefined;\n return bundle;\n}\n","/**\n * Member fingerprints and the two-way approval code (#654 design §7.2, §7.8;\n * owner decision 10a).\n *\n * Fingerprint of one member:\n *\n * 1. `digest = SHA-256(MEMBER_FINGERPRINT_DOMAIN || canonicalJson({ v: 1, tenantId, signingKey: { x, y } }))`.\n * 2. Take the first 25 bytes as 5 groups of 5 bytes.\n * 3. Read each group as a big-endian integer, take it modulo 100000, and pad\n * it to 5 decimal digits.\n *\n * The result is 25 digits in 5 groups, about 83 bits. The KEM key is not in\n * the fingerprint; the bundle's `kemSig` binds it. So a KEM rotation keeps the\n * fingerprint.\n *\n * Approval code: approval is two-way. Both screens show the same 50 digits:\n * the two members' fingerprints, ordered by member id, in 10 groups of 5. The\n * approver signs `add` only after both sides confirm the same code, and the\n * new member pins the approver's signing key only after it confirms (11b).\n * A device's local approval command shows the same code.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJsonBytes } from '../attestation';\nimport { safeParseTotal } from '../total-parse';\nimport { deriveMemberId } from './member-chain';\nimport { P256PublicJwkSchema, concat, invalidInput, sha256, utf8, type P256PublicJwk } from './primitives';\n\nexport const MEMBER_FINGERPRINT_DOMAIN = 'byok-member-fingerprint-v1\\n';\n\nconst FINGERPRINT_GROUPS = 5;\nconst GROUP_BYTES = 5;\nconst GROUP_MODULUS = 100000n;\n\n/** The caller data, read once into plain values. */\nconst FingerprintInputSchema = z.object({ tenantId: z.string().min(1), signingPublicJwk: P256PublicJwkSchema });\n\nexport interface MemberFingerprintInput {\n readonly tenantId: string;\n readonly signingPublicJwk: P256PublicJwk;\n}\n\n/** The 25-digit fingerprint of one member, as 5 groups of 5 digits joined by single spaces. */\nexport async function memberFingerprint(input: MemberFingerprintInput): Promise<string> {\n return (await fingerprintGroups(input)).groups.join(' ');\n}\n\n/**\n * The 50-digit two-way approval code of two members of one tenant: their\n * fingerprints ordered by member id, as 10 groups of 5 digits joined by\n * single spaces. The order of the arguments does not matter.\n */\nexport async function memberApprovalCode(\n tenantId: string,\n first: P256PublicJwk,\n second: P256PublicJwk,\n): Promise<string> {\n const members = await Promise.all([first, second].map((signingPublicJwk) => fingerprintGroups({ tenantId, signingPublicJwk })));\n if (members[0]!.memberId === members[1]!.memberId) throw invalidInput('An approval code needs two different members');\n members.sort((a, b) => (a.memberId < b.memberId ? -1 : 1));\n return members.flatMap((member) => member.groups).join(' ');\n}\n\n/** The member id and the 5 fingerprint groups of one member. */\nasync function fingerprintGroups(input: MemberFingerprintInput): Promise<{ memberId: string; groups: string[] }> {\n const parsed = safeParseTotal(FingerprintInputSchema, input);\n if (!parsed.success) throw invalidInput('Member fingerprint needs a tenant id and a P-256 signing key');\n const { tenantId, signingPublicJwk } = parsed.data;\n // deriveMemberId checks that the key is a point on P-256.\n const memberId = await deriveMemberId(signingPublicJwk);\n const digest = await sha256(\n concat(\n utf8(MEMBER_FINGERPRINT_DOMAIN),\n canonicalizeJsonBytes({ v: 1, tenantId, signingKey: { x: signingPublicJwk.x, y: signingPublicJwk.y } }),\n ),\n );\n const groups: string[] = [];\n for (let group = 0; group < FINGERPRINT_GROUPS; group += 1) {\n let value = 0n;\n for (const byte of digest.subarray(group * GROUP_BYTES, (group + 1) * GROUP_BYTES)) value = (value << 8n) | BigInt(byte);\n groups.push((value % GROUP_MODULUS).toString().padStart(5, '0'));\n }\n return { memberId, groups };\n}\n","/**\n * The pairing verification secret `pv` (#654 design §7.2, D2).\n *\n * The client generates `pv` when it shows a pairing code, and shows\n * `<pairing code>.<pv>`. The user gives that string to the device. The device\n * sends only the pairing code to the Host and keeps `pv`. The Host never sees\n * `pv`, so it cannot replace a member public key during pairing.\n *\n * Text form: RFC 4648 base32 of the 16 bytes, without padding. That is 26\n * characters. The encoder writes upper case. The decoder also accepts lower\n * case, because a person may type the string. The two unused low bits of the\n * last character must be zero, so one value has one upper-case text form.\n *\n * The parser splits on the LAST `.`, because base32 has no `.` and a pairing\n * code may contain one. It requires `pv`: the daemon decides from its own\n * configuration that a pairing needs `pv`, and never infers it from the text.\n *\n * The two pairing MACs (§7.2 steps 3 and 4) key HMAC-SHA-256 with `pv`. The\n * design writes their inputs with `||`. Here each input is a domain tag and\n * the canonical JSON of named fields, so field boundaries are unambiguous and\n * a device MAC never verifies as a client MAC.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJsonBytes } from '../attestation';\nimport { CONTENT_HASH_PATTERN } from '../blob';\nimport { safeParseTotal } from '../total-parse';\nimport { webCryptoSubtle, type WebCryptoKey } from '../webcrypto';\nimport type { MemberKeyBundleV1 } from './member-bundle';\nimport { MemberKeyBundleV1Schema } from './member-bundle';\nimport {\n base64UrlBytes,\n concat,\n copy,\n decodeBase64Url,\n encodeBase64Url,\n hmacSha256,\n invalidInput,\n randomBytes,\n utf8,\n type Bytes,\n} from './primitives';\n\nexport const PAIRING_VERIFICATION_SECRET_BYTES = 16;\nexport const PAIRING_VERIFICATION_TEXT_LENGTH = 26;\n\nconst BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n// Checked on the raw text, before upper-casing: Unicode case mapping turns\n// some non-ASCII characters into ASCII letters (`ſ` to `S`, `ff` to `FF`).\nconst PV_TEXT_PATTERN = /^[A-Za-z2-7]{26}$/u;\n\n/** 128 fresh CSPRNG bits. */\nexport function generatePairingVerificationSecret(): Bytes {\n return randomBytes(PAIRING_VERIFICATION_SECRET_BYTES);\n}\n\nexport function encodePairingVerificationSecret(pv: Uint8Array): string {\n if (pv.byteLength !== PAIRING_VERIFICATION_SECRET_BYTES) {\n throw invalidInput(`Pairing verification secret must be ${PAIRING_VERIFICATION_SECRET_BYTES} bytes`);\n }\n let out = '';\n let buffer = 0;\n let bits = 0;\n for (const byte of pv) {\n buffer = (buffer << 8) | byte;\n bits += 8;\n while (bits >= 5) {\n bits -= 5;\n out += BASE32_ALPHABET[(buffer >>> bits) & 31];\n }\n buffer &= (1 << bits) - 1;\n }\n return out + BASE32_ALPHABET[(buffer << (5 - bits)) & 31];\n}\n\nexport function decodePairingVerificationSecret(text: string): Bytes {\n if (!PV_TEXT_PATTERN.test(text)) {\n throw invalidInput(`Pairing verification secret must be ${PAIRING_VERIFICATION_TEXT_LENGTH} base32 characters`);\n }\n const upper = text.toUpperCase();\n const out = new Uint8Array(PAIRING_VERIFICATION_SECRET_BYTES);\n let buffer = 0;\n let bits = 0;\n let index = 0;\n for (const char of upper) {\n buffer = (buffer << 5) | BASE32_ALPHABET.indexOf(char);\n bits += 5;\n if (bits >= 8) {\n bits -= 8;\n out[index++] = (buffer >>> bits) & 0xff;\n }\n buffer &= (1 << bits) - 1;\n }\n if (buffer !== 0) throw invalidInput('Pairing verification secret has nonzero trailing bits');\n return out as Bytes;\n}\n\n/** `<pairingCode>.<pv>`, the string the client shows and the user gives to the device. */\nexport function formatPairingInput(pairingCode: string, pv: Uint8Array): string {\n if (pairingCode.length === 0) throw invalidInput('Pairing code must not be empty');\n return `${pairingCode}.${encodePairingVerificationSecret(pv)}`;\n}\n\nexport interface PairingInput {\n /** The only part the device sends to the Host. */\n readonly pairingCode: string;\n /** Kept on the device; never sent to the Host. */\n readonly pv: Bytes;\n}\n\n/** Split `<pairingCode>.<pv>` on the last `.`. Both parts are required. */\nexport function parsePairingInput(text: string): PairingInput {\n const dot = text.lastIndexOf('.');\n if (dot <= 0) throw invalidInput('Pairing input must be <pairing code>.<verification secret>');\n return { pairingCode: text.slice(0, dot), pv: decodePairingVerificationSecret(text.slice(dot + 1)) };\n}\n\n/** Domain tag of the MAC the device sends: step 3, `HMAC(pv, device bundle, tenantId, deviceId)`. */\nexport const DEVICE_PAIRING_MAC_DOMAIN = 'byok-pairing-device-mac-v1\\n';\n/** Domain tag of the MAC the client sends: step 4, `HMAC(pv, client bundle, chain head)`. */\nexport const CLIENT_PAIRING_MAC_DOMAIN = 'byok-pairing-client-mac-v1\\n';\n\n/** A pairing MAC on the wire: base64url of the 32-byte HMAC-SHA-256 tag. */\nconst PairingMacSchema = base64UrlBytes(32);\n\nexport interface DevicePairingMacInput {\n readonly tenantId: string;\n readonly deviceId: string;\n /** The device's own bundle. Its `deviceId` must equal `deviceId`. */\n readonly member: MemberKeyBundleV1;\n}\n\nexport interface ClientPairingMacInput {\n /** The client's own bundle. A client bundle has no `deviceId`. */\n readonly member: MemberKeyBundleV1;\n /** The chain head after the client signed `add(device)`. */\n readonly chainHead: { readonly seq: number; readonly hash: string };\n}\n\nconst ChainHeadSchema = z.strictObject({\n seq: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n hash: z.string().regex(CONTENT_HASH_PATTERN),\n});\n\n/** The caller data of the two MAC inputs, read once into plain values. */\nconst DeviceMacInputSchema = z.object({ tenantId: z.string().min(1), deviceId: z.string().min(1), member: MemberKeyBundleV1Schema });\nconst ClientMacInputSchema = z.object({ member: MemberKeyBundleV1Schema, chainHead: ChainHeadSchema });\n\nfunction devicePairingMacInput(input: DevicePairingMacInput): Bytes {\n const parsed = safeParseTotal(DeviceMacInputSchema, input);\n if (!parsed.success || parsed.data.member.deviceId !== parsed.data.deviceId) {\n throw invalidInput('Device pairing MAC input must name the device member\\'s own device id');\n }\n const { tenantId, deviceId, member } = parsed.data;\n return concat(utf8(DEVICE_PAIRING_MAC_DOMAIN), canonicalizeJsonBytes({ tenantId, deviceId, member }));\n}\n\nfunction clientPairingMacInput(input: ClientPairingMacInput): Bytes {\n const parsed = safeParseTotal(ClientMacInputSchema, input);\n if (!parsed.success || parsed.data.member.deviceId !== undefined) {\n throw invalidInput('Client pairing MAC input must hold a client member and a chain head');\n }\n const { member, chainHead } = parsed.data;\n return concat(utf8(CLIENT_PAIRING_MAC_DOMAIN), canonicalizeJsonBytes({ member, chainHead: { seq: chainHead.seq, hash: chainHead.hash } }));\n}\n\nfunction checkPv(pv: Uint8Array): void {\n if (pv.byteLength !== PAIRING_VERIFICATION_SECRET_BYTES) {\n throw invalidInput(`Pairing verification secret must be ${PAIRING_VERIFICATION_SECRET_BYTES} bytes`);\n }\n}\n\nexport async function computeDevicePairingMac(pv: Uint8Array, input: DevicePairingMacInput): Promise<string> {\n checkPv(pv);\n return encodeBase64Url(await hmacSha256(pv, devicePairingMacInput(input)));\n}\n\nexport async function computeClientPairingMac(pv: Uint8Array, input: ClientPairingMacInput): Promise<string> {\n checkPv(pv);\n return encodeBase64Url(await hmacSha256(pv, clientPairingMacInput(input)));\n}\n\n/**\n * Check a received device MAC. Parse the received bundle with\n * `parseMemberKeyBundle` first. Returns `false` for a wrong or malformed MAC,\n * or a bundle that does not name `deviceId`. Only a malformed `pv` throws.\n */\nexport async function verifyDevicePairingMac(pv: Uint8Array, input: DevicePairingMacInput, mac: unknown): Promise<boolean> {\n checkPv(pv);\n return hmacVerify(pv, () => devicePairingMacInput(input), mac);\n}\n\n/**\n * Check a received client MAC. Parse the received bundle with\n * `parseMemberKeyBundle` first. Returns `false` for a wrong or malformed MAC,\n * a device bundle, or a malformed chain head. Only a malformed `pv` throws.\n */\nexport async function verifyClientPairingMac(pv: Uint8Array, input: ClientPairingMacInput, mac: unknown): Promise<boolean> {\n checkPv(pv);\n return hmacVerify(pv, () => clientPairingMacInput(input), mac);\n}\n\n/**\n * WebCrypto HMAC verify compares in constant time. Core's public\n * `WebCryptoSubtle` interface does not declare `verify`, so this module types\n * the same runtime object locally, as `primitives.ts` does for ECDSA.\n */\ninterface HmacVerifySubtle {\n importKey(format: 'raw', keyData: Bytes, algorithm: object, extractable: boolean, usages: string[]): Promise<WebCryptoKey>;\n verify(algorithm: string, key: WebCryptoKey, signature: Bytes, data: Bytes): Promise<boolean>;\n}\n\nasync function hmacVerify(key: Uint8Array, buildData: () => Bytes, mac: unknown): Promise<boolean> {\n const parsed = safeParseTotal(PairingMacSchema, mac);\n if (!parsed.success) return false;\n let data: Bytes;\n try {\n data = buildData();\n } catch {\n return false;\n }\n const subtle = webCryptoSubtle() as unknown as HmacVerifySubtle;\n const hmacKey = await subtle.importKey('raw', copy(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);\n return subtle.verify('HMAC', hmacKey, decodeBase64Url(parsed.data, 'mac'), data);\n}\n","/**\n * Member chain walk (#654 design §7.3, §7.4, §7.5, §11.2, E2b; owner\n * decisions 11a and 11b).\n *\n * `applyMemberChainEntries` checks entries forward from a state and returns\n * the new state. Each entry must:\n *\n * - be the next entry: same tenant, `seq = head.seq + 1`, `prev = head.hash`\n * (from the empty state: `seq = 1`, `prev = null`);\n * - be signed by a current member (an `add`ed member that is not removed), or\n * be the genesis entry (11a, below);\n * - have the subject shape and the rule of its op (below);\n * - for `scope-policy` and `shred`, after the subject rules, be signed by a\n * member of the scope (below).\n *\n * One bad entry rejects the whole batch. The caller's state does not change.\n *\n * Genesis (11a): from the empty state only, the first entry is a self-signed\n * `add`: `subject.member.memberId === signer`, verified with the subject's\n * own signing key. Self-signing proves only that the member holds the key.\n * Trust comes from the anchor (11b, `verifyMemberChainFromAnchor`). An active\n * Host can write a false first entry first; that only denies service.\n *\n * Precondition (D10, #655 D-I2): one tenant is one user. v1 has no per-user\n * permissions, so any current member may sign `add` and `remove`. A Host\n * that maps two users to one tenant breaks this: one user's client could\n * change the other user's devices.\n *\n * Scope signers (owner batch §50f A): a `scope-policy` or `shred` of an\n * existing scope must be signed by a member in that scope's current policy.\n * The first `scope-policy` of a new scope must be signed by a member in its\n * own member list. Another signer fails with `member_chain_signer_invalid`.\n * So a member cannot change or shred, on the chain, a scope it is not in.\n * The rule does not cover two cases (design §7.9):\n *\n * - The Host deletes a scope's key packages on any well-shaped `shred` and\n * does not check the signature (owner batch §50g). That deletion still\n * depends on the other members being honest.\n * - The first member that creates a scope id takes it. E2d confirms a\n * scope's current policy before it seals to the scope.\n *\n * When every member of a scope's current policy has been removed, nobody can\n * update or shred that scope again (design §7.9).\n *\n * Op rules:\n *\n * - `add` `{ member }`: a valid bundle (`parseMemberKeyBundle`) of a member\n * that is not current and was never removed. A removed member id is final;\n * a re-paired device is a new member (§7.5).\n * - `remove` `{ memberId }`: a current member. A member may remove itself,\n * but the last member may not: the member set never becomes empty after\n * genesis (owner decision 14A).\n * - `rotate` `{ memberId, kemPublicJwk, kemEpoch, kemSig }`: signed by that\n * member itself; `kemEpoch` is its current KEM epoch + 1; the KEM key is\n * not the current one; `kemSig` is the member's signature over the new KEM\n * key (10a).\n * - `scope-policy` `{ scopeId, categories, members }`: categories in the\n * order of `SEALED_CATEGORIES`, no repeats; members sorted, no repeats,\n * each a current member (§7.4); the scope is not shredded.\n * - `shred` `{ scopeId }`: a scope with a policy that is not shredded. After\n * it, no `scope-policy` for that scope is valid (§11.2).\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson, type JsonObject } from '../attestation';\nimport { safeParseTotal } from '../total-parse';\nimport {\n KemEpochSchema,\n KemSigSchema,\n parseMemberKeyBundle,\n verifyMemberKem,\n type MemberKeyBundleV1,\n} from './member-bundle';\nimport { MEMBER_ID_PATTERN, deriveMemberId, verifyMemberChainEntry, type MemberChainEntryV1 } from './member-chain';\nimport { P256PublicJwkSchema, type P256PublicJwk } from './primitives';\nimport { SEALED_CATEGORIES, type SealedCategory } from './sealed-content';\n\nexport interface MemberChainScope {\n readonly categories: readonly SealedCategory[];\n /** Member ids from the latest `scope-policy` entry, sorted. Some may be removed since. */\n readonly members: readonly string[];\n /** `seq` of that entry. */\n readonly policySeq: number;\n}\n\nexport interface MemberChainHead {\n readonly seq: number;\n readonly hash: string;\n}\n\nexport interface MemberChainState {\n readonly tenantId: string;\n /** `null` before the genesis entry. */\n readonly head: MemberChainHead | null;\n /** Current members by member id, with their current KEM key. */\n readonly members: ReadonlyMap<string, MemberKeyBundleV1>;\n readonly removed: ReadonlySet<string>;\n readonly scopes: ReadonlyMap<string, MemberChainScope>;\n readonly shredded: ReadonlySet<string>;\n}\n\nexport type MemberChainWalkFailure =\n | 'member_chain_entry_invalid'\n | 'member_chain_link_invalid'\n | 'member_chain_signer_invalid'\n | 'member_chain_signature_invalid'\n | 'member_chain_subject_invalid';\n\nexport type MemberChainWalkResult =\n | { readonly ok: true; readonly state: MemberChainState }\n | { readonly ok: false; readonly reason: MemberChainWalkFailure; readonly index: number };\n\nconst MemberIdSchema = z.string().regex(MEMBER_ID_PATTERN);\nconst ScopeIdSchema = z.string().min(1);\n\nconst AddSubjectSchema = z.strictObject({ member: z.unknown() });\nconst RemoveSubjectSchema = z.strictObject({ memberId: MemberIdSchema });\nconst RotateSubjectSchema = z.strictObject({\n memberId: MemberIdSchema,\n kemPublicJwk: P256PublicJwkSchema,\n kemEpoch: KemEpochSchema,\n kemSig: KemSigSchema,\n});\nconst ScopePolicySubjectSchema = z.strictObject({\n scopeId: ScopeIdSchema,\n categories: z.array(z.enum(SEALED_CATEGORIES)).min(1),\n members: z.array(MemberIdSchema).min(1),\n});\nconst ShredSubjectSchema = z.strictObject({ scopeId: ScopeIdSchema });\nconst SignerSchema = z.object({ signer: MemberIdSchema });\nconst GenesisSchema = z.object({ op: z.literal('add'), subject: AddSubjectSchema });\nconst HeadSchema = z.object({ seq: z.number(), hash: z.string() });\nconst EntriesSchema = z.array(z.unknown());\n/** The caller data of the anchor check, read once. `self` and `authenticatedHead` are parsed after this read. */\nconst AnchorInputSchema = z.object({\n tenantId: z.string(),\n entries: EntriesSchema,\n self: z.unknown(),\n approverSigningPublicJwk: P256PublicJwkSchema,\n authenticatedHead: z.unknown().optional(),\n});\n\n/** The state before the genesis entry of `tenantId`'s chain. */\nexport function emptyMemberChainState(tenantId: string): MemberChainState {\n return { tenantId, head: null, members: new Map(), removed: new Set(), scopes: new Map(), shredded: new Set() };\n}\n\n/** The latest policy's members that are still current: the members that get key packages for the scope. */\nexport function memberChainScopeRecipients(state: MemberChainState, scopeId: string): readonly MemberKeyBundleV1[] {\n const scope = state.scopes.get(scopeId);\n if (scope === undefined) return [];\n return scope.members.flatMap((memberId) => {\n const member = state.members.get(memberId);\n return member === undefined ? [] : [member];\n });\n}\n\n/** Apply `entries` in order after `state`. Never throws for hostile entries. */\nexport async function applyMemberChainEntries(state: MemberChainState, entries: readonly unknown[]): Promise<MemberChainWalkResult> {\n const list = safeParseTotal(EntriesSchema, entries);\n if (!list.success) return { ok: false, reason: 'member_chain_entry_invalid', index: 0 };\n const result = await walk(state, list.data, () => false);\n return result.ok ? { ok: true, state: result.state } : result;\n}\n\n/** The genesis signer: the subject of a self-signed `add`, only from the empty state (11a). */\nasync function genesisSigner(state: WalkState, raw: unknown, signer: string): Promise<MemberKeyBundleV1 | undefined> {\n if (state.head !== null || state.members.size > 0) return undefined;\n const entry = safeParseTotal(GenesisSchema, raw);\n const member = entry.success ? await parseMemberKeyBundle(entry.data.subject.member) : undefined;\n return member !== undefined && member.memberId === signer ? member : undefined;\n}\n\ninterface WalkState {\n tenantId: string;\n head: MemberChainHead | null;\n members: Map<string, MemberKeyBundleV1>;\n removed: Set<string>;\n scopes: Map<string, MemberChainScope>;\n shredded: Set<string>;\n}\n\n/** The first entry that `mark` accepted: its index in the batch, its `seq` and its entry hash. */\ninterface MarkedEntry {\n readonly index: number;\n readonly seq: number;\n readonly hash: string;\n}\n\ntype WalkOutcome =\n | { readonly ok: true; readonly state: MemberChainState; readonly marked: MarkedEntry | undefined }\n | { readonly ok: false; readonly reason: MemberChainWalkFailure; readonly index: number };\n\n/**\n * The walk. `mark` sees each verified entry before it applies, with the\n * signer's key; the outcome reports the first index it marked.\n */\nasync function walk(\n state: MemberChainState,\n entries: readonly unknown[],\n mark: (entry: MemberChainEntryV1, signerKey: P256PublicJwk) => boolean,\n): Promise<WalkOutcome> {\n const next: WalkState = {\n tenantId: state.tenantId,\n head: state.head,\n members: new Map(state.members),\n removed: new Set(state.removed),\n scopes: new Map(state.scopes),\n shredded: new Set(state.shredded),\n };\n let marked: MarkedEntry | undefined;\n for (const [index, raw] of entries.entries()) {\n const signer = safeParseTotal(SignerSchema, raw);\n if (!signer.success) return { ok: false, reason: 'member_chain_entry_invalid', index };\n const signerBundle = next.members.get(signer.data.signer) ?? (await genesisSigner(next, raw, signer.data.signer));\n if (signerBundle === undefined) return { ok: false, reason: 'member_chain_signer_invalid', index };\n const verified = await verifyMemberChainEntry(raw, signerBundle.signingPublicJwk);\n if (!verified.ok) return { ok: false, reason: verified.reason, index };\n const entry = verified.entry;\n const expected = next.head === null ? { seq: 1, prev: null } : { seq: next.head.seq + 1, prev: next.head.hash };\n if (entry.tenantId !== next.tenantId || entry.seq !== expected.seq || entry.prev !== expected.prev) {\n return { ok: false, reason: 'member_chain_link_invalid', index };\n }\n if (marked === undefined && mark(entry, signerBundle.signingPublicJwk)) marked = { index, seq: entry.seq, hash: verified.hash };\n const applied = await applySubject(next, entry);\n if (applied !== true) return { ok: false, reason: applied === false ? 'member_chain_subject_invalid' : applied, index };\n next.head = { seq: entry.seq, hash: verified.hash };\n }\n return { ok: true, state: next, marked };\n}\n\n/**\n * `true` when the entry applied, `false` when its subject breaks the op rule.\n * A scope change with a valid subject from a member outside the scope (§50f\n * A) is `member_chain_signer_invalid`; the subject rules are checked first.\n */\nasync function applySubject(state: WalkState, entry: MemberChainEntryV1): Promise<boolean | 'member_chain_signer_invalid'> {\n switch (entry.op) {\n case 'add': {\n const subject = safeParseTotal(AddSubjectSchema, entry.subject);\n const member = subject.success ? await parseMemberKeyBundle(subject.data.member) : undefined;\n if (member === undefined || state.members.has(member.memberId) || state.removed.has(member.memberId)) return false;\n state.members.set(member.memberId, member);\n return true;\n }\n case 'remove': {\n const subject = safeParseTotal(RemoveSubjectSchema, entry.subject);\n if (!subject.success || !state.members.has(subject.data.memberId) || state.members.size === 1) return false;\n state.members.delete(subject.data.memberId);\n state.removed.add(subject.data.memberId);\n return true;\n }\n case 'rotate': {\n const subject = safeParseTotal(RotateSubjectSchema, entry.subject);\n if (!subject.success || subject.data.memberId !== entry.signer) return false;\n const member = state.members.get(subject.data.memberId);\n if (member === undefined || subject.data.kemEpoch !== member.kemEpoch + 1) return false;\n // A rotation to the current key keeps the old private key valid for new packages.\n const { kemPublicJwk } = subject.data;\n if (kemPublicJwk.x === member.kemPublicJwk.x && kemPublicJwk.y === member.kemPublicJwk.y) return false;\n if (!(await verifyMemberKem(member, subject.data))) return false;\n state.members.set(member.memberId, {\n ...member,\n kemPublicJwk: subject.data.kemPublicJwk,\n kemEpoch: subject.data.kemEpoch,\n kemSig: subject.data.kemSig,\n });\n return true;\n }\n case 'scope-policy': {\n const subject = safeParseTotal(ScopePolicySubjectSchema, entry.subject);\n if (!subject.success || state.shredded.has(subject.data.scopeId)) return false;\n const { categories, members } = subject.data;\n if (!strictlyIncreasing(categories.map((category) => SEALED_CATEGORIES.indexOf(category)))) return false;\n if (!strictlyIncreasing(members) || !members.every((memberId) => state.members.has(memberId))) return false;\n // An existing scope's current policy names who may change it; a new scope's own list names who may create it.\n if (!(state.scopes.get(subject.data.scopeId)?.members ?? members).includes(entry.signer)) return 'member_chain_signer_invalid';\n state.scopes.set(subject.data.scopeId, { categories, members, policySeq: entry.seq });\n return true;\n }\n case 'shred': {\n const subject = safeParseTotal(ShredSubjectSchema, entry.subject);\n if (!subject.success) return false;\n const scope = state.scopes.get(subject.data.scopeId);\n if (scope === undefined) return false;\n if (!scope.members.includes(entry.signer)) return 'member_chain_signer_invalid';\n state.scopes.delete(subject.data.scopeId);\n state.shredded.add(subject.data.scopeId);\n return true;\n }\n }\n}\n\n/** Sorted with no repeats. Member ids are ASCII, so `<` is code-point order. */\nfunction strictlyIncreasing<T extends number | string>(values: readonly T[]): boolean {\n return values.every((value, index) => index === 0 || values[index - 1]! < value);\n}\n\nexport type MemberChainAnchorFailure = MemberChainWalkFailure | 'member_chain_anchor_missing' | 'member_chain_head_mismatch';\n\nexport type MemberChainAnchorResult =\n | {\n readonly ok: true;\n readonly state: MemberChainState;\n /** `seq` of the anchor entry: the `add` of this member, signed by the pinned approver. */\n readonly anchorSeq: number;\n }\n | { readonly ok: false; readonly reason: MemberChainAnchorFailure; readonly index?: number };\n\nexport interface VerifyMemberChainFromAnchorInput {\n readonly tenantId: string;\n /** The whole chain, from the genesis entry (seq 1). */\n readonly entries: readonly unknown[];\n /** This member's own bundle, exactly as it was approved. */\n readonly self: MemberKeyBundleV1;\n /** The approver's signing key, pinned out of band: by the pv MAC or by the two-way fingerprint (10a). */\n readonly approverSigningPublicJwk: P256PublicJwk;\n /**\n * A chain head the approver authenticated out of band, for example the\n * head in the client pairing MAC. When given, it must be the anchor entry.\n */\n readonly authenticatedHead?: MemberChainHead;\n}\n\n/**\n * Verify a chain as a member that joined after the genesis entry (11b):\n *\n * 1. The member pins the approver's signing key K out of band.\n * 2. Entry E is an `add` whose `member` is byte-identical to `self` (KEM key\n * included) and whose signer is `memberId(K)`, verified with K.\n * 3. The walk from genesis reaches E, so E is on the chain path.\n * 4. The entries after E verify forward by signature.\n *\n * The first E counts; `self` can be added only once. Never throws for\n * hostile entries.\n */\nexport async function verifyMemberChainFromAnchor(input: VerifyMemberChainFromAnchorInput): Promise<MemberChainAnchorResult> {\n const parsed = safeParseTotal(AnchorInputSchema, input);\n if (!parsed.success) return { ok: false, reason: 'member_chain_anchor_missing' };\n const { tenantId, entries, self, approverSigningPublicJwk: approver, authenticatedHead } = parsed.data;\n let approverId: string;\n let selfText: string;\n try {\n approverId = await deriveMemberId(approver);\n selfText = canonicalizeJson(self as JsonObject);\n } catch {\n return { ok: false, reason: 'member_chain_anchor_missing' };\n }\n // The walk verified each entry with `signerKey`, so an entry that matches here verifies with the approver's key.\n const isAnchor = (entry: MemberChainEntryV1, signerKey: P256PublicJwk): boolean => {\n if (entry.op !== 'add' || entry.signer !== approverId || signerKey.x !== approver.x || signerKey.y !== approver.y) return false;\n try {\n return canonicalizeJson((entry.subject as { member?: unknown }).member as JsonObject) === selfText;\n } catch {\n return false;\n }\n };\n const outcome = await walk(emptyMemberChainState(tenantId), entries, isAnchor);\n if (!outcome.ok) return outcome;\n const anchor = outcome.marked;\n if (anchor === undefined) return { ok: false, reason: 'member_chain_anchor_missing' };\n if (authenticatedHead !== undefined) {\n const head = safeParseTotal(HeadSchema, authenticatedHead);\n if (!head.success || head.data.seq !== anchor.seq || head.data.hash !== anchor.hash) {\n return { ok: false, reason: 'member_chain_head_mismatch', index: anchor.index };\n }\n }\n return { ok: true, state: outcome.state, anchorSeq: anchor.seq };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/blob.ts","../../src/attestation.ts","../../src/time.ts","../../src/total-parse.ts","../../src/webcrypto.ts","../../src/hpke.ts","../../src/sealed-provider-secret.ts","../../src/sealed-payload/primitives.ts","../../src/sealed-payload/member-chain.ts","../../src/sealed-payload/member-bundle.ts","../../src/sealed-payload/scope-key.ts","../../src/sealed-payload/sealed-json.ts","../../src/sealed-payload/sealed-content.ts","../../src/sealed-payload/member-key-record.ts","../../src/sealed-payload/member-fingerprint.ts","../../src/sealed-payload/pairing-verification.ts","../../src/sealed-payload/member-chain-walk.ts"],"names":["ByokCoreError","parts","z","utf8","copy","concat","hmacSha256","AEAD_TAG_BYTES","KemEpochSchema","ECDSA_P256","ECDSA_SHA256"],"mappings":"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","file":"index.js","sourcesContent":["import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Content addressing and the object manifest (§12.7.4, §12.7.8).\n *\n * This module is **metadata only**. No byte transport, no presigning, no\n * hashing: R2/S3 URL signing and digest computation are composition concerns\n * that need platform crypto, and core stays Node-free. What core owns is the\n * shape everyone must agree on — the hash format, the manifest state machine,\n * and reference counting — so that Postgres, D1, and the in-memory reference\n * cannot disagree about when an object is safe to delete.\n *\n * Object keys are tenant-scoped by construction ({@link tenantObjectKey}).\n * A global `sha256/<hex>` key space would turn object existence into a\n * cross-tenant oracle, which is why §12.7.4 forbids it even though it would\n * deduplicate better.\n */\nimport { ByokCoreError } from './errors';\nimport type { TenantId } from './tenant';\n\n/** `sha256:<64 lowercase hex>`. The only content-address form core accepts. */\nexport const CONTENT_HASH_PATTERN = /^sha256:[0-9a-f]{64}$/;\n\n/** A validated content address. Branded so an unvalidated digest cannot stand in for one. */\nexport type ContentHash = string & { readonly __byokContentHash: unique symbol };\n\n/**\n * The single mint point for {@link ContentHash}.\n *\n * Fail-closed on uppercase hex: accepting both cases would make the same bytes\n * addressable under two keys, which breaks per-tenant deduplication and the\n * \"count each hash once\" billing rule (§12.7.6).\n *\n * @throws {ByokCoreError} code `content_hash_invalid`.\n */\nexport function contentHash(value: string): ContentHash {\n if (!CONTENT_HASH_PATTERN.test(value)) {\n throw new ByokCoreError(\n 'content_hash_invalid',\n `Content hash must match ${CONTENT_HASH_PATTERN.source}, received ${JSON.stringify(value)}.`,\n );\n }\n return value as ContentHash;\n}\n\n/** Non-throwing form of {@link contentHash}. */\nexport function isContentHash(value: unknown): value is ContentHash {\n return typeof value === 'string' && CONTENT_HASH_PATTERN.test(value);\n}\n\n/**\n * What a deployment-level key namespace may look like: slash-joined segments of\n * lowercase alphanumerics, `.`, `_`, and `-`, each starting with an\n * alphanumeric. No leading or trailing slash, and therefore no empty segment.\n *\n * Narrow on purpose, and narrower than S3 keys allow. A prefix is spliced into\n * every key this SDK ever writes, so the only prefixes worth accepting are the\n * ones that reach the object store spelled exactly as configured: anything\n * requiring percent-encoding would give the deployment's objects two names, and\n * anything with an empty segment would make `a//b` and `a/b` the same key at\n * rest but different strings in config. Case is folded out for the same reason\n * {@link contentHash} refuses uppercase hex — one address, one spelling.\n */\nexport const OBJECT_KEY_PREFIX_PATTERN = /^[a-z0-9][a-z0-9._-]*(\\/[a-z0-9][a-z0-9._-]*)*$/;\n\n/** A validated deployment key namespace. Branded, so only the mint point below can produce one. */\nexport type ObjectKeyPrefix = string & { readonly __byokObjectKeyPrefix: unique symbol };\n\n/**\n * The single mint point for {@link ObjectKeyPrefix}.\n *\n * There is no \"empty means no prefix\" spelling here: a composition that has no\n * prefix omits the option, and one that passes `''` has misconfigured something\n * (an unset environment variable is the usual way). Accepting it silently would\n * make the two indistinguishable at exactly the moment the difference decides\n * where a deployment's objects live.\n *\n * @throws {ByokCoreError} code `object_key_prefix_invalid`.\n */\nexport function objectKeyPrefix(value: string): ObjectKeyPrefix {\n if (!OBJECT_KEY_PREFIX_PATTERN.test(value)) {\n throw new ByokCoreError(\n 'object_key_prefix_invalid',\n `Object key prefix must match ${OBJECT_KEY_PREFIX_PATTERN.source}, received ${JSON.stringify(value)}.`,\n );\n }\n return value as ObjectKeyPrefix;\n}\n\n/**\n * Tenant-scoped object key, e.g.\n * `tenants/<tenantId>/objects/sha256/<hex>` (§12.7.4).\n *\n * `prefix` namespaces the whole layout — `<prefix>/tenants/...` — so one bucket\n * can hold several deployments without either of them owning the bucket root.\n * Omitting it produces the unprefixed key verbatim, which is what makes the\n * option safe to add: every object already at rest was written without one.\n *\n * The prefix is an IMMUTABLE property of a deployment. It is spliced in here\n * and nowhere else, and nothing reads a key back under a second layout: change\n * a live deployment's prefix and its existing objects become unaddressable.\n * See `R2BlobStoreOptions.keyPrefix` in `@byok-sdk/cloud-dataplane` for the full\n * operational contract.\n */\nexport function tenantObjectKey(\n tenant: TenantId,\n hash: ContentHash,\n prefix?: ObjectKeyPrefix,\n): string {\n const hex = hash.slice('sha256:'.length);\n const key = `tenants/${tenant as string}/objects/sha256/${hex}`;\n return prefix === undefined ? key : `${prefix as string}/${key}`;\n}\n\n/**\n * Object manifest lifecycle (§12.7.8).\n *\n * `pending` exists because Postgres and R2 have no shared transaction: the row\n * is written before the bytes land, and only `committed` rows may be referenced\n * by a truth record. `delete_pending` is the tombstone the GC worker drives, so\n * a failed R2 delete is retryable instead of leaving usage silently wrong.\n */\nexport const OBJECT_STATES = ['pending', 'committed', 'delete_pending', 'deleted'] as const;\nexport type ObjectState = (typeof OBJECT_STATES)[number];\n\n/** Legal manifest transitions. Anything else raises `object_state_invalid`. */\nexport const OBJECT_STATE_TRANSITIONS: Readonly<Record<ObjectState, readonly ObjectState[]>> = {\n pending: ['committed', 'delete_pending'],\n committed: ['delete_pending'],\n delete_pending: ['deleted', 'committed'],\n deleted: [],\n};\n\nexport function isLegalObjectTransition(from: ObjectState, to: ObjectState): boolean {\n return OBJECT_STATE_TRANSITIONS[from].includes(to);\n}\n\n/** One row of `object_manifest` (§12.7.6). */\nexport interface ObjectManifestEntry {\n readonly tenantId: TenantId;\n readonly hash: ContentHash;\n /** Declared at reservation time, re-verified at commit against the store's `HEAD`. */\n readonly byteSize: bigint;\n readonly contentType: string;\n readonly state: ObjectState;\n /** Number of live {@link ObjectReference} rows. `0` makes the object GC-eligible after grace. */\n readonly refCount: number;\n readonly createdAt: string;\n readonly updatedAt: string;\n /** Set when the row entered `delete_pending`; the grace window is measured from here. */\n readonly deletePendingAt?: string;\n}\n\n/** What references an object. `refKind`/`refId` are opaque to core. */\nexport interface ObjectReference {\n readonly tenantId: TenantId;\n readonly hash: ContentHash;\n readonly refKind: string;\n readonly refId: string;\n readonly createdAt: string;\n}\n\nexport interface ObjectManifestInput {\n readonly hash: ContentHash;\n readonly byteSize: bigint;\n readonly contentType: string;\n}\n\n/**\n * Finalize input. `byteSize`/`contentType` are what the composition actually\n * observed on the object store, not what the client declared — the whole point\n * of the check is that the two can differ (§12.7.7 step 4).\n */\nexport interface ObjectCommitInput {\n readonly hash: ContentHash;\n readonly observedByteSize: bigint;\n readonly observedContentType: string;\n}\n\nexport interface ObjectReferenceInput {\n readonly hash: ContentHash;\n readonly refKind: string;\n readonly refId: string;\n}\n\nexport interface ObjectListQuery {\n readonly state?: ObjectState;\n /**\n * Only rows whose `deletePendingAt` is at or before this instant.\n *\n * Must be a **canonical ISO-8601 UTC instant** (`YYYY-MM-DDTHH:mm:ss.sssZ`);\n * anything else is rejected with `timestamp_not_canonical`, because the\n * in-memory composition compares it as a string and a SQL composition\n * compares it as a `timestamptz` — see `time.ts`.\n */\n readonly deletePendingBefore?: string;\n readonly limit?: number;\n}\n\n/**\n * Object manifest port. Tenant-first, async, metadata only.\n *\n * Raises: `object_not_found`, `object_state_invalid`,\n * `storage_integrity_mismatch` (commit observed size/type disagreeing with the\n * declared manifest row), `timestamp_not_canonical` (a `list` query whose\n * `deletePendingBefore` is not a canonical ISO-8601 UTC instant).\n */\nexport interface ObjectStore {\n collectExpired(tenant: TenantId, input: ObjectCollectExpiredInput): Promise<CollectExpiredResult>;\n /** Creates or returns the `pending` row for `hash`. Idempotent per (tenant, hash). */\n putManifest(tenant: TenantId, input: ObjectManifestInput): Promise<ObjectManifestEntry>;\n /** `pending` → `committed` after verifying observed size/type. */\n commit(tenant: TenantId, input: ObjectCommitInput): Promise<ObjectManifestEntry>;\n get(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry | undefined>;\n list(tenant: TenantId, query: ObjectListQuery): Promise<readonly ObjectManifestEntry[]>;\n /** Idempotent per (tenant, hash, refKind, refId) — re-adding does not double-count. */\n addReference(tenant: TenantId, input: ObjectReferenceInput): Promise<ObjectManifestEntry>;\n removeReference(tenant: TenantId, input: ObjectReferenceInput): Promise<ObjectManifestEntry>;\n /** Tombstone step 1: only legal at `refCount === 0`. */\n markDeletePending(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;\n /** Tombstone step 3: the object store delete succeeded. */\n markDeleted(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;\n}\n\nexport interface ObjectCollectExpiredInput extends CollectExpiredInput { readonly orphanBefore: string; }\n","/**\n * Device proof envelope and canonical signing bytes (§12.6.3, sprint §S6.2).\n *\n * Three things live here and nothing else:\n *\n * 1. **The protected-claims schema.** Every field a signature must cover so the\n * proof binds a *specific request*: tenant, product, device, key + epoch,\n * request id, operation, resource, the request line (method+path or a stable\n * operation id), and the body's hash *and* size. Signing only the body is\n * forbidden — it would let a valid proof be replayed against a different\n * operation or resource.\n * 2. **A dependency-free deterministic canonicalizer.** RFC 8785 (JCS) in the\n * narrow subset the envelope allows. Node and Workers must produce\n * byte-identical output, so the accepted value space is deliberately small:\n * strings, booleans, null, safe integers, plain objects, arrays. Floats,\n * non-safe integers, `NaN`, `Infinity`, `undefined`, `bigint`, dates and\n * class instances throw instead of being coerced — a signature over a value\n * whose serialization is implementation-defined is not a signature.\n * 3. **The verify port.** An interface, never an implementation: core is\n * Node-free and Workers-safe, and `node:crypto` and WebCrypto disagree about\n * key handling. The composition brings its own verifier.\n *\n * Claims are **untrusted input**. `tenantId` here is a plain string, not a\n * branded `TenantId`, because a device asserting a tenant proves nothing: the\n * claim is a lookup key used to load the device row, and the row is the\n * authority (§12.6.2 layer 5). Branding happens after that lookup, not here.\n */\nimport { z } from 'zod';\nimport { CONTENT_HASH_PATTERN } from './blob';\nimport { ByokCoreError } from './errors';\n\n/** Envelope schema id, self-consistent with the domain prefix below. */\nexport const DEVICE_PROOF_SCHEMA_ID = 'byok-device-proof-v1';\n\n/**\n * Domain separation prefix (§12.6.3). Prepended to the canonical claim bytes\n * before signing so a device-proof signature can never be replayed as a nonce\n * signature (`byok-nonce-v1\\n`) or a record attestation.\n */\nexport const DEVICE_PROOF_DOMAIN_PREFIX = 'byok-device-proof-v1\\n';\n\nexport const DEVICE_PROOF_VERSION = 1;\n\n/** Signature algorithms this envelope version admits. */\nexport const DEVICE_PROOF_ALGORITHMS = ['ed25519'] as const;\nexport type DeviceProofAlgorithm = (typeof DEVICE_PROOF_ALGORITHMS)[number];\n\n/**\n * HTTP header carrying the base64url device-proof envelope on a truth-route\n * request (§12.6.3). Both the daemon that mints the proof and the host that\n * decodes it must name the exact same header, so it is a single wire constant\n * here rather than a string re-spelled on each side.\n */\nexport const DEVICE_PROOF_HEADER = 'x-byok-device-proof';\n\nconst BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;\nconst HTTP_METHOD_PATTERN = /^[A-Z]+$/;\n\n// ---------------------------------------------------------------------------\n// Canonicalization (RFC 8785 subset)\n// ---------------------------------------------------------------------------\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | readonly JsonValue[] | { readonly [key: string]: JsonValue };\nexport type JsonObject = { readonly [key: string]: JsonValue };\n\nfunction canonicalizationFailure(path: string, reason: string): ByokCoreError {\n return new ByokCoreError(\n 'proof_canonicalization_failed',\n `Cannot canonicalize ${path}: ${reason}`,\n );\n}\n\nfunction isPlainObject(value: object): boolean {\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction canonicalizeValue(value: unknown, path: string, seen: Set<object>): string {\n if (value === null) return 'null';\n\n switch (typeof value) {\n case 'boolean':\n return value ? 'true' : 'false';\n case 'string':\n // JSON.stringify implements exactly the ECMAScript string serialization\n // RFC 8785 mandates, including well-formed escaping of lone surrogates.\n return JSON.stringify(value);\n case 'number': {\n if (!Number.isSafeInteger(value)) {\n throw canonicalizationFailure(\n path,\n `only safe integers are canonicalizable, received ${String(value)}`,\n );\n }\n // Normalizes -0 to 0; RFC 8785 has no signed zero.\n return String(value === 0 ? 0 : value);\n }\n case 'undefined':\n throw canonicalizationFailure(path, 'undefined has no canonical form');\n case 'bigint':\n throw canonicalizationFailure(path, 'bigint is not a JSON type');\n case 'function':\n case 'symbol':\n throw canonicalizationFailure(path, `${typeof value} is not a JSON type`);\n case 'object':\n break;\n default:\n throw canonicalizationFailure(path, `unsupported type ${typeof value}`);\n }\n\n const objectValue = value as object;\n if (seen.has(objectValue)) {\n throw canonicalizationFailure(path, 'circular reference');\n }\n seen.add(objectValue);\n try {\n if (Array.isArray(objectValue)) {\n const parts = objectValue.map((entry, index) =>\n canonicalizeValue(entry, `${path}[${index}]`, seen),\n );\n return `[${parts.join(',')}]`;\n }\n if (!isPlainObject(objectValue)) {\n throw canonicalizationFailure(\n path,\n 'only plain objects and arrays are canonicalizable',\n );\n }\n // Default string sort compares UTF-16 code units, which is what RFC 8785\n // specifies for member ordering.\n const keys = Object.keys(objectValue).sort();\n const record = objectValue as Record<string, unknown>;\n const parts = keys.map((key) => {\n const encodedKey = JSON.stringify(key);\n const encodedValue = canonicalizeValue(record[key], `${path}.${key}`, seen);\n return `${encodedKey}:${encodedValue}`;\n });\n return `{${parts.join(',')}}`;\n } finally {\n seen.delete(objectValue);\n }\n}\n\n/**\n * Canonical JSON text for `value`, per RFC 8785 restricted to the value space\n * above. Key insertion order never affects the output; anything outside the\n * accepted space throws `proof_canonicalization_failed`.\n */\nexport function canonicalizeJson(value: JsonValue): string {\n return canonicalizeValue(value, '<root>', new Set());\n}\n\n/** UTF-8 bytes of {@link canonicalizeJson}. `TextEncoder` is a platform global on Node and Workers. */\nexport function canonicalizeJsonBytes(value: JsonValue): Uint8Array {\n return new TextEncoder().encode(canonicalizeJson(value));\n}\n\n// ---------------------------------------------------------------------------\n// Protected claims\n// ---------------------------------------------------------------------------\n\n/**\n * The signed claim set (§S6.2).\n *\n * The request line is expressible two ways — `method` + `path`, or a stable\n * `operationId` — and exactly one form must be present. Allowing both at once\n * would create two different canonical byte strings for one request; allowing\n * neither would drop the operation binding the whole design rests on.\n */\nexport const DeviceProofProtectedClaimsSchema = z\n .strictObject({\n version: z.literal(DEVICE_PROOF_VERSION),\n tenantId: z.string().min(1),\n productId: z.string().min(1),\n deviceId: z.string().min(1),\n /** Identity of the signing key, resolved against the device row at verify time. */\n keyId: z.string().min(1),\n /** Rotation generation. An older epoch is rejected by the verifier, not here. */\n keyEpoch: z.number().int().nonnegative(),\n /** Idempotency key: exact replay returns the original result, reuse with a different body is a conflict. */\n requestId: z.string().min(1),\n /** Logical operation, e.g. `truth.write`. */\n operation: z.string().min(1),\n /** Tenant-scoped resource the operation targets. */\n resource: z.string().min(1),\n method: z.string().regex(HTTP_METHOD_PATTERN).optional(),\n path: z.string().startsWith('/').optional(),\n operationId: z.string().min(1).optional(),\n bodySha256: z.string().regex(CONTENT_HASH_PATTERN),\n /** Bound alongside the hash so a truncation attack cannot hide behind a hash collision claim. */\n bodySize: z.number().int().nonnegative(),\n issuedAt: z.iso.datetime(),\n expiresAt: z.iso.datetime().optional(),\n nonce: z.string().min(1).optional(),\n })\n .superRefine((claims, ctx) => {\n const hasRequestLine = claims.method !== undefined && claims.path !== undefined;\n const hasOperationId = claims.operationId !== undefined;\n if (hasRequestLine === hasOperationId) {\n ctx.addIssue({\n code: 'custom',\n message:\n 'Claims must carry exactly one request binding: both `method` and `path`, or `operationId`.',\n });\n }\n if (!hasRequestLine && (claims.method !== undefined || claims.path !== undefined)) {\n ctx.addIssue({\n code: 'custom',\n message: '`method` and `path` must be supplied together.',\n });\n }\n });\n\nexport type DeviceProofProtectedClaims = z.infer<typeof DeviceProofProtectedClaimsSchema>;\n\nexport const DeviceProofEnvelopeV1Schema = z.strictObject({\n schema: z.literal(DEVICE_PROOF_SCHEMA_ID),\n algorithm: z.enum(DEVICE_PROOF_ALGORITHMS),\n protected: DeviceProofProtectedClaimsSchema,\n /** base64url, unpadded. */\n signature: z.string().regex(BASE64URL_PATTERN),\n});\n\nexport type DeviceProofEnvelopeV1 = z.infer<typeof DeviceProofEnvelopeV1Schema>;\n\n/**\n * Parses an envelope fail-closed.\n *\n * @throws {ByokCoreError} code `proof_envelope_invalid`.\n */\nexport function parseDeviceProofEnvelope(input: unknown): DeviceProofEnvelopeV1 {\n const result = DeviceProofEnvelopeV1Schema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'proof_envelope_invalid',\n `Invalid device proof envelope: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\n/**\n * Projects claims into the exact JSON object that gets canonicalized.\n *\n * Built field by field rather than by spreading the parsed object: an absent\n * optional must be an *absent key*, never a key holding `undefined`, or\n * `{nonce: undefined}` and `{}` would be the same request with two different\n * signatures. The canonicalizer refuses `undefined` outright, so this\n * projection is where absence is decided.\n */\nexport function deviceProofCanonicalClaims(claims: DeviceProofProtectedClaims): JsonObject {\n const canonical: Record<string, JsonValue> = {\n version: claims.version,\n tenantId: claims.tenantId,\n productId: claims.productId,\n deviceId: claims.deviceId,\n keyId: claims.keyId,\n keyEpoch: claims.keyEpoch,\n requestId: claims.requestId,\n operation: claims.operation,\n resource: claims.resource,\n bodySha256: claims.bodySha256,\n bodySize: claims.bodySize,\n issuedAt: claims.issuedAt,\n };\n if (claims.method !== undefined) canonical['method'] = claims.method;\n if (claims.path !== undefined) canonical['path'] = claims.path;\n if (claims.operationId !== undefined) canonical['operationId'] = claims.operationId;\n if (claims.expiresAt !== undefined) canonical['expiresAt'] = claims.expiresAt;\n if (claims.nonce !== undefined) canonical['nonce'] = claims.nonce;\n return canonical;\n}\n\n/** Canonical JSON text of the protected claim set, without the domain prefix. */\nexport function deviceProofCanonicalJson(claims: DeviceProofProtectedClaims): string {\n return canonicalizeJson(deviceProofCanonicalClaims(claims));\n}\n\n/**\n * The exact bytes a device signs and a verifier reconstructs:\n * `byok-device-proof-v1\\n` followed by the canonical claim JSON, UTF-8 encoded.\n *\n * Frozen by `src/__tests__/golden/device-proof-v1.canonical.json`.\n */\nexport function deviceProofSigningInput(claims: DeviceProofProtectedClaims): Uint8Array {\n return new TextEncoder().encode(\n DEVICE_PROOF_DOMAIN_PREFIX + deviceProofCanonicalJson(claims),\n );\n}\n\n// ---------------------------------------------------------------------------\n// Verify port\n// ---------------------------------------------------------------------------\n\nexport interface DeviceProofVerifyInput {\n readonly algorithm: DeviceProofAlgorithm;\n /** Raw public key, base64url — the JWK `x` encoding the device registry stores. */\n readonly publicKey: string;\n readonly signature: string;\n readonly signingInput: Uint8Array;\n}\n\n/**\n * Injected signature verification.\n *\n * Not a store port, so it has no tenant parameter: it answers a pure\n * cryptographic question about bytes. Deciding *which* key to check against is\n * the caller's tenant-scoped device-row lookup, and keeping that out of here is\n * what stops a verifier from becoming a second authority on device identity.\n */\nexport interface DeviceProofVerifier {\n verify(input: DeviceProofVerifyInput): Promise<boolean>;\n}\n","/**\n * The one timestamp format this package accepts across every composition.\n *\n * Every instant that crosses a store port is an ISO-8601 UTC string, and the\n * in-memory reference compares those strings with `<` / `>=` — a downgrade\n * grace deadline, a retention cutoff, a reservation expiry. Lexicographic\n * order equals chronological order **only** for the canonical\n * `YYYY-MM-DDTHH:mm:ss.sssZ` shape that `Date.prototype.toISOString` emits.\n * Feed the same store `2026-08-08T00:00:00+08:00` and the string comparison\n * silently answers a different question than a SQL `timestamptz` comparison\n * would, so the in-memory and Postgres compositions would diverge on an input\n * the conformance suite never sees.\n *\n * The fix is a format contract rather than a normalizer: a caller-supplied\n * timestamp that is not already canonical is **rejected**, not rewritten.\n * Rewriting would make this module a second authority on what instant the\n * caller meant, and an offset-bearing or second-precision string is exactly the\n * case where that guess is worth refusing.\n *\n * Store-produced timestamps are canonical by construction (they come from\n * `Clock.now().toISOString()`); this module guards the *inbound* direction —\n * `downgradeGraceUntil`, `deletePendingBefore`, `ackedBefore`,\n * `expireUnackedBefore`.\n *\n * No `node:` import and no clock read: validation is pure, so a Workers\n * composition and the constraint test (`Date.now()` is banned package-wide)\n * both stay happy. `Date.parse` is used for *calendar validity only* — the\n * pattern is what pins the shape.\n */\nimport { ByokCoreError } from './errors';\n\n/**\n * Exactly what `toISOString()` produces: four-digit year, `T` separator,\n * millisecond precision, literal `Z`. No offsets, no omitted milliseconds, no\n * expanded-year form — each of those breaks the lexicographic-order property.\n */\nexport const CANONICAL_TIMESTAMP_PATTERN =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n\n/**\n * True when `value` is a canonical ISO-8601 UTC instant.\n *\n * Two checks, in order: the pattern pins the *shape*, then a round trip\n * through `Date` pins *calendar validity* — `2026-02-30T00:00:00.000Z` matches\n * the pattern and is not an instant.\n */\nexport function isCanonicalTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') return false;\n if (!CANONICAL_TIMESTAMP_PATTERN.test(value)) return false;\n const parsed = Date.parse(value);\n if (!Number.isFinite(parsed)) return false;\n return new Date(parsed).toISOString() === value;\n}\n\n/**\n * Fail-closed gate for a caller-supplied instant.\n *\n * @param value The timestamp as received from the caller.\n * @param field Field name, so the failure names the contract that was missed\n * rather than just the bad string.\n * @returns The same string, so call sites can validate and assign in one step.\n * @throws {ByokCoreError} code `timestamp_not_canonical`.\n */\nexport function assertCanonicalTimestamp(value: string, field: string): string {\n if (!isCanonicalTimestamp(value)) {\n throw new ByokCoreError(\n 'timestamp_not_canonical',\n `${field} must be a canonical ISO-8601 UTC instant (YYYY-MM-DDTHH:mm:ss.sssZ), received ${JSON.stringify(value)}.`,\n );\n }\n return value;\n}\n","/**\n * A zod parse that never throws.\n *\n * `safeParse` returns a failure for invalid data, but it does not catch an\n * error that a getter or a proxy trap throws while zod reads the value, and a\n * revoked proxy throws on any read. A receiver that promises a typed result\n * for hostile input, or a typed error for bad caller input, parses through\n * this. Wire input from `JSON.parse` cannot hold getters or proxies; this\n * closes the same gap for in-process callers.\n */\nimport type { z } from 'zod';\n\nexport type TotalParseResult<T> =\n | { readonly success: true; readonly data: T }\n | { readonly success: false; readonly error?: z.ZodError };\n\n/** `schema.safeParse(value)`, with a throw while reading `value` as a failure without issues. */\nexport function safeParseTotal<S extends z.ZodType>(schema: S, value: unknown): TotalParseResult<z.output<S>> {\n try {\n return schema.safeParse(value);\n } catch {\n return { success: false };\n }\n}\n","/**\n * The WebCrypto surface core relies on, declared structurally so core's\n * published types need neither the DOM lib nor Node's types, and resolved\n * from `globalThis.crypto.subtle` so the browser, Node, and Bun share one\n * code path. No `node:crypto`.\n */\nimport { ByokCoreError } from './errors';\n\n/**\n * A WebCrypto `CryptoKey`, declared structurally so core's published types\n * need neither the DOM lib nor Node's types. Every runtime's native\n * `CryptoKey` satisfies it.\n */\nexport interface WebCryptoKey {\n readonly type: string;\n readonly extractable: boolean;\n readonly algorithm: object;\n readonly usages: readonly string[];\n}\n\n/** The subset of `SubtleCrypto` this package calls, typed loosely on purpose (see {@link WebCryptoKey}). */\nexport interface WebCryptoSubtle {\n importKey(format: 'raw' | 'jwk', keyData: object, algorithm: object, extractable: boolean, usages: string[]): Promise<WebCryptoKey>;\n exportKey(format: 'raw', key: WebCryptoKey): Promise<ArrayBuffer>;\n generateKey(algorithm: object, extractable: boolean, usages: string[]): Promise<{ publicKey: WebCryptoKey; privateKey: WebCryptoKey }>;\n deriveBits(algorithm: object, baseKey: WebCryptoKey, length: number): Promise<ArrayBuffer>;\n sign(algorithm: string, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n encrypt(algorithm: object, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n decrypt(algorithm: object, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n digest(algorithm: string, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n}\n\n/** The WebCrypto subtle interface, or a closed-set failure when the runtime lacks it. */\nexport function webCryptoSubtle(): WebCryptoSubtle {\n const subtle = (globalThis as { crypto?: { subtle?: WebCryptoSubtle } }).crypto?.subtle;\n if (subtle === undefined) {\n throw new ByokCoreError('webcrypto_unavailable', 'WebCrypto subtle is unavailable in this runtime');\n }\n return subtle;\n}\n","/**\n * RFC 9180 HPKE, base mode, exactly one cipher suite:\n * `DHKEM(P-256, HKDF-SHA256) / HKDF-SHA256 / AES-128-GCM`\n * (KEM `0x0010`, KDF `0x0001`, AEAD `0x0001`).\n *\n * Why this module exists instead of a dependency: the same bytes must be\n * produced in a browser (the Web seals a provider key), in Node, and in a\n * Bun-compiled device daemon (which opens it). Every primitive used here —\n * P-256 ECDH, HMAC-SHA-256, AES-GCM, SHA-256, random key generation — is a\n * WebCrypto primitive all three runtimes ship, so the suite needs no\n * third-party code and no `node:` import (core must stay Workers/browser\n * safe). There is no algorithm negotiation: one suite, one mode, and anything\n * else is rejected by the envelope schema before this module is reached.\n *\n * Only one-shot seal/open is reachable from the package root. The key\n * schedule and sequence-numbered nonces are exported from this module for the\n * RFC 9180 Appendix A.3 conformance tests only; `index.ts` never re-exports a\n * reusable encryption context.\n *\n * Self-implemented HPKE: RFC vectors and an independent implementation\n * interoperate in the test suite, but passing vectors is not an audit. A\n * dedicated security review is required before a release is published.\n */\nimport { ByokCoreError } from './errors';\nimport { webCryptoSubtle, type WebCryptoKey } from './webcrypto';\n\nconst KEM_ID = 0x0010;\nconst KDF_ID = 0x0001;\nconst AEAD_ID = 0x0001;\n\n/** Encoded P-256 public key and encapsulation length (uncompressed SEC1). */\nexport const HPKE_P256_PUBLIC_KEY_BYTES = 65;\nconst N_SECRET = 32;\nconst N_K = 16;\nconst N_N = 12;\nconst N_H = 32;\n/** AES-GCM authentication tag length. */\nexport const HPKE_AEAD_TAG_BYTES = 16;\n\nconst MODE_BASE = 0x00;\nconst HPKE_V1 = utf8('HPKE-v1');\nconst KEM_SUITE_ID = concat(utf8('KEM'), i2osp(KEM_ID, 2));\nconst HPKE_SUITE_ID = concat(utf8('HPKE'), i2osp(KEM_ID, 2), i2osp(KDF_ID, 2), i2osp(AEAD_ID, 2));\nconst EMPTY = new Uint8Array(0);\n/** HMAC pads its key with zeros to the block size, so an empty salt equals HashLen zeros. */\nconst ZERO_SALT = new Uint8Array(N_H);\n\ntype Bytes = Uint8Array<ArrayBuffer>;\n\nfunction utf8(value: string): Bytes {\n return new TextEncoder().encode(value) as Bytes;\n}\n\nfunction concat(...parts: readonly Uint8Array[]): Bytes {\n const length = parts.reduce((total, part) => total + part.byteLength, 0);\n const out = new Uint8Array(length);\n let offset = 0;\n for (const part of parts) {\n out.set(part, offset);\n offset += part.byteLength;\n }\n return out;\n}\n\nfunction i2osp(value: number, length: number): Bytes {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE integer encoding requires a non-negative safe integer');\n }\n const out = new Uint8Array(length);\n let remaining = value;\n for (let index = length - 1; index >= 0; index -= 1) {\n out[index] = remaining % 256;\n remaining = Math.floor(remaining / 256);\n }\n if (remaining !== 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE integer does not fit the requested width');\n }\n return out;\n}\n\nfunction copy(bytes: Uint8Array): Bytes {\n return new Uint8Array(bytes) as Bytes;\n}\n\nasync function hmacSha256(key: Uint8Array, data: Uint8Array): Promise<Bytes> {\n const subtle = webCryptoSubtle();\n const hmacKey = await subtle.importKey('raw', copy(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n return new Uint8Array(await subtle.sign('HMAC', hmacKey, copy(data))) as Bytes;\n}\n\nasync function hkdfExpand(prk: Uint8Array, info: Uint8Array, length: number): Promise<Bytes> {\n if (length > 255 * N_H) {\n throw new ByokCoreError('sealed_secret_invalid', 'HKDF output length exceeds its limit');\n }\n const out = new Uint8Array(length);\n let previous: Uint8Array = EMPTY;\n let offset = 0;\n for (let counter = 1; offset < length; counter += 1) {\n previous = await hmacSha256(prk, concat(previous, info, Uint8Array.of(counter)));\n const take = Math.min(previous.byteLength, length - offset);\n out.set(previous.subarray(0, take), offset);\n offset += take;\n }\n return out as Bytes;\n}\n\nasync function labeledExtract(suiteId: Uint8Array, salt: Uint8Array, label: string, ikm: Uint8Array): Promise<Bytes> {\n return hmacSha256(salt.byteLength === 0 ? ZERO_SALT : salt, concat(HPKE_V1, suiteId, utf8(label), ikm));\n}\n\nasync function labeledExpand(\n suiteId: Uint8Array,\n prk: Uint8Array,\n label: string,\n info: Uint8Array,\n length: number,\n): Promise<Bytes> {\n return hkdfExpand(prk, concat(i2osp(length, 2), HPKE_V1, suiteId, utf8(label), info), length);\n}\n\n/**\n * Import an uncompressed SEC1 P-256 public key for ECDH.\n *\n * The length and `0x04` prefix are checked here; the on-curve check is the\n * WebCrypto import itself, which rejects a point that is not on P-256.\n */\nexport async function importP256PublicKey(raw: Uint8Array): Promise<WebCryptoKey> {\n if (raw.byteLength !== HPKE_P256_PUBLIC_KEY_BYTES || raw[0] !== 0x04) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 public key must be a 65-byte uncompressed point');\n }\n try {\n return await webCryptoSubtle().importKey('raw', copy(raw), { name: 'ECDH', namedCurve: 'P-256' }, true, []);\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 public key is not a valid curve point', { cause });\n }\n}\n\nasync function ecdhP256(privateKey: WebCryptoKey, publicKey: WebCryptoKey): Promise<Bytes> {\n const bits = await webCryptoSubtle().deriveBits({ name: 'ECDH', public: publicKey }, privateKey, N_SECRET * 8);\n return new Uint8Array(bits) as Bytes;\n}\n\nasync function extractAndExpand(dh: Uint8Array, kemContext: Uint8Array): Promise<Bytes> {\n const eaePrk = await labeledExtract(KEM_SUITE_ID, EMPTY, 'eae_prk', dh);\n return labeledExpand(KEM_SUITE_ID, eaePrk, 'shared_secret', kemContext, N_SECRET);\n}\n\n/** Key schedule output for base mode. Exported for the RFC 9180 conformance tests only. */\nexport interface HpkeBaseKeySchedule {\n readonly sharedSecret: Uint8Array;\n readonly key: Uint8Array;\n readonly baseNonce: Uint8Array;\n readonly exporterSecret: Uint8Array;\n}\n\nasync function keyScheduleBase(sharedSecret: Uint8Array, info: Uint8Array): Promise<HpkeBaseKeySchedule> {\n const pskIdHash = await labeledExtract(HPKE_SUITE_ID, EMPTY, 'psk_id_hash', EMPTY);\n const infoHash = await labeledExtract(HPKE_SUITE_ID, EMPTY, 'info_hash', info);\n const context = concat(Uint8Array.of(MODE_BASE), pskIdHash, infoHash);\n const secret = await labeledExtract(HPKE_SUITE_ID, sharedSecret, 'secret', EMPTY);\n return {\n sharedSecret,\n key: await labeledExpand(HPKE_SUITE_ID, secret, 'key', context, N_K),\n baseNonce: await labeledExpand(HPKE_SUITE_ID, secret, 'base_nonce', context, N_N),\n exporterSecret: await labeledExpand(HPKE_SUITE_ID, secret, 'exp', context, N_H),\n };\n}\n\n/** A caller-fixed ephemeral key pair. Conformance tests only; production always generates one. */\nexport interface HpkeEphemeralKeyPair {\n readonly privateKey: WebCryptoKey;\n readonly publicKey: Uint8Array;\n}\n\n/** `SetupBaseS`. Exported for the RFC 9180 conformance tests only. */\nexport async function setupBaseSender(\n recipientPublicKey: Uint8Array,\n info: Uint8Array,\n ephemeral?: HpkeEphemeralKeyPair,\n): Promise<{ enc: Uint8Array; schedule: HpkeBaseKeySchedule }> {\n const pkR = await importP256PublicKey(recipientPublicKey);\n let pair = ephemeral;\n if (pair === undefined) {\n const subtle = webCryptoSubtle();\n const generated = await subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveBits']);\n pair = {\n privateKey: generated.privateKey,\n publicKey: new Uint8Array(await subtle.exportKey('raw', generated.publicKey)),\n };\n }\n const enc = copy(pair.publicKey);\n const dh = await ecdhP256(pair.privateKey, pkR);\n const sharedSecret = await extractAndExpand(dh, concat(enc, recipientPublicKey));\n return { enc, schedule: await keyScheduleBase(sharedSecret, info) };\n}\n\n/** `SetupBaseR`. Exported for the RFC 9180 conformance tests only. */\nexport async function setupBaseRecipient(\n enc: Uint8Array,\n recipientPrivateKey: WebCryptoKey,\n recipientPublicKey: Uint8Array,\n info: Uint8Array,\n): Promise<HpkeBaseKeySchedule> {\n if (recipientPublicKey.byteLength !== HPKE_P256_PUBLIC_KEY_BYTES || recipientPublicKey[0] !== 0x04) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 recipient public key must be a 65-byte uncompressed point');\n }\n const pkE = await importP256PublicKey(enc);\n let dh: Bytes;\n try {\n dh = await ecdhP256(recipientPrivateKey, pkE);\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_open_failed', 'HPKE decapsulation failed', { cause });\n }\n const sharedSecret = await extractAndExpand(dh, concat(enc, recipientPublicKey));\n return keyScheduleBase(sharedSecret, info);\n}\n\n/** `ComputeNonce(seq)`. Exported for the RFC 9180 conformance tests only. */\nexport function hpkeNonce(baseNonce: Uint8Array, sequence: number): Bytes {\n const seq = i2osp(sequence, N_N);\n const out = new Uint8Array(N_N);\n for (let index = 0; index < N_N; index += 1) out[index] = baseNonce[index]! ^ seq[index]!;\n return out as Bytes;\n}\n\nasync function aesGcmKey(key: Uint8Array, usage: 'encrypt' | 'decrypt'): Promise<WebCryptoKey> {\n return webCryptoSubtle().importKey('raw', copy(key), { name: 'AES-GCM' }, false, [usage]);\n}\n\n/** AEAD seal at an explicit sequence number. Exported for the RFC 9180 conformance tests only. */\nexport async function hpkeAeadSeal(\n schedule: HpkeBaseKeySchedule,\n sequence: number,\n aad: Uint8Array,\n plaintext: Uint8Array,\n): Promise<Bytes> {\n const ciphertext = await webCryptoSubtle().encrypt(\n { name: 'AES-GCM', iv: hpkeNonce(schedule.baseNonce, sequence), additionalData: copy(aad), tagLength: 128 },\n await aesGcmKey(schedule.key, 'encrypt'),\n copy(plaintext),\n );\n return new Uint8Array(ciphertext) as Bytes;\n}\n\n/** AEAD open at an explicit sequence number. Exported for the RFC 9180 conformance tests only. */\nexport async function hpkeAeadOpen(\n schedule: HpkeBaseKeySchedule,\n sequence: number,\n aad: Uint8Array,\n ciphertext: Uint8Array,\n): Promise<Bytes> {\n if (ciphertext.byteLength < HPKE_AEAD_TAG_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE ciphertext is shorter than its authentication tag');\n }\n try {\n const plaintext = await webCryptoSubtle().decrypt(\n { name: 'AES-GCM', iv: hpkeNonce(schedule.baseNonce, sequence), additionalData: copy(aad), tagLength: 128 },\n await aesGcmKey(schedule.key, 'decrypt'),\n copy(ciphertext),\n );\n return new Uint8Array(plaintext) as Bytes;\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_open_failed', 'HPKE ciphertext failed authentication', { cause });\n }\n}\n\n/** One-shot `SealBase`: a fresh ephemeral key, sequence 0, never reused. */\nexport async function hpkeSealBase(input: {\n readonly recipientPublicKey: Uint8Array;\n readonly info: Uint8Array;\n readonly aad: Uint8Array;\n readonly plaintext: Uint8Array;\n}): Promise<{ enc: Uint8Array; ciphertext: Uint8Array }> {\n const { enc, schedule } = await setupBaseSender(input.recipientPublicKey, input.info);\n return { enc, ciphertext: await hpkeAeadSeal(schedule, 0, input.aad, input.plaintext) };\n}\n\n/** One-shot `OpenBase`, sequence 0. */\nexport async function hpkeOpenBase(input: {\n readonly recipientPrivateKey: WebCryptoKey;\n readonly recipientPublicKey: Uint8Array;\n readonly enc: Uint8Array;\n readonly info: Uint8Array;\n readonly aad: Uint8Array;\n readonly ciphertext: Uint8Array;\n}): Promise<Uint8Array> {\n const schedule = await setupBaseRecipient(input.enc, input.recipientPrivateKey, input.recipientPublicKey, input.info);\n return hpkeAeadOpen(schedule, 0, input.aad, input.ciphertext);\n}\n","/**\n * Sealed provider provisioning v1 (plan web-sealed-provisioning §3).\n *\n * A browser seals a provider API key to one device's long-lived P-256\n * sealing key; the cloud relays only ciphertext; the device opens it in\n * memory. This module is the single byte authority both ends share:\n *\n * - the request schema (header + non-secret config + optional sealed secret),\n * - canonical AAD bytes, config digest, and request digest,\n * - the sealing-key claim canonical bytes a device signs at registration,\n * - plaintext padding (2-byte length prefix, zero-padded to 256-byte blocks),\n * - one-shot seal/open on top of `hpke.ts`.\n *\n * Every function is WebCrypto-only and `node:`-free so the Web bundle and the\n * device use literally the same code. Nothing here reads a clock, a network,\n * or a store; time windows, replay ledgers, placement and enrollment are the\n * device's (`@byok-sdk/keys`) decisions.\n *\n * Error messages never include plaintext, ciphertext, or key material.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson, canonicalizeJsonBytes, type JsonObject, type JsonValue } from './attestation';\nimport { CONTENT_HASH_PATTERN } from './blob';\nimport { ByokCoreError } from './errors';\nimport {\n HPKE_AEAD_TAG_BYTES,\n HPKE_P256_PUBLIC_KEY_BYTES,\n hpkeOpenBase,\n hpkeSealBase,\n importP256PublicKey,\n} from './hpke';\nimport { isCanonicalTimestamp } from './time';\nimport { safeParseTotal } from './total-parse';\nimport { webCryptoSubtle, type WebCryptoKey } from './webcrypto';\n\nexport type { WebCryptoKey } from './webcrypto';\n\n/** The only HPKE suite v1 admits. There is no negotiation and no second value. */\nexport const PROVIDER_SECRET_HPKE_SUITE = 'hpke-base.dhkem-p256-hkdf-sha256.hkdf-sha256.aes-128-gcm';\n\n/** HPKE `info`, versioned; a v2 is a new constant, never a parser branch. */\nexport const PROVIDER_SECRET_HPKE_INFO = 'byok-sdk.provider-secret.v1';\n\nexport const PROVIDER_PROVISIONING_REQUEST_VERSION = 1;\n\nexport const PROVIDER_PROVISIONING_OPERATIONS = ['configure', 'update_model', 'replace_secret', 'delete'] as const;\nexport type ProviderProvisioningOperation = (typeof PROVIDER_PROVISIONING_OPERATIONS)[number];\n\n/** Operations whose request must carry exactly one sealed secret. */\nexport const PROVIDER_PROVISIONING_SECRET_OPERATIONS = ['configure', 'replace_secret'] as const;\n\n/** Upper bound for `expiresAt - issuedAt` (plan D11). */\nexport const PROVIDER_PROVISIONING_MAX_TTL_MS = 15 * 60 * 1000;\n\n/** Plaintext is padded to a multiple of this many bytes so ciphertext length hides key length. */\nexport const PROVIDER_SECRET_PAD_BLOCK_BYTES = 256;\n\n/** Largest padded plaintext v1 accepts; the secret itself is at most this minus the 2-byte prefix. */\nexport const PROVIDER_SECRET_MAX_PADDED_BYTES = 4096;\n\nexport const PROVIDER_SECRET_MAX_BYTES = PROVIDER_SECRET_MAX_PADDED_BYTES - 2;\n\n/** Length of a sealing key id: base64url(sha256(raw public key)) truncated to 22 characters. */\nexport const SEALING_KEY_ID_LENGTH = 22;\n\n// ---------------------------------------------------------------------------\n// base64url (strict, unpadded, canonical)\n// ---------------------------------------------------------------------------\n\nconst B64URL_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\nconst B64URL_PATTERN = /^[A-Za-z0-9_-]*$/;\n\nexport function encodeBase64Url(bytes: Uint8Array): string {\n let out = '';\n let index = 0;\n for (; index + 3 <= bytes.length; index += 3) {\n const value = (bytes[index]! << 16) | (bytes[index + 1]! << 8) | bytes[index + 2]!;\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!\n + B64URL_ALPHABET[(value >> 6) & 63]! + B64URL_ALPHABET[value & 63]!;\n }\n const rest = bytes.length - index;\n if (rest === 1) {\n const value = bytes[index]! << 16;\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!;\n } else if (rest === 2) {\n const value = (bytes[index]! << 16) | (bytes[index + 1]! << 8);\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!\n + B64URL_ALPHABET[(value >> 6) & 63]!;\n }\n return out;\n}\n\n/** Decode canonical unpadded base64url, or throw — never a repaired approximation. */\nexport function decodeBase64Url(value: string, field: string): Uint8Array<ArrayBuffer> {\n if (!B64URL_PATTERN.test(value) || value.length % 4 === 1) {\n throw new ByokCoreError('sealed_secret_invalid', `${field} is not canonical base64url`);\n }\n const out = new Uint8Array(Math.floor((value.length * 3) / 4));\n let buffer = 0;\n let bits = 0;\n let offset = 0;\n for (const char of value) {\n buffer = (buffer << 6) | B64URL_ALPHABET.indexOf(char);\n bits += 6;\n if (bits >= 8) {\n bits -= 8;\n out[offset] = (buffer >> bits) & 0xff;\n offset += 1;\n }\n }\n if (encodeBase64Url(out) !== value) {\n throw new ByokCoreError('sealed_secret_invalid', `${field} is not canonical base64url`);\n }\n return out;\n}\n\nfunction base64UrlField(bytes: { exact?: number; max?: number }) {\n return z.string().superRefine((value, ctx) => {\n try {\n const decoded = decodeBase64Url(value, 'field');\n if (bytes.exact !== undefined && decoded.byteLength !== bytes.exact) {\n ctx.addIssue({ code: 'custom', message: `must decode to exactly ${bytes.exact} bytes` });\n }\n if (bytes.max !== undefined && decoded.byteLength > bytes.max) {\n ctx.addIssue({ code: 'custom', message: `must decode to at most ${bytes.max} bytes` });\n }\n } catch {\n ctx.addIssue({ code: 'custom', message: 'must be canonical unpadded base64url' });\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Hashing\n// ---------------------------------------------------------------------------\n\nasync function sha256(bytes: Uint8Array): Promise<Uint8Array> {\n return new Uint8Array(await webCryptoSubtle().digest('SHA-256', new Uint8Array(bytes)));\n}\n\nfunction hex(bytes: Uint8Array): string {\n let out = '';\n for (const byte of bytes) out += byte.toString(16).padStart(2, '0');\n return out;\n}\n\nasync function contentDigest(value: JsonValue): Promise<string> {\n return `sha256:${hex(await sha256(canonicalizeJsonBytes(value)))}`;\n}\n\n// ---------------------------------------------------------------------------\n// Sealing key (public JWK + claim)\n// ---------------------------------------------------------------------------\n\n/**\n * The only public-key shape v1 accepts. Strict: a `d` (private) member, an\n * `alg`, `use`, `key_ops` or any other extra member is rejected rather than\n * ignored, so a private JWK can never be published by mistake.\n */\nexport const SealingPublicJwkSchema = z.strictObject({\n kty: z.literal('EC'),\n crv: z.literal('P-256'),\n x: base64UrlField({ exact: 32 }),\n y: base64UrlField({ exact: 32 }),\n});\nexport type SealingPublicJwk = z.infer<typeof SealingPublicJwkSchema>;\n\nexport const SealingKeyIdSchema = z.string().regex(new RegExp(`^[A-Za-z0-9_-]{${SEALING_KEY_ID_LENGTH}}$`));\n\nfunction parseSealingPublicJwk(input: unknown): SealingPublicJwk {\n const result = safeParseTotal(SealingPublicJwkSchema, input);\n if (!result.success) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing public key must be a strict P-256 EC public JWK');\n }\n return result.data;\n}\n\n/** Uncompressed SEC1 bytes (`0x04 || x || y`) of a sealing public JWK. */\nexport function sealingPublicKeyBytes(publicJwk: SealingPublicJwk): Uint8Array<ArrayBuffer> {\n const jwk = parseSealingPublicJwk(publicJwk);\n const raw = new Uint8Array(HPKE_P256_PUBLIC_KEY_BYTES);\n raw[0] = 0x04;\n raw.set(decodeBase64Url(jwk.x, 'x'), 1);\n raw.set(decodeBase64Url(jwk.y, 'y'), 33);\n return raw;\n}\n\n/** `base64url(sha256(0x04 || x || y))[0..22]` — the device's and the browser's shared key id rule. */\nexport async function deriveSealingKeyId(publicJwk: SealingPublicJwk): Promise<string> {\n const raw = sealingPublicKeyBytes(publicJwk);\n await importP256PublicKey(raw);\n return encodeBase64Url(await sha256(raw)).slice(0, SEALING_KEY_ID_LENGTH);\n}\n\n/**\n * The claim a device signs (through its device-proof signer, host glue) when\n * it registers its sealing key. The proof body is these canonical bytes.\n */\nexport const SealingKeyClaimV1Schema = z.strictObject({\n version: z.literal(1),\n keyId: SealingKeyIdSchema,\n epoch: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n publicJwk: SealingPublicJwkSchema,\n});\nexport type SealingKeyClaimV1 = z.infer<typeof SealingKeyClaimV1Schema>;\n\n/** Canonical UTF-8 bytes of a sealing-key claim. */\nexport function sealingKeyClaimCanonicalBytes(claim: SealingKeyClaimV1): Uint8Array {\n const result = safeParseTotal(SealingKeyClaimV1Schema, claim);\n if (!result.success) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing key claim is invalid');\n }\n const parsed = result.data;\n return canonicalizeJsonBytes({\n version: parsed.version,\n keyId: parsed.keyId,\n epoch: parsed.epoch,\n publicJwk: { kty: parsed.publicJwk.kty, crv: parsed.publicJwk.crv, x: parsed.publicJwk.x, y: parsed.publicJwk.y },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Request schema\n// ---------------------------------------------------------------------------\n\n/** Opaque identifier: non-empty, bounded, no surrounding whitespace, no control characters. */\nconst OpaqueIdSchema = z.string().min(1).max(200).superRefine((value, ctx) => {\n if (value.trim() !== value || /[\\u0000-\\u001f\\u007f]/u.test(value)) {\n ctx.addIssue({ code: 'custom', message: 'must not carry surrounding whitespace or control characters' });\n }\n});\n\nconst CanonicalTimestampSchema = z.string().refine(isCanonicalTimestamp, 'must be a canonical ISO-8601 UTC instant');\n\nconst ProfileRefSchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/u);\nconst ProviderKindSchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/u);\nconst ModelIdSchema = z.string().min(1).max(160).refine((value) => value.trim() === value && !/[\\u0000-\\u001f\\u007f]/u.test(value), 'model id is invalid');\nconst CapabilitySchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/u);\n\n/**\n * `pi_model` travels as an opaque canonicalizable JSON object; the device\n * validates it against `@byok-sdk/keys`' strict `PiModelConfigSchema`. Core\n * only guarantees it has one canonical byte form.\n */\nconst PiModelJsonSchema = z.custom<JsonObject>((value) => {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return false;\n try {\n canonicalizeJson(value as JsonObject);\n return true;\n } catch {\n return false;\n }\n}, 'piModel must be a canonical JSON object');\n\nconst ModelConfigFields = {\n agentId: OpaqueIdSchema,\n providerKind: ProviderKindSchema,\n modelId: ModelIdSchema,\n piModel: PiModelJsonSchema,\n capabilities: z.array(CapabilitySchema).max(8).refine((values) => new Set(values).size === values.length, 'capabilities must be unique'),\n};\n\n/**\n * The non-secret configuration, one exact shape per operation. An operation\n * carries only the fields it acts on — `delete` has no model, `replace_secret`\n * declares only the provider kind its key is scoped to — so nothing is\n * accepted and silently ignored.\n */\nexport const ProviderProvisioningConfigV1Schema = z.discriminatedUnion('operation', [\n z.strictObject({ operation: z.literal('configure'), ...ModelConfigFields }),\n z.strictObject({ operation: z.literal('update_model'), ...ModelConfigFields }),\n z.strictObject({ operation: z.literal('replace_secret'), agentId: OpaqueIdSchema, providerKind: ProviderKindSchema }),\n z.strictObject({ operation: z.literal('delete'), agentId: OpaqueIdSchema }),\n]);\nexport type ProviderProvisioningConfigV1 = z.infer<typeof ProviderProvisioningConfigV1Schema>;\n\n/** The credential-free provider triple the Host believes is current (A3), or `null` for none. */\nexport const ProviderProvisioningExpectedProfileSchema = z.union([\n z.null(),\n z.strictObject({\n profileRef: ProfileRefSchema,\n profileRevision: z.string().regex(/^(?:0|[1-9][0-9]{0,19})$/u),\n profileHash: z.string().regex(CONTENT_HASH_PATTERN),\n }),\n]);\nexport type ProviderProvisioningExpectedProfile = z.infer<typeof ProviderProvisioningExpectedProfileSchema>;\n\n/**\n * Opaque, Host-issued identity version: the enrollment revision (changes on\n * re-pair / re-enrollment of the same device id) or the agent placement\n * revision. The device compares it byte-for-byte with its own snapshot.\n */\nexport const ProviderProvisioningIdentityRevisionSchema = z.string().min(1).max(128).regex(/^[A-Za-z0-9._:-]+$/u);\n\nexport const ProviderProvisioningHeaderV1Schema = z.strictObject({\n tenantId: OpaqueIdSchema,\n deviceId: OpaqueIdSchema,\n agentId: OpaqueIdSchema,\n requestId: OpaqueIdSchema,\n operation: z.enum(PROVIDER_PROVISIONING_OPERATIONS),\n /** Non-secret, strictly increasing per bot (A3); a device rejects anything not above its high-watermark. */\n operationGeneration: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n expectedProfile: ProviderProvisioningExpectedProfileSchema,\n /** The device enrollment revision the Host authorized against (F2). */\n expectedEnrollmentRevision: ProviderProvisioningIdentityRevisionSchema,\n /** The agent placement revision the Host authorized against (F2). */\n expectedPlacementRevision: ProviderProvisioningIdentityRevisionSchema,\n configDigest: z.string().regex(CONTENT_HASH_PATTERN),\n issuedAt: CanonicalTimestampSchema,\n expiresAt: CanonicalTimestampSchema,\n});\nexport type ProviderProvisioningHeaderV1 = z.infer<typeof ProviderProvisioningHeaderV1Schema>;\n\n/** Ciphertext bound: largest padded plaintext plus the AEAD tag. */\nconst MAX_CIPHERTEXT_BYTES = PROVIDER_SECRET_MAX_PADDED_BYTES + HPKE_AEAD_TAG_BYTES;\n\nexport const SealedProviderSecretV1Schema = z.strictObject({\n suite: z.literal(PROVIDER_SECRET_HPKE_SUITE),\n keyId: SealingKeyIdSchema,\n enc: base64UrlField({ exact: HPKE_P256_PUBLIC_KEY_BYTES }),\n ciphertext: base64UrlField({ max: MAX_CIPHERTEXT_BYTES }),\n});\nexport type SealedProviderSecretV1 = z.infer<typeof SealedProviderSecretV1Schema>;\n\nfunction isSecretOperation(operation: ProviderProvisioningOperation): boolean {\n return (PROVIDER_PROVISIONING_SECRET_OPERATIONS as readonly string[]).includes(operation);\n}\n\nexport const ProviderProvisioningRequestV1Schema = z\n .strictObject({\n version: z.literal(PROVIDER_PROVISIONING_REQUEST_VERSION),\n header: ProviderProvisioningHeaderV1Schema,\n config: ProviderProvisioningConfigV1Schema,\n sealed: SealedProviderSecretV1Schema.optional(),\n })\n .superRefine((request, ctx) => {\n if (request.header.operation !== request.config.operation) {\n ctx.addIssue({ code: 'custom', path: ['config', 'operation'], message: 'config operation must equal header operation' });\n }\n if (request.header.agentId !== request.config.agentId) {\n ctx.addIssue({ code: 'custom', path: ['config', 'agentId'], message: 'config agentId must equal header agentId' });\n }\n if (isSecretOperation(request.header.operation) !== (request.sealed !== undefined)) {\n ctx.addIssue({ code: 'custom', path: ['sealed'], message: 'a sealed secret is required exactly for configure and replace_secret' });\n }\n });\nexport type ProviderProvisioningRequestV1 = z.infer<typeof ProviderProvisioningRequestV1Schema>;\n\n/** Parse a request fail-closed. Issue text names paths and rules only, never values. */\nexport function parseProviderProvisioningRequest(input: unknown): ProviderProvisioningRequestV1 {\n const result = safeParseTotal(ProviderProvisioningRequestV1Schema, input);\n if (!result.success) {\n throw new ByokCoreError(\n 'provider_provisioning_request_invalid',\n `Invalid provider provisioning request: ${(result.error?.issues ?? [{ path: [], message: 'is not readable' }])\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n );\n }\n return result.data;\n}\n\n// ---------------------------------------------------------------------------\n// Canonical bytes and digests\n// ---------------------------------------------------------------------------\n\nfunction configJson(config: ProviderProvisioningConfigV1): JsonObject {\n return config as unknown as JsonObject;\n}\n\n/** `sha256:<hex>` over the canonical JSON of the non-secret config. */\nexport async function providerProvisioningConfigDigest(config: ProviderProvisioningConfigV1): Promise<string> {\n const result = safeParseTotal(ProviderProvisioningConfigV1Schema, config);\n if (!result.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config is invalid');\n }\n return contentDigest(configJson(result.data));\n}\n\n/**\n * Canonical AAD bytes. Every header field plus the sealing key id is bound,\n * so tampering with any of tenant, device, key, request, agent, operation,\n * generation, expected triple, expected enrollment and placement revisions,\n * config digest, or time window fails the AEAD.\n */\nexport function providerSecretAadBytes(header: ProviderProvisioningHeaderV1, keyId: string): Uint8Array {\n const parsed = safeParseTotal(ProviderProvisioningHeaderV1Schema, header);\n if (!parsed.success || !safeParseTotal(SealingKeyIdSchema, keyId).success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning AAD input is invalid');\n }\n const value = parsed.data;\n return canonicalizeJsonBytes({\n v: PROVIDER_PROVISIONING_REQUEST_VERSION,\n tenantId: value.tenantId,\n deviceId: value.deviceId,\n keyId,\n requestId: value.requestId,\n agentId: value.agentId,\n operation: value.operation,\n operationGeneration: value.operationGeneration,\n expectedProfile: value.expectedProfile === null\n ? null\n : {\n profileRef: value.expectedProfile.profileRef,\n profileRevision: value.expectedProfile.profileRevision,\n profileHash: value.expectedProfile.profileHash,\n },\n expectedEnrollmentRevision: value.expectedEnrollmentRevision,\n expectedPlacementRevision: value.expectedPlacementRevision,\n configDigest: value.configDigest,\n issuedAt: value.issuedAt,\n expiresAt: value.expiresAt,\n });\n}\n\n/**\n * `sha256:<hex>` over the canonical JSON of the complete request. A device\n * compares it for an already-seen `requestId`: equal returns the stored\n * result, different is a conflict.\n */\nexport async function providerProvisioningRequestDigest(request: ProviderProvisioningRequestV1): Promise<string> {\n const parsed = parseProviderProvisioningRequest(request);\n return contentDigest(parsed as unknown as JsonObject);\n}\n\n/** Fail closed unless `header.configDigest` is the digest of `config`. */\nexport async function assertProviderProvisioningConfigDigest(request: ProviderProvisioningRequestV1): Promise<void> {\n const parsed = parseProviderProvisioningRequest(request);\n if ((await providerProvisioningConfigDigest(parsed.config)) !== parsed.header.configDigest) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config digest does not match its header');\n }\n}\n\n// ---------------------------------------------------------------------------\n// Padding\n// ---------------------------------------------------------------------------\n\n/** `u16be(len) || utf8(secret) || zeros`, total a multiple of 256 bytes. */\nexport function padProviderSecret(secret: string): Uint8Array<ArrayBuffer> {\n const bytes = new TextEncoder().encode(secret);\n if (bytes.byteLength === 0 || bytes.byteLength > PROVIDER_SECRET_MAX_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', `Provider secret must be 1 to ${PROVIDER_SECRET_MAX_BYTES} UTF-8 bytes`);\n }\n const total = Math.ceil((bytes.byteLength + 2) / PROVIDER_SECRET_PAD_BLOCK_BYTES) * PROVIDER_SECRET_PAD_BLOCK_BYTES;\n const out = new Uint8Array(total);\n out[0] = bytes.byteLength >> 8;\n out[1] = bytes.byteLength & 0xff;\n out.set(bytes, 2);\n return out;\n}\n\n/** Strict inverse of {@link padProviderSecret}: block size, bounds, zero padding, and fatal UTF-8 are all checked. */\nexport function unpadProviderSecret(padded: Uint8Array): string {\n if (\n padded.byteLength < PROVIDER_SECRET_PAD_BLOCK_BYTES\n || padded.byteLength > PROVIDER_SECRET_MAX_PADDED_BYTES\n || padded.byteLength % PROVIDER_SECRET_PAD_BLOCK_BYTES !== 0\n ) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has an invalid length');\n }\n const length = (padded[0]! << 8) | padded[1]!;\n if (length === 0 || length + 2 > padded.byteLength || padded.byteLength - (length + 2) >= PROVIDER_SECRET_PAD_BLOCK_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has an invalid length prefix');\n }\n for (let index = length + 2; index < padded.byteLength; index += 1) {\n if (padded[index] !== 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has non-zero padding');\n }\n }\n try {\n return new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(padded.subarray(2, length + 2));\n } catch {\n throw new ByokCoreError('sealed_secret_invalid', 'Provider secret is not valid UTF-8');\n }\n}\n\n// ---------------------------------------------------------------------------\n// One-shot seal / open\n// ---------------------------------------------------------------------------\n\nconst INFO_BYTES = (): Uint8Array => new TextEncoder().encode(PROVIDER_SECRET_HPKE_INFO);\n\nexport interface SealProviderProvisioningRequestInput {\n /** The header without its digest; the digest is computed here from `config`. */\n readonly header: Omit<ProviderProvisioningHeaderV1, 'configDigest'>;\n readonly config: ProviderProvisioningConfigV1;\n /** Required exactly for secret-bearing operations. */\n readonly recipient?: { readonly keyId: string; readonly publicJwk: SealingPublicJwk };\n /** Required exactly for secret-bearing operations. */\n readonly secret?: string;\n}\n\n/**\n * Build one immutable provisioning request. Secret-bearing operations are\n * sealed once, to a freshly generated ephemeral key; the key id is re-derived\n * from the public JWK so a claim whose id does not match its key is refused\n * before anything is encrypted.\n */\nexport async function sealProviderProvisioningRequest(\n input: SealProviderProvisioningRequestInput,\n): Promise<ProviderProvisioningRequestV1> {\n const configResult = safeParseTotal(ProviderProvisioningConfigV1Schema, input.config);\n if (!configResult.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config is invalid');\n }\n const config = configResult.data;\n const headerResult = safeParseTotal(ProviderProvisioningHeaderV1Schema, {\n ...input.header,\n configDigest: await providerProvisioningConfigDigest(config),\n });\n if (!headerResult.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning header is invalid');\n }\n const header = headerResult.data;\n const needsSecret = isSecretOperation(header.operation);\n if (needsSecret !== (input.secret !== undefined) || needsSecret !== (input.recipient !== undefined)) {\n throw new ByokCoreError(\n 'provider_provisioning_request_invalid',\n 'A secret and recipient are required exactly for configure and replace_secret',\n );\n }\n let sealed: SealedProviderSecretV1 | undefined;\n if (needsSecret) {\n const recipient = input.recipient!;\n const publicJwk = parseSealingPublicJwk(recipient.publicJwk);\n if ((await deriveSealingKeyId(publicJwk)) !== recipient.keyId) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing key id does not match its public key');\n }\n const { enc, ciphertext } = await hpkeSealBase({\n recipientPublicKey: sealingPublicKeyBytes(publicJwk),\n info: INFO_BYTES(),\n aad: providerSecretAadBytes(header, recipient.keyId),\n plaintext: padProviderSecret(input.secret!),\n });\n sealed = {\n suite: PROVIDER_SECRET_HPKE_SUITE,\n keyId: recipient.keyId,\n enc: encodeBase64Url(enc),\n ciphertext: encodeBase64Url(ciphertext),\n };\n }\n return parseProviderProvisioningRequest({\n version: PROVIDER_PROVISIONING_REQUEST_VERSION,\n header,\n config,\n ...(sealed === undefined ? {} : { sealed }),\n });\n}\n\nexport interface ProviderSecretRecipient {\n readonly keyId: string;\n readonly publicJwk: SealingPublicJwk;\n /** Non-extractable ECDH private key; never leaves the device. */\n readonly privateKey: WebCryptoKey;\n}\n\n/**\n * Open the sealed secret of a request, in memory. Checks, in order: request\n * schema, suite (schema literal), recipient key id, config digest, ciphertext\n * length against the padding grammar, HPKE open under the request's own AAD,\n * then strict unpadding. Time windows, replay, and placement are not checked\n * here — they are device state.\n */\nexport async function openProviderProvisioningSecret(input: {\n readonly request: ProviderProvisioningRequestV1;\n readonly recipient: ProviderSecretRecipient;\n}): Promise<string> {\n const request = parseProviderProvisioningRequest(input.request);\n const sealed = request.sealed;\n if (sealed === undefined) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning request carries no sealed secret');\n }\n const publicJwk = parseSealingPublicJwk(input.recipient.publicJwk);\n if (sealed.keyId !== input.recipient.keyId || (await deriveSealingKeyId(publicJwk)) !== input.recipient.keyId) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealed secret is not addressed to this sealing key');\n }\n await assertProviderProvisioningConfigDigest(request);\n const ciphertext = decodeBase64Url(sealed.ciphertext, 'ciphertext');\n const paddedLength = ciphertext.byteLength - HPKE_AEAD_TAG_BYTES;\n if (\n paddedLength < PROVIDER_SECRET_PAD_BLOCK_BYTES\n || paddedLength > PROVIDER_SECRET_MAX_PADDED_BYTES\n || paddedLength % PROVIDER_SECRET_PAD_BLOCK_BYTES !== 0\n ) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealed secret ciphertext has an invalid length');\n }\n const padded = await hpkeOpenBase({\n recipientPrivateKey: input.recipient.privateKey,\n recipientPublicKey: sealingPublicKeyBytes(publicJwk),\n enc: decodeBase64Url(sealed.enc, 'enc'),\n info: INFO_BYTES(),\n aad: providerSecretAadBytes(request.header, sealed.keyId),\n ciphertext,\n });\n try {\n return unpadProviderSecret(padded);\n } finally {\n padded.fill(0);\n }\n}\n","/**\n * Byte helpers shared by the sealed-payload modules (#654 E1a).\n *\n * Every function is WebCrypto-only and `node:`-free, so a browser, Workers,\n * Node and Bun run the same code. The subpath `@byok-sdk/core/sealed-payload`\n * exports the sealed-payload interface, but not these helpers. The package\n * root exports none of the sealed-payload modules.\n *\n * Caller input errors throw `sealed_secret_invalid`, the code `hpke.ts`\n * already raises for bad HPKE input. Receiver checks never throw for hostile\n * bytes; they return a typed failure.\n */\nimport { z } from 'zod';\n\nimport { ByokCoreError } from '../errors';\nimport {\n SealingPublicJwkSchema,\n decodeBase64Url,\n encodeBase64Url,\n sealingPublicKeyBytes,\n type SealingPublicJwk,\n} from '../sealed-provider-secret';\nimport { webCryptoSubtle, type WebCryptoKey } from '../webcrypto';\n\nexport type Bytes = Uint8Array<ArrayBuffer>;\n\n/**\n * The strict EC P-256 public JWK core already uses for sealing keys. Member\n * signing keys and member KEM keys use the same shape.\n */\nexport type P256PublicJwk = SealingPublicJwk;\nexport const P256PublicJwkSchema = SealingPublicJwkSchema;\n\n/** Raw P1363 (`r || s`) ECDSA P-256 signature length. */\nconst ECDSA_P256_SIGNATURE_BYTES = 64;\n\nexport function invalidInput(message: string): ByokCoreError {\n return new ByokCoreError('sealed_secret_invalid', message);\n}\n\nexport function utf8(value: string): Bytes {\n return new TextEncoder().encode(value) as Bytes;\n}\n\nexport function copy(bytes: Uint8Array): Bytes {\n return new Uint8Array(bytes) as Bytes;\n}\n\nexport function concat(...parts: readonly Uint8Array[]): Bytes {\n const out = new Uint8Array(parts.reduce((total, part) => total + part.byteLength, 0));\n let offset = 0;\n for (const part of parts) {\n out.set(part, offset);\n offset += part.byteLength;\n }\n return out as Bytes;\n}\n\nexport function hex(bytes: Uint8Array): string {\n let out = '';\n for (const byte of bytes) out += byte.toString(16).padStart(2, '0');\n return out;\n}\n\nexport { decodeBase64Url, encodeBase64Url };\n\n/** Fresh CSPRNG bytes from `globalThis.crypto`, the same source WebCrypto keys come from. */\nexport function randomBytes(length: number): Bytes {\n const source = (globalThis as { crypto?: { getRandomValues?: <T extends Uint8Array>(array: T) => T } }).crypto;\n if (source?.getRandomValues === undefined) {\n throw new ByokCoreError('webcrypto_unavailable', 'WebCrypto getRandomValues is unavailable in this runtime');\n }\n return source.getRandomValues(new Uint8Array(length)) as Bytes;\n}\n\nexport async function sha256(bytes: Uint8Array): Promise<Bytes> {\n return new Uint8Array(await webCryptoSubtle().digest('SHA-256', copy(bytes))) as Bytes;\n}\n\nexport async function hmacSha256(key: Uint8Array, data: Uint8Array): Promise<Bytes> {\n const subtle = webCryptoSubtle();\n const hmacKey = await subtle.importKey('raw', copy(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n return new Uint8Array(await subtle.sign('HMAC', hmacKey, copy(data))) as Bytes;\n}\n\n/** RFC 5869 HKDF-SHA-256 through WebCrypto's own HKDF. */\nexport async function hkdfSha256(ikm: Uint8Array, salt: Uint8Array, info: string, length: number): Promise<Bytes> {\n const subtle = webCryptoSubtle();\n const key = await subtle.importKey('raw', copy(ikm), { name: 'HKDF' }, false, ['deriveBits']);\n const bits = await subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt: copy(salt), info: utf8(info) }, key, length * 8);\n return new Uint8Array(bits) as Bytes;\n}\n\n/** A zod string that must be canonical unpadded base64url of exactly `bytes` bytes. */\nexport function base64UrlBytes(bytes: number) {\n return z.string().refine((value) => {\n try {\n return decodeBase64Url(value, 'field').byteLength === bytes;\n } catch {\n return false;\n }\n }, `must be canonical unpadded base64url of ${bytes} bytes`);\n}\n\n/**\n * ECDSA `sign` with an algorithm object, and `verify`. Core's public\n * `WebCryptoSubtle` interface declares neither, and widening it would change\n * the published API, so this module types the same runtime object locally.\n */\ninterface EcdsaSubtle {\n importKey(format: 'jwk', keyData: object, algorithm: object, extractable: boolean, usages: string[]): Promise<WebCryptoKey>;\n sign(algorithm: object, key: WebCryptoKey, data: Bytes): Promise<ArrayBuffer>;\n verify(algorithm: object, key: WebCryptoKey, signature: Bytes, data: Bytes): Promise<boolean>;\n}\n\nconst ECDSA_P256 = { name: 'ECDSA', namedCurve: 'P-256' } as const;\nconst ECDSA_SHA256 = { name: 'ECDSA', hash: 'SHA-256' } as const;\n\nfunction ecdsaSubtle(): EcdsaSubtle {\n return webCryptoSubtle() as unknown as EcdsaSubtle;\n}\n\n/** Uncompressed SEC1 bytes of a strict P-256 public JWK, checked to be a point on the curve. */\nexport async function p256PublicKeyBytes(publicJwk: P256PublicJwk): Promise<Bytes> {\n const raw = sealingPublicKeyBytes(publicJwk);\n await importEcdsaPublicKey(publicJwk);\n return raw;\n}\n\nasync function importEcdsaPublicKey(publicJwk: P256PublicJwk): Promise<WebCryptoKey> {\n const jwk = P256PublicJwkSchema.parse(publicJwk);\n try {\n return await ecdsaSubtle().importKey('jwk', { kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y }, ECDSA_P256, true, ['verify']);\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 public key is not a valid curve point', { cause });\n }\n}\n\n/**\n * ECDSA P-256 / SHA-256 signature over `data`, as base64url of the 64-byte\n * P1363 form. The signature must verify under `publicJwk`, so a private key\n * that does not pair with the caller's public key throws\n * `sealed_secret_invalid` and signs nothing under another key's id.\n */\nexport async function ecdsaSign(publicJwk: P256PublicJwk, privateKey: WebCryptoKey, data: Uint8Array): Promise<string> {\n let signature: string;\n try {\n signature = encodeBase64Url(new Uint8Array(await ecdsaSubtle().sign(ECDSA_SHA256, privateKey, copy(data))));\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_invalid', 'Signing key is not an ECDSA P-256 private key', { cause });\n }\n if (!(await ecdsaVerify(publicJwk, signature, data))) {\n throw invalidInput('Signing private key does not pair with the signing public key');\n }\n return signature;\n}\n\n/** True only for a canonical 64-byte P1363 signature that verifies under `publicJwk`. */\nexport async function ecdsaVerify(publicJwk: P256PublicJwk, signature: string, data: Uint8Array): Promise<boolean> {\n let signatureBytes: Bytes;\n try {\n signatureBytes = decodeBase64Url(signature, 'sig');\n } catch {\n return false;\n }\n if (signatureBytes.byteLength !== ECDSA_P256_SIGNATURE_BYTES) return false;\n const key = await importEcdsaPublicKey(publicJwk);\n return ecdsaSubtle().verify(ECDSA_SHA256, key, signatureBytes, copy(data));\n}\n","/**\n * Member ids and member chain entries (#654 design §7.1, §7.3).\n *\n * A member is one device or one client. It holds an ECDSA P-256 signing key\n * and a P-256 KEM key. Its id derives from the signing public key alone, so a\n * KEM rotation keeps the id, and no SDK device id or product identity enters\n * it. A device member names its SDK device id inside its chain entry instead.\n *\n * This module signs and verifies ONE entry. Walking a chain — the `prev`\n * links, removed signers, the pinned anchor — and the per-op `subject` shapes\n * belong to the chain verifier (E2), which builds on these bytes.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson, canonicalizeJsonBytes, type JsonObject } from '../attestation';\nimport { CONTENT_HASH_PATTERN } from '../blob';\nimport { safeParseTotal } from '../total-parse';\nimport type { WebCryptoKey } from '../webcrypto';\nimport {\n base64UrlBytes,\n concat,\n ecdsaSign,\n ecdsaVerify,\n encodeBase64Url,\n hex,\n invalidInput,\n p256PublicKeyBytes,\n sha256,\n utf8,\n type Bytes,\n type P256PublicJwk,\n} from './primitives';\n\n/** Domain separation for {@link deriveMemberId}. */\nexport const MEMBER_ID_DOMAIN = 'byok-member-id-v1\\n';\n\n/** `base64url(sha256(MEMBER_ID_DOMAIN || 0x04 || x || y))`: 43 characters, no padding. */\nexport const MEMBER_ID_PATTERN = /^[A-Za-z0-9_-]{43}$/u;\n\nexport const MEMBER_CHAIN_VERSION = 1;\n\n/** Prepended to the canonical entry bytes, so a chain signature never verifies as another signed object. */\nexport const MEMBER_CHAIN_DOMAIN_PREFIX = 'byok-member-chain-v1\\n';\n\nexport const MEMBER_CHAIN_OPS = ['add', 'remove', 'rotate', 'scope-policy', 'shred'] as const;\nexport type MemberChainOp = (typeof MEMBER_CHAIN_OPS)[number];\n\n/** One entry before it is signed. `seq` starts at 1; the first entry, and only it, has `prev: null`. */\nexport interface UnsignedMemberChainEntryV1 {\n readonly v: typeof MEMBER_CHAIN_VERSION;\n readonly tenantId: string;\n readonly seq: number;\n /** `sha256:<hex>` of the previous entry's signing input. */\n readonly prev: string | null;\n readonly op: MemberChainOp;\n readonly subject: JsonObject;\n /** Member id of the signer. */\n readonly signer: string;\n}\n\nexport interface MemberChainEntryV1 extends UnsignedMemberChainEntryV1 {\n /** ECDSA P-256 / SHA-256 over the signing input, base64url of the 64-byte P1363 form. */\n readonly sig: string;\n}\n\n/**\n * A plain JSON object that has exactly one canonical byte form. The output is\n * rebuilt from the canonical text, so no later step reads the caller's object\n * again: a getter or a proxy cannot change or throw after this check.\n */\nconst CanonicalJsonObjectSchema = z.unknown().transform((value, ctx): JsonObject => {\n try {\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return JSON.parse(canonicalizeJson(value as JsonObject)) as JsonObject;\n }\n } catch {\n // Not canonical JSON, or a read threw: the issue below reports it.\n }\n ctx.addIssue({ code: 'custom', message: 'must be a canonical JSON object' });\n return z.NEVER;\n});\n\nconst unsignedEntryShape = {\n v: z.literal(MEMBER_CHAIN_VERSION),\n tenantId: z.string().min(1),\n seq: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n prev: z.union([z.null(), z.string().regex(CONTENT_HASH_PATTERN)]),\n op: z.enum(MEMBER_CHAIN_OPS),\n subject: CanonicalJsonObjectSchema,\n signer: z.string().regex(MEMBER_ID_PATTERN),\n};\n\nfunction firstEntryHasNoPrev(entry: { readonly seq: number; readonly prev: string | null }, ctx: z.RefinementCtx): void {\n if ((entry.seq === 1) !== (entry.prev === null)) {\n ctx.addIssue({ code: 'custom', path: ['prev'], message: 'the first entry, and only the first, has no prev' });\n }\n}\n\nconst UnsignedMemberChainEntryV1Schema = z.strictObject(unsignedEntryShape).superRefine(firstEntryHasNoPrev);\nconst MemberChainEntryV1Schema = z\n .strictObject({ ...unsignedEntryShape, sig: base64UrlBytes(64) })\n .superRefine(firstEntryHasNoPrev);\n\n/** The member id of a signing public key. The key must be a point on P-256. */\nexport async function deriveMemberId(signingPublicJwk: P256PublicJwk): Promise<string> {\n const raw = await p256PublicKeyBytes(signingPublicJwk);\n return encodeBase64Url(await sha256(concat(utf8(MEMBER_ID_DOMAIN), raw)));\n}\n\nfunction parseUnsignedEntry(entry: UnsignedMemberChainEntryV1): UnsignedMemberChainEntryV1 {\n const parsed = safeParseTotal(UnsignedMemberChainEntryV1Schema, entry);\n if (!parsed.success) throw invalidInput('Member chain entry is invalid');\n return parsed.data;\n}\n\nfunction signingInput(entry: UnsignedMemberChainEntryV1): Bytes {\n return concat(\n utf8(MEMBER_CHAIN_DOMAIN_PREFIX),\n canonicalizeJsonBytes({\n v: entry.v,\n tenantId: entry.tenantId,\n seq: entry.seq,\n prev: entry.prev,\n op: entry.op,\n subject: entry.subject,\n signer: entry.signer,\n }),\n );\n}\n\n/** `MEMBER_CHAIN_DOMAIN_PREFIX || canonicalJson(entry without sig)`. */\nexport function memberChainSigningInput(entry: UnsignedMemberChainEntryV1): Bytes {\n return signingInput(parseUnsignedEntry(entry));\n}\n\n/** `sha256:<hex>` of the signing input. The signature is not hashed, so the hash names the entry's content. */\nexport async function memberChainEntryHash(entry: UnsignedMemberChainEntryV1): Promise<string> {\n return `sha256:${hex(await sha256(memberChainSigningInput(entry)))}`;\n}\n\n/**\n * Sign one entry. The signer's public key is required so an entry is never\n * signed under a member id that is not the signer's own. A private key that\n * does not pair with that public key throws `sealed_secret_invalid`.\n */\nexport async function signMemberChainEntry(\n entry: UnsignedMemberChainEntryV1,\n signer: { readonly publicJwk: P256PublicJwk; readonly privateKey: WebCryptoKey },\n): Promise<MemberChainEntryV1> {\n const unsigned = parseUnsignedEntry(entry);\n if ((await deriveMemberId(signer.publicJwk)) !== unsigned.signer) {\n throw invalidInput('Member chain entry signer does not match the signing key');\n }\n return { ...unsigned, sig: await ecdsaSign(signer.publicJwk, signer.privateKey, signingInput(unsigned)) };\n}\n\nexport type MemberChainEntryVerifyResult =\n | { readonly ok: true; readonly entry: MemberChainEntryV1; readonly hash: string }\n | { readonly ok: false; readonly reason: 'member_chain_entry_invalid' | 'member_chain_signature_invalid' };\n\n/**\n * Verify one received entry against the signing key the verifier already\n * pins for `entry.signer`. A malformed entry, or a key whose member id is not\n * the entry's signer, is `member_chain_entry_invalid`; a bad signature is\n * `member_chain_signature_invalid`. Nothing here throws for hostile input.\n */\nexport async function verifyMemberChainEntry(\n entry: unknown,\n signerPublicJwk: P256PublicJwk,\n): Promise<MemberChainEntryVerifyResult> {\n const parsed = safeParseTotal(MemberChainEntryV1Schema, entry);\n if (!parsed.success || (await deriveMemberId(signerPublicJwk)) !== parsed.data.signer) {\n return { ok: false, reason: 'member_chain_entry_invalid' };\n }\n const input = signingInput(parsed.data);\n if (!(await ecdsaVerify(signerPublicJwk, parsed.data.sig, input))) {\n return { ok: false, reason: 'member_chain_signature_invalid' };\n }\n return { ok: true, entry: parsed.data, hash: `sha256:${hex(await sha256(input))}` };\n}\n","/**\n * The member key bundle (#654 design §7.1, §7.2, E2b; owner decision 10a).\n *\n * A bundle is the public half of one member: its id, its ECDSA P-256 signing\n * key, its P-256 KEM key, the KEM epoch, and `kemSig`. A device member also\n * names its SDK device id. A client member does not.\n *\n * `kemSig` is the member's own signature over its KEM key and epoch. The\n * fingerprint covers only the signing key, so a KEM rotation keeps the member\n * id and the fingerprint. The self-signature binds the KEM key to the member:\n * a Host that swaps the KEM key breaks the signature.\n *\n * An `add` chain entry carries the bundle. The pairing MACs bind it. In a\n * later slice, the device registers it with device proof.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJsonBytes } from '../attestation';\nimport type { WebCryptoKey } from '../webcrypto';\nimport { safeParseTotal } from '../total-parse';\nimport { deriveMemberId, MEMBER_ID_PATTERN } from './member-chain';\nimport {\n P256PublicJwkSchema,\n base64UrlBytes,\n concat,\n ecdsaSign,\n ecdsaVerify,\n invalidInput,\n p256PublicKeyBytes,\n utf8,\n type Bytes,\n type P256PublicJwk,\n} from './primitives';\n\nexport const MEMBER_KEY_BUNDLE_VERSION = 1;\n\n/** Prepended to the canonical KEM statement, so `kemSig` never verifies as another signed object. */\nexport const MEMBER_KEM_DOMAIN_PREFIX = 'byok-member-kem-v1\\n';\n\nexport interface MemberKeyBundleV1 {\n readonly v: typeof MEMBER_KEY_BUNDLE_VERSION;\n readonly memberId: string;\n readonly signingPublicJwk: P256PublicJwk;\n readonly kemPublicJwk: P256PublicJwk;\n readonly kemEpoch: number;\n /** ECDSA P-256 / SHA-256 by the signing key over the KEM statement, base64url of the 64-byte P1363 form. */\n readonly kemSig: string;\n /** The SDK device id of a device member. A client member has none. */\n readonly deviceId?: string;\n}\n\nexport const KemEpochSchema = z.number().int().positive().max(Number.MAX_SAFE_INTEGER);\nexport const KemSigSchema = base64UrlBytes(64);\n\n/** @internal The strict bundle shape. Shared with `pairing-verification.ts`. */\nexport const MemberKeyBundleV1Schema = z.strictObject({\n v: z.literal(MEMBER_KEY_BUNDLE_VERSION),\n memberId: z.string().regex(MEMBER_ID_PATTERN),\n signingPublicJwk: P256PublicJwkSchema,\n kemPublicJwk: P256PublicJwkSchema,\n kemEpoch: KemEpochSchema,\n kemSig: KemSigSchema,\n deviceId: z.string().min(1).optional(),\n});\n\n/** The caller data of `createMemberKeyBundle`, read once. The private key is kept as given; `ecdsaSign` checks it. */\nconst CreateInputSchema = z.object({\n signingPublicJwk: P256PublicJwkSchema,\n signingPrivateKey: z.custom<WebCryptoKey>(),\n kemPublicJwk: P256PublicJwkSchema,\n kemEpoch: KemEpochSchema,\n deviceId: z.string().min(1).optional(),\n});\n\n/** The fields `verifyMemberKem` reads, as plain values. Other fields, such as the rest of a bundle, are ignored. */\nconst KemSignerSchema = z.object({ memberId: z.string().regex(MEMBER_ID_PATTERN), signingPublicJwk: P256PublicJwkSchema });\nconst KemStatementSchema = z.object({ kemPublicJwk: P256PublicJwkSchema, kemEpoch: KemEpochSchema, kemSig: KemSigSchema });\n\n/** `MEMBER_KEM_DOMAIN_PREFIX || canonicalJson({ memberId, kemPublicKey: { x, y }, kemEpoch })`. */\nexport function memberKemSigningInput(memberId: string, kemPublicJwk: P256PublicJwk, kemEpoch: number): Bytes {\n return concat(\n utf8(MEMBER_KEM_DOMAIN_PREFIX),\n canonicalizeJsonBytes({ memberId, kemPublicKey: { x: kemPublicJwk.x, y: kemPublicJwk.y }, kemEpoch }),\n );\n}\n\nexport interface CreateMemberKeyBundleInput {\n readonly signingPublicJwk: P256PublicJwk;\n readonly signingPrivateKey: WebCryptoKey;\n readonly kemPublicJwk: P256PublicJwk;\n readonly kemEpoch: number;\n readonly deviceId?: string;\n}\n\n/** Build a bundle: derive the member id and sign the KEM statement. Bad input throws `sealed_secret_invalid`. */\nexport async function createMemberKeyBundle(input: CreateMemberKeyBundleInput): Promise<MemberKeyBundleV1> {\n const parsed = safeParseTotal(CreateInputSchema, input);\n if (!parsed.success) throw invalidInput('Member key bundle input is invalid');\n const { signingPublicJwk, signingPrivateKey, kemPublicJwk, kemEpoch, deviceId } = parsed.data;\n const memberId = await deriveMemberId(signingPublicJwk);\n if (!(await isValidMemberKemKey(kemPublicJwk, signingPublicJwk))) throw invalidInput('Member KEM key is invalid');\n const kemSig = await ecdsaSign(signingPublicJwk, signingPrivateKey, memberKemSigningInput(memberId, kemPublicJwk, kemEpoch));\n return {\n v: MEMBER_KEY_BUNDLE_VERSION,\n memberId,\n signingPublicJwk,\n kemPublicJwk,\n kemEpoch,\n kemSig,\n ...(deviceId === undefined ? {} : { deviceId }),\n };\n}\n\n/** Both keys are points on P-256, and the KEM key is not the signing key. */\nexport async function isValidMemberKemKey(kemPublicJwk: P256PublicJwk, signingPublicJwk: P256PublicJwk): Promise<boolean> {\n if (kemPublicJwk.x === signingPublicJwk.x && kemPublicJwk.y === signingPublicJwk.y) return false;\n try {\n await p256PublicKeyBytes(kemPublicJwk);\n return true;\n } catch {\n return false;\n }\n}\n\n/** The KEM key is valid for the member, and `kemSig` is the member's signature over it. Never throws. */\nexport async function verifyMemberKem(\n member: { readonly memberId: string; readonly signingPublicJwk: P256PublicJwk },\n kem: { readonly kemPublicJwk: P256PublicJwk; readonly kemEpoch: number; readonly kemSig: string },\n): Promise<boolean> {\n const signer = safeParseTotal(KemSignerSchema, member);\n const statement = safeParseTotal(KemStatementSchema, kem);\n if (!signer.success || !statement.success) return false;\n const { memberId, signingPublicJwk } = signer.data;\n const { kemPublicJwk, kemEpoch, kemSig } = statement.data;\n if (!(await isValidMemberKemKey(kemPublicJwk, signingPublicJwk))) return false;\n try {\n return await ecdsaVerify(signingPublicJwk, kemSig, memberKemSigningInput(memberId, kemPublicJwk, kemEpoch));\n } catch {\n return false;\n }\n}\n\n/**\n * Parse a received bundle. It is valid when its shape is strict, `memberId`\n * is the id of `signingPublicJwk` (which also checks that key is on the\n * curve), the KEM key is a different point on the curve, and `kemSig`\n * verifies. Returns `undefined` for anything else; it never throws for\n * hostile input.\n */\nexport async function parseMemberKeyBundle(value: unknown): Promise<MemberKeyBundleV1 | undefined> {\n const parsed = safeParseTotal(MemberKeyBundleV1Schema, value);\n if (!parsed.success) return undefined;\n const bundle = parsed.data;\n try {\n if ((await deriveMemberId(bundle.signingPublicJwk)) !== bundle.memberId) return undefined;\n } catch {\n return undefined;\n }\n if (!(await verifyMemberKem(bundle, bundle))) return undefined;\n return bundle;\n}\n","/**\n * Scope keys and key packages (#654 design §7.4, §8.1, §9.1).\n *\n * A scope key `SK(scope, epoch)` is 32 random bytes one member generates.\n * Three values derive from it:\n *\n * - `keyId`: `base64url(HMAC-SHA-256(SK, \"byok-scope-key-id-v1\"))[0..22]`. It\n * commits to the key, and the Host cannot derive the key from it.\n * - the content key of one sealed content: `HKDF-SHA-256(SK, salt,\n * \"byok-sdk.sealed.v1.enc\")`, with a fresh 32-byte salt per content;\n * - the MAC key of the scope epoch: `HKDF-SHA-256(SK, empty salt,\n * \"byok-sdk.sealed.v1.mac\")`.\n *\n * A key package carries SK to one member: HPKE base mode with core's one suite\n * (`hpke.ts`), info `byok-sdk.scope-key.v<version>`, AAD the canonical JSON of\n * the package's identity fields. HPKE base mode does not authenticate the\n * sender, so the sender member also signs the package.\n *\n * Version 2 (#654 E5b-2, owner batch §77a) adds `recipientKemEpoch`, the KEM\n * epoch of the recipient key the package is wrapped to, to the identity\n * fields, so the Host can refuse a package wrapped to a retired KEM key.\n * Packages are sealed as version 2; version 1 packages stored before it\n * still open.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJsonBytes } from '../attestation';\nimport { ByokCoreError } from '../errors';\nimport { hpkeOpenBase, hpkeSealBase } from '../hpke';\nimport { safeParseTotal } from '../total-parse';\nimport type { WebCryptoKey } from '../webcrypto';\nimport { KemEpochSchema } from './member-bundle';\nimport { MEMBER_ID_PATTERN, deriveMemberId } from './member-chain';\nimport {\n base64UrlBytes,\n concat,\n decodeBase64Url,\n ecdsaSign,\n ecdsaVerify,\n encodeBase64Url,\n hkdfSha256,\n hmacSha256,\n invalidInput,\n p256PublicKeyBytes,\n randomBytes,\n utf8,\n type Bytes,\n type P256PublicJwk,\n} from './primitives';\n\nexport const SCOPE_KEY_BYTES = 32;\n\n/** 16 bytes of the key-id HMAC, as unpadded base64url. */\nexport const SCOPE_KEY_ID_LENGTH = 22;\nexport const SCOPE_KEY_ID_PATTERN = /^[A-Za-z0-9_-]{22}$/u;\n\nconst KEY_ID_MESSAGE = 'byok-scope-key-id-v1';\nconst CONTENT_KEY_INFO = 'byok-sdk.sealed.v1.enc';\nconst MAC_KEY_INFO = 'byok-sdk.sealed.v1.mac';\n\n/** Byte length of the per-content HKDF salt. */\nexport const SEALED_SALT_BYTES = 32;\n\nexport const SCOPE_KEY_PACKAGE_VERSION = 1;\nexport const SCOPE_KEY_HPKE_INFO = 'byok-sdk.scope-key.v1';\n\n/** Prepended to the canonical package bytes the sender signs. */\nexport const SCOPE_KEY_PACKAGE_DOMAIN_PREFIX = 'byok-scope-key-package-v1\\n';\n\nexport const SCOPE_KEY_PACKAGE_V2 = 2;\nexport const SCOPE_KEY_HPKE_INFO_V2 = 'byok-sdk.scope-key.v2';\nexport const SCOPE_KEY_PACKAGE_V2_DOMAIN_PREFIX = 'byok-scope-key-package-v2\\n';\n\nconst P256_POINT_BYTES = 65;\nconst AEAD_TAG_BYTES = 16;\n\nfunction assertScopeKey(scopeKey: Uint8Array): void {\n if (scopeKey.byteLength !== SCOPE_KEY_BYTES) throw invalidInput(`Scope key must be ${SCOPE_KEY_BYTES} bytes`);\n}\n\n/** A fresh scope key from the platform CSPRNG. */\nexport function generateScopeKey(): Bytes {\n return randomBytes(SCOPE_KEY_BYTES);\n}\n\nexport async function deriveScopeKeyId(scopeKey: Uint8Array): Promise<string> {\n assertScopeKey(scopeKey);\n const mac = await hmacSha256(scopeKey, utf8(KEY_ID_MESSAGE));\n return encodeBase64Url(mac.subarray(0, 16));\n}\n\n/** The AES-256-GCM key of one sealed content. Each content has its own salt, so each key encrypts once. */\nexport async function deriveSealedContentKey(scopeKey: Uint8Array, salt: Uint8Array): Promise<Bytes> {\n assertScopeKey(scopeKey);\n if (salt.byteLength !== SEALED_SALT_BYTES) throw invalidInput(`Sealed content salt must be ${SEALED_SALT_BYTES} bytes`);\n return hkdfSha256(scopeKey, salt, CONTENT_KEY_INFO, 32);\n}\n\n/**\n * The content-MAC key of one scope epoch. The design's salt is empty; HMAC\n * pads its key with zeros, so 32 zero bytes give the same output, and no\n * runtime has to accept a zero-length HKDF salt.\n */\nexport async function deriveSealedMacKey(scopeKey: Uint8Array): Promise<Bytes> {\n assertScopeKey(scopeKey);\n return hkdfSha256(scopeKey, new Uint8Array(32), MAC_KEY_INFO, 32);\n}\n\nexport interface ScopeKeyPackageV1 {\n readonly v: typeof SCOPE_KEY_PACKAGE_VERSION;\n readonly tenantId: string;\n readonly scopeId: string;\n readonly epoch: number;\n readonly keyId: string;\n /** Member id of the member that can open the package. */\n readonly recipient: string;\n /** Member id of the member that sealed and signed the package. */\n readonly sender: string;\n /** HPKE encapsulated key: base64url of a 65-byte uncompressed P-256 point. */\n readonly enc: string;\n /** HPKE ciphertext of the scope key: base64url of 48 bytes. */\n readonly ciphertext: string;\n /** Sender's ECDSA P-256 / SHA-256 signature, base64url of the 64-byte P1363 form. */\n readonly sig: string;\n}\n\nconst ScopeKeyPackageV1Schema = z.strictObject({\n v: z.literal(SCOPE_KEY_PACKAGE_VERSION),\n tenantId: z.string().min(1),\n scopeId: z.string().min(1),\n epoch: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n keyId: z.string().regex(SCOPE_KEY_ID_PATTERN),\n recipient: z.string().regex(MEMBER_ID_PATTERN),\n sender: z.string().regex(MEMBER_ID_PATTERN),\n enc: base64UrlBytes(P256_POINT_BYTES),\n ciphertext: base64UrlBytes(SCOPE_KEY_BYTES + AEAD_TAG_BYTES),\n sig: base64UrlBytes(64),\n});\n\nexport interface ScopeKeyPackageV2 extends Omit<ScopeKeyPackageV1, 'v'> {\n readonly v: typeof SCOPE_KEY_PACKAGE_V2;\n /** The KEM epoch of the recipient key the package is wrapped to. */\n readonly recipientKemEpoch: number;\n}\n\nexport type ScopeKeyPackage = ScopeKeyPackageV1 | ScopeKeyPackageV2;\n\nconst ScopeKeyPackageV2Schema = z.strictObject({\n ...ScopeKeyPackageV1Schema.shape,\n v: z.literal(SCOPE_KEY_PACKAGE_V2),\n recipientKemEpoch: KemEpochSchema,\n});\n\nconst ScopeKeyPackageSchema = z.union([ScopeKeyPackageV1Schema, ScopeKeyPackageV2Schema]);\n\ntype PackageIdentity = Omit<ScopeKeyPackage, 'enc' | 'ciphertext' | 'sig'>;\n\n/** HPKE AAD: the canonical JSON of the package's identity fields. */\nfunction packageAad({ enc: _enc, ciphertext: _ciphertext, sig: _sig, ...identity }: PackageIdentity & Partial<ScopeKeyPackage>): Uint8Array {\n return canonicalizeJsonBytes(identity);\n}\n\n/** The bytes the sender signs: every field except `sig`, after the prefix of its version. */\nfunction packageSigningInput({ sig: _sig, ...pkg }: Omit<ScopeKeyPackage, 'sig'> & { readonly sig?: string }): Bytes {\n return concat(utf8(pkg.v === SCOPE_KEY_PACKAGE_V2 ? SCOPE_KEY_PACKAGE_V2_DOMAIN_PREFIX : SCOPE_KEY_PACKAGE_DOMAIN_PREFIX), canonicalizeJsonBytes(pkg));\n}\n\nexport interface SealScopeKeyPackageInput {\n readonly scopeKey: Uint8Array;\n readonly tenantId: string;\n readonly scopeId: string;\n readonly epoch: number;\n /** The recipient's current KEM key, with its epoch from the verified member chain. */\n readonly recipient: { readonly memberId: string; readonly kemPublicJwk: P256PublicJwk; readonly kemEpoch: number };\n readonly sender: { readonly signingPublicJwk: P256PublicJwk; readonly signingPrivateKey: WebCryptoKey };\n}\n\nconst PackageIdentitySchema = ScopeKeyPackageV2Schema.omit({ enc: true, ciphertext: true, sig: true });\n\n/**\n * Wrap one scope key to one member's KEM key of `recipient.kemEpoch` and sign\n * the version 2 package. A signing private key that does not pair with\n * `sender.signingPublicJwk` throws `sealed_secret_invalid`.\n */\nexport async function sealScopeKeyPackage(input: SealScopeKeyPackageInput): Promise<ScopeKeyPackageV2> {\n const parsed = safeParseTotal(PackageIdentitySchema, {\n v: SCOPE_KEY_PACKAGE_V2,\n tenantId: input.tenantId,\n scopeId: input.scopeId,\n epoch: input.epoch,\n keyId: await deriveScopeKeyId(input.scopeKey),\n recipient: input.recipient.memberId,\n recipientKemEpoch: input.recipient.kemEpoch,\n sender: await deriveMemberId(input.sender.signingPublicJwk),\n });\n if (!parsed.success) throw invalidInput('Scope key package input is invalid');\n const identity = parsed.data;\n const { enc, ciphertext } = await hpkeSealBase({\n recipientPublicKey: await p256PublicKeyBytes(input.recipient.kemPublicJwk),\n info: utf8(SCOPE_KEY_HPKE_INFO_V2),\n aad: packageAad(identity),\n plaintext: input.scopeKey,\n });\n const unsigned = { ...identity, enc: encodeBase64Url(enc), ciphertext: encodeBase64Url(ciphertext) };\n return { ...unsigned, sig: await ecdsaSign(input.sender.signingPublicJwk, input.sender.signingPrivateKey, packageSigningInput(unsigned)) };\n}\n\nexport interface OpenScopeKeyPackageInput {\n readonly package: unknown;\n /** What the caller asked the Host for. A package for anything else is refused. */\n readonly expected: { readonly tenantId: string; readonly scopeId: string; readonly epoch: number };\n readonly recipient: {\n readonly memberId: string;\n readonly kemPublicJwk: P256PublicJwk;\n readonly kemPrivateKey: WebCryptoKey;\n /** The KEM epoch of this key pair. A version 2 package must name it. */\n readonly kemEpoch: number;\n };\n /** The signing key the caller's verified chain holds for `package.sender`. */\n readonly senderSigningPublicJwk: P256PublicJwk;\n}\n\nexport type ScopeKeyPackageOpenResult =\n | { readonly ok: true; readonly scopeKey: Uint8Array; readonly keyId: string }\n | {\n readonly ok: false;\n readonly reason: 'key_package_invalid' | 'key_package_signature_invalid' | 'key_package_open_failed';\n };\n\n/**\n * Verify and open one key package, in this order: shape; addressed to this\n * recipient (and, for version 2, its KEM epoch) for the expected tenant,\n * scope and epoch; sender key matches the\n * sender id; sender signature; HPKE open; key length; and `keyId` equal to\n * the opened key's own id. Nothing here throws for hostile input.\n */\nexport async function openScopeKeyPackage(input: OpenScopeKeyPackageInput): Promise<ScopeKeyPackageOpenResult> {\n const parsed = safeParseTotal(ScopeKeyPackageSchema, input.package);\n if (!parsed.success) return { ok: false, reason: 'key_package_invalid' };\n const pkg = parsed.data;\n if (\n pkg.recipient !== input.recipient.memberId\n || (pkg.v === SCOPE_KEY_PACKAGE_V2 && pkg.recipientKemEpoch !== input.recipient.kemEpoch)\n || pkg.tenantId !== input.expected.tenantId\n || pkg.scopeId !== input.expected.scopeId\n || pkg.epoch !== input.expected.epoch\n || pkg.sender !== (await deriveMemberId(input.senderSigningPublicJwk))\n ) {\n return { ok: false, reason: 'key_package_invalid' };\n }\n if (!(await ecdsaVerify(input.senderSigningPublicJwk, pkg.sig, packageSigningInput(pkg)))) {\n return { ok: false, reason: 'key_package_signature_invalid' };\n }\n let scopeKey: Uint8Array;\n try {\n scopeKey = await hpkeOpenBase({\n recipientPrivateKey: input.recipient.kemPrivateKey,\n recipientPublicKey: await p256PublicKeyBytes(input.recipient.kemPublicJwk),\n enc: decodeBase64Url(pkg.enc, 'enc'),\n info: utf8(pkg.v === SCOPE_KEY_PACKAGE_V2 ? SCOPE_KEY_HPKE_INFO_V2 : SCOPE_KEY_HPKE_INFO),\n aad: packageAad(pkg),\n ciphertext: decodeBase64Url(pkg.ciphertext, 'ciphertext'),\n });\n } catch (error) {\n if (error instanceof ByokCoreError) return { ok: false, reason: 'key_package_open_failed' };\n throw error;\n }\n // A signed package whose key does not match its own key id came from a\n // faulty or hostile member; it opens nothing.\n if (scopeKey.byteLength !== SCOPE_KEY_BYTES || (await deriveScopeKeyId(scopeKey)) !== pkg.keyId) {\n scopeKey.fill(0);\n return { ok: false, reason: 'key_package_open_failed' };\n }\n return { ok: true, scopeKey, keyId: pkg.keyId };\n}\n","/**\n * Canonical JSON of a sealed plaintext (#786): RFC 8785 with its full number\n * rule.\n *\n * Keys sort by UTF-16 code unit and strings use the ECMAScript serialization,\n * the same as `canonicalizeJson`. Numbers differ. A finite number serializes\n * as `Number.prototype.toString` (RFC 8785 §3.2.2.3), so a decimal, an\n * exponent and an integer above 2^53 are sealable. `-0` serializes as `0`.\n * NaN and the infinities have no JSON form and throw.\n *\n * Only the sealed plaintext uses this rule. The AAD, the MAC identity, member\n * chain entries and key packages keep `canonicalizeJson`, whose safe-integer\n * rule belongs to the attestation contract.\n */\nimport type { JsonValue } from '../attestation';\nimport { invalidInput } from './primitives';\n\nfunction canonicalValue(value: unknown, seen: Set<object>): string {\n if (value === null) return 'null';\n switch (typeof value) {\n case 'boolean':\n return value ? 'true' : 'false';\n case 'string':\n return JSON.stringify(value);\n case 'number':\n if (!Number.isFinite(value)) throw invalidInput('Sealed plaintext holds a number with no JSON form');\n return String(value);\n case 'object':\n break;\n default:\n throw invalidInput(`Sealed plaintext holds a ${typeof value}, which is not a JSON type`);\n }\n if (seen.has(value)) throw invalidInput('Sealed plaintext holds a circular reference');\n seen.add(value);\n try {\n if (Array.isArray(value)) return `[${Array.from(value, (entry) => canonicalValue(entry, seen)).join(',')}]`;\n const prototype: unknown = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) throw invalidInput('Sealed plaintext holds an object that is not plain');\n const record = value as Record<string, unknown>;\n const members = Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalValue(record[key], seen)}`);\n return `{${members.join(',')}}`;\n } finally {\n seen.delete(value);\n }\n}\n\n/** The canonical JSON text of a sealed plaintext value. Throws `sealed_secret_invalid` outside JSON. */\nexport function canonicalizeSealedJson(value: JsonValue): string {\n return canonicalValue(value, new Set());\n}\n","/**\n * Sealed content v1 (#654 design §8.1, §8.2, §8.6, §9.1).\n *\n * A member seals the fields one category moves out of a payload. The result is\n * a header the Host may read — version, suite, category, scope, chain head,\n * sender, salt, nonce, padded length and content MAC — and the ciphertext\n * bytes. Whether the ciphertext travels inline or by reference is the wire\n * schema's rule, not this module's.\n *\n * The plaintext is the canonical JSON of the moved fields. It is framed before\n * encryption: `u32be(contentLength) || content || zeros`, padded in 256-byte\n * steps up to 16 KiB and with Padmé above. The frame is inside the AEAD, so the\n * length and the padding are authenticated, and one content has exactly one\n * legal padded length.\n *\n * The AAD binds every identity the Host could otherwise swap: tenant, scope,\n * epoch, key id, chain head, sender, message family, direction, the write's\n * identity, target device, Agent, the task's sealing categories, padded length\n * and content MAC. Envelope `id`, `seq` and `ts` stay out, so an envelope that\n * a dead-letter replay re-encodes still opens.\n *\n * `contentMac` is a keyed MAC over category, family, identity and plaintext. The\n * Host compares two submissions of one identity by it, without a key.\n *\n * A blob field is sealed by the same frame and key rule, before its outer\n * content. Its AAD is the outer AAD without `paddedLength` and `contentMac`,\n * plus its own `paddedLength` and the JSON Pointer `fieldPath` to its BlobRef.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson, canonicalizeJsonBytes, type JsonObject } from '../attestation';\nimport { CONTENT_HASH_PATTERN } from '../blob';\nimport { ByokCoreError } from '../errors';\nimport { isCanonicalTimestamp } from '../time';\nimport { safeParseTotal } from '../total-parse';\nimport { webCryptoSubtle } from '../webcrypto';\nimport { MEMBER_ID_PATTERN } from './member-chain';\nimport {\n base64UrlBytes,\n copy,\n decodeBase64Url,\n encodeBase64Url,\n hex,\n hmacSha256,\n invalidInput,\n randomBytes,\n utf8,\n type Bytes,\n} from './primitives';\nimport {\n SCOPE_KEY_ID_PATTERN,\n SEALED_SALT_BYTES,\n deriveScopeKeyId,\n deriveSealedContentKey,\n deriveSealedMacKey,\n} from './scope-key';\nimport { canonicalizeSealedJson } from './sealed-json';\n\nexport const SEALED_CONTENT_VERSION = 1;\n\n/** The only suite v1 admits. A new suite is a new constant and a new capability, never a parser branch. */\nexport const SEALED_CONTENT_SUITE = 'byok-sealed-v1.hkdf-sha256.aes-256-gcm';\n\n/** C1–C4, in their canonical order. A task's sealing categories are listed in this order. */\nexport const SEALED_CATEGORIES = ['task-input', 'agent-message', 'task-output', 'memory-projection'] as const;\nexport type SealedCategory = (typeof SEALED_CATEGORIES)[number];\n\nexport const SEALED_DIRECTIONS = ['server-to-daemon', 'daemon-to-server'] as const;\nexport type SealedDirection = (typeof SEALED_DIRECTIONS)[number];\n\nexport const SEALED_NONCE_BYTES = 12;\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport const AEAD_TAG_BYTES = 16;\nconst FRAME_HEADER_BYTES = 4;\nconst ALIGNED_FRAME_LIMIT = 16 * 1024;\nconst FRAME_ALIGNMENT = 256;\nconst MAX_CONTENT_LENGTH = 0xffff_ffff;\n\nconst CONTENT_MAC_PREFIX = 'byok-content-mac-v1\\n';\nconst CONTENT_MAC_PATTERN = /^hmac-sha256:[0-9a-f]{64}$/u;\n\n/** Dot-separated lowercase words, e.g. `task.offer_for_agent`. It can never hold the MAC's `\\n` separator. */\nconst FAMILY_PATTERN = /^[a-z][a-z0-9_]*(?:\\.[a-z][a-z0-9_]*)+$/u;\nconst IDENTITY_FIELD_PATTERN = /^[a-z][A-Za-z0-9]*$/u;\n/** The one family that binds no device (design §6.3). */\nconst ROUTINE_TEMPLATE_FAMILY = 'routine.template';\n\n// ---------------------------------------------------------------------------\n// Padding and framing (§8.1, §8.6)\n// ---------------------------------------------------------------------------\n\n/** `floor(log2(value))` for a positive safe integer, without floating-point logarithms. */\nfunction floorLog2(value: number): number {\n let exponent = 0;\n for (let remaining = value; remaining >= 2; remaining = Math.floor(remaining / 2)) exponent += 1;\n return exponent;\n}\n\n/**\n * The one legal padded length of a frame whose unpadded length is\n * `frameLength` (`4 + contentLength`). Up to 16 KiB: the next multiple of 256.\n * Above: Padmé — `E = floor(log2 n)`, `S = floor(log2 E) + 1`, rounded up to a\n * multiple of `2^(E − S)`, which adds less than 6.25%.\n */\nexport function sealedPaddedLength(frameLength: number): number {\n if (!Number.isSafeInteger(frameLength) || frameLength < FRAME_HEADER_BYTES) {\n throw invalidInput('Sealed frame length must be a safe integer of at least 4');\n }\n if (frameLength <= ALIGNED_FRAME_LIMIT) return Math.ceil(frameLength / FRAME_ALIGNMENT) * FRAME_ALIGNMENT;\n const exponent = floorLog2(frameLength);\n const step = 2 ** (exponent - (floorLog2(exponent) + 1));\n return Math.ceil(frameLength / step) * step;\n}\n\n/**\n * Total on any number: zod runs this refinement even after the integer checks fail.\n * @internal Shared with `sealed-blob.ts`. Stripped from the published declarations.\n */\nexport function isLegalPaddedLength(paddedLength: number): boolean {\n return Number.isSafeInteger(paddedLength)\n && paddedLength >= FRAME_ALIGNMENT\n && sealedPaddedLength(paddedLength) === paddedLength;\n}\n\n/** `u32be(contentLength) || content || zeros`, as long as {@link sealedPaddedLength} says. */\nexport function encodeSealedFrame(content: Uint8Array): Bytes {\n if (content.byteLength > MAX_CONTENT_LENGTH) throw invalidInput('Sealed content exceeds the 32-bit frame length');\n const frame = new Uint8Array(sealedPaddedLength(FRAME_HEADER_BYTES + content.byteLength));\n new DataView(frame.buffer).setUint32(0, content.byteLength, false);\n frame.set(content, FRAME_HEADER_BYTES);\n return frame as Bytes;\n}\n\n/**\n * The content of a decrypted frame, or `undefined` when one of the five\n * receiver checks fails: frame length equals `paddedLength`; the content fits;\n * `paddedLength` is the padded length of exactly this content; every padding\n * byte is zero; the content is within the message type's plaintext limit.\n */\nexport function decodeSealedFrame(frame: Uint8Array, paddedLength: number, maxContentLength: number): Uint8Array | undefined {\n if (frame.byteLength !== paddedLength || paddedLength < FRAME_HEADER_BYTES) return undefined;\n const contentLength = new DataView(frame.buffer, frame.byteOffset, frame.byteLength).getUint32(0, false);\n if (contentLength > paddedLength - FRAME_HEADER_BYTES) return undefined;\n if (sealedPaddedLength(FRAME_HEADER_BYTES + contentLength) !== paddedLength) return undefined;\n if (contentLength > maxContentLength) return undefined;\n for (let index = FRAME_HEADER_BYTES + contentLength; index < paddedLength; index += 1) {\n if (frame[index] !== 0) return undefined;\n }\n return frame.subarray(FRAME_HEADER_BYTES, FRAME_HEADER_BYTES + contentLength);\n}\n\n// ---------------------------------------------------------------------------\n// Header and binding\n// ---------------------------------------------------------------------------\n\nconst NonEmptyStringSchema = z.string().min(1);\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport const PositiveIntegerSchema = z.number().int().positive().max(Number.MAX_SAFE_INTEGER);\n\n/** What the Host may read of one sealed content. The ciphertext travels next to it. */\nexport const SealedContentHeaderV1Schema = z.strictObject({\n v: z.literal(SEALED_CONTENT_VERSION),\n suite: z.literal(SEALED_CONTENT_SUITE),\n category: z.enum(SEALED_CATEGORIES),\n scope: z.strictObject({\n id: NonEmptyStringSchema,\n epoch: PositiveIntegerSchema,\n keyId: z.string().regex(SCOPE_KEY_ID_PATTERN),\n }),\n chainHead: z.strictObject({\n seq: PositiveIntegerSchema,\n hash: z.string().regex(CONTENT_HASH_PATTERN),\n }),\n sender: z.string().regex(MEMBER_ID_PATTERN),\n salt: base64UrlBytes(SEALED_SALT_BYTES),\n nonce: base64UrlBytes(SEALED_NONCE_BYTES),\n paddedLength: PositiveIntegerSchema.refine(isLegalPaddedLength, 'must be a legal padded frame length'),\n contentMac: z.string().regex(CONTENT_MAC_PATTERN),\n});\nexport type SealedContentHeaderV1 = z.infer<typeof SealedContentHeaderV1Schema>;\n\nfunction isCanonicalCategoryList(categories: readonly SealedCategory[]): boolean {\n return categories.every((category, index) =>\n index === 0 || SEALED_CATEGORIES.indexOf(categories[index - 1]!) < SEALED_CATEGORIES.indexOf(category));\n}\n\n/**\n * What the receiver knows from its own context and the payload's plaintext\n * fields. The receiver builds it; the sealed bytes never supply it.\n */\nexport interface SealedBinding {\n readonly tenantId: string;\n /** Message family, e.g. `task.offer_for_agent`, or `routine.template`. */\n readonly family: string;\n readonly direction: SealedDirection;\n /** The write's identity: `{ taskId }`, `{ messageId }`, … or `{ routineId, definitionVersion }`. */\n readonly identity: { readonly [field: string]: string | number };\n /** Target device. `null` only for the `routine.template` family, which binds no device. */\n readonly deviceId: string | null;\n readonly agentRef: { readonly agentId: string; readonly profileRevision: string } | null;\n /** The task's `sealing.categories`, unique and in {@link SEALED_CATEGORIES} order. */\n readonly categories: readonly SealedCategory[];\n /** A `routine.template`'s expiry; `null` for every other family. */\n readonly notAfter: string | null;\n}\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport const SealedBindingSchema = z\n .strictObject({\n tenantId: NonEmptyStringSchema,\n family: z.string().regex(FAMILY_PATTERN),\n direction: z.enum(SEALED_DIRECTIONS),\n identity: z\n .record(\n z.string().regex(IDENTITY_FIELD_PATTERN),\n z.union([NonEmptyStringSchema, z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER)]),\n )\n .refine((identity) => Object.keys(identity).length > 0, 'identity must name at least one field'),\n deviceId: z.union([z.null(), NonEmptyStringSchema]),\n agentRef: z.union([z.null(), z.strictObject({ agentId: NonEmptyStringSchema, profileRevision: NonEmptyStringSchema })]),\n categories: z.array(z.enum(SEALED_CATEGORIES)).min(1).refine(isCanonicalCategoryList, 'categories must be unique and in canonical order'),\n notAfter: z.union([z.null(), z.string().refine(isCanonicalTimestamp, 'must be a canonical UTC instant')]),\n })\n .superRefine((binding, ctx) => {\n const template = binding.family === ROUTINE_TEMPLATE_FAMILY;\n if ((binding.deviceId === null) !== template || (binding.notAfter === null) === template) {\n ctx.addIssue({\n code: 'custom',\n path: ['deviceId'],\n message: 'a routine template binds an expiry and no device; every other family binds a device and no expiry',\n });\n }\n });\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport type ParsedBinding = z.infer<typeof SealedBindingSchema>;\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport function parseBinding(binding: SealedBinding): ParsedBinding {\n const parsed = safeParseTotal(SealedBindingSchema, binding);\n if (!parsed.success) throw invalidInput('Sealed content binding is invalid');\n return parsed.data;\n}\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport function assertMaxContentLength(maxContentLength: number): void {\n if (!Number.isSafeInteger(maxContentLength) || maxContentLength < 0 || maxContentLength > MAX_CONTENT_LENGTH) {\n throw invalidInput('Sealed content limit must be a non-negative 32-bit integer');\n }\n}\n\n/**\n * The header fields that do not depend on the plaintext. A blob is sealed before its outer content, so it knows only these.\n * @internal Shared with `sealed-blob.ts`. Stripped from the published declarations.\n */\nexport type SealedAadContext = Pick<SealedContentHeaderV1, 'v' | 'suite' | 'category' | 'scope' | 'chainHead' | 'sender'>;\n\n/**\n * The 16 AAD members that the outer content and its blobs share (§8.2, §8.1).\n * @internal Shared with `sealed-blob.ts`. Stripped from the published declarations.\n */\nexport function bindingAad(header: SealedAadContext, binding: ParsedBinding) {\n return {\n v: header.v,\n suite: header.suite,\n category: header.category,\n tenantId: binding.tenantId,\n scopeId: header.scope.id,\n epoch: header.scope.epoch,\n keyId: header.scope.keyId,\n chainHead: { seq: header.chainHead.seq, hash: header.chainHead.hash },\n sender: header.sender,\n family: binding.family,\n direction: binding.direction,\n identity: binding.identity,\n deviceId: binding.deviceId,\n agentRef: binding.agentRef === null\n ? null\n : { agentId: binding.agentRef.agentId, profileRevision: binding.agentRef.profileRevision },\n categories: [...binding.categories],\n notAfter: binding.notAfter,\n };\n}\n\nfunction aadBytes(header: SealedContentHeaderV1, binding: ParsedBinding): Uint8Array {\n return canonicalizeJsonBytes({ ...bindingAad(header, binding), paddedLength: header.paddedLength, contentMac: header.contentMac });\n}\n\n/** The canonical AAD bytes of a header under a binding (§8.2). */\nexport function sealedContentAad(header: SealedContentHeaderV1, binding: SealedBinding): Uint8Array {\n const parsed = safeParseTotal(SealedContentHeaderV1Schema, header);\n if (!parsed.success) throw invalidInput('Sealed content header is invalid');\n return aadBytes(parsed.data, parseBinding(binding));\n}\n\n// ---------------------------------------------------------------------------\n// Plaintext and content MAC (§9.1)\n// ---------------------------------------------------------------------------\n\nfunction isNonEmptyPlainObject(value: unknown): boolean {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return false;\n const prototype: unknown = Object.getPrototypeOf(value);\n return (prototype === Object.prototype || prototype === null) && Object.keys(value).length > 0;\n}\n\n/** The plaintext text, with the RFC 8785 number rule (#786). The AAD and the MAC identity keep `canonicalizeJson`. */\nfunction canonicalPlaintext(plaintext: JsonObject): string {\n try {\n if (isNonEmptyPlainObject(plaintext)) return canonicalizeSealedJson(plaintext);\n } catch (cause) {\n // A throwing getter or proxy trap reaches here too, from either check; the caller sees one typed error.\n throw new ByokCoreError('sealed_secret_invalid', 'Sealed plaintext is not canonical JSON', { cause });\n }\n throw invalidInput('Sealed plaintext must be a non-empty plain JSON object');\n}\n\n/** Decoded content, only when it is the canonical JSON text of a non-empty plain object. */\nfunction parseCanonicalPlaintext(content: Uint8Array): { readonly value: JsonObject; readonly text: string } | undefined {\n let text: string;\n let value: unknown;\n try {\n text = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(content);\n value = JSON.parse(text);\n if (!isNonEmptyPlainObject(value) || canonicalizeSealedJson(value as JsonObject) !== text) return undefined;\n } catch {\n return undefined;\n }\n return { value: value as JsonObject, text };\n}\n\n/**\n * `\"hmac-sha256:\" + hex(HMAC-SHA-256(K_mac, \"byok-content-mac-v1\\n\" || category\n * || \"\\n\" || family || \"\\n\" || canonicalJson(identity) || \"\\n\" || plaintext))`.\n * No field before the plaintext can hold a raw `\\n`, so the input splits one way.\n */\nasync function contentMacOf(scopeKey: Uint8Array, category: SealedCategory, binding: ParsedBinding, plaintextText: string): Promise<string> {\n const macKey = await deriveSealedMacKey(scopeKey);\n try {\n const input = `${CONTENT_MAC_PREFIX}${category}\\n${binding.family}\\n${canonicalizeJson(binding.identity)}\\n${plaintextText}`;\n return `hmac-sha256:${hex(await hmacSha256(macKey, utf8(input)))}`;\n } finally {\n macKey.fill(0);\n }\n}\n\n/** The content MAC of one plaintext under one scope key (§9.1). */\nexport async function sealedContentMac(input: {\n readonly scopeKey: Uint8Array;\n readonly category: SealedCategory;\n readonly binding: SealedBinding;\n readonly plaintext: JsonObject;\n}): Promise<string> {\n return contentMacOf(input.scopeKey, input.category, parseBinding(input.binding), canonicalPlaintext(input.plaintext));\n}\n\n// ---------------------------------------------------------------------------\n// Seal and open\n// ---------------------------------------------------------------------------\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport async function aesGcm(\n mode: 'encrypt' | 'decrypt',\n key: Uint8Array,\n nonce: Uint8Array,\n aad: Uint8Array,\n data: Uint8Array,\n): Promise<Bytes> {\n const subtle = webCryptoSubtle();\n const cryptoKey = await subtle.importKey('raw', copy(key), { name: 'AES-GCM' }, false, [mode]);\n const params = { name: 'AES-GCM', iv: copy(nonce), additionalData: copy(aad), tagLength: 128 };\n const out = mode === 'encrypt'\n ? await subtle.encrypt(params, cryptoKey, copy(data))\n : await subtle.decrypt(params, cryptoKey, copy(data));\n return new Uint8Array(out) as Bytes;\n}\n\nexport interface SealContentInput {\n readonly scopeKey: Uint8Array;\n readonly scope: { readonly id: string; readonly epoch: number };\n /** The member chain head the sender verified before sealing. */\n readonly chainHead: { readonly seq: number; readonly hash: string };\n /** The sender's member id. */\n readonly sender: string;\n readonly category: SealedCategory;\n readonly binding: SealedBinding;\n /** The fields this category moves out of the payload. */\n readonly plaintext: JsonObject;\n /** The plaintext limit of this message type, in UTF-8 bytes of canonical JSON. */\n readonly maxContentLength: number;\n}\n\n/**\n * The salt and nonce of one seal, for test vectors only.\n * @internal Stripped from the published declarations.\n */\nexport interface SealedContentRandomness {\n readonly salt: Uint8Array;\n readonly nonce: Uint8Array;\n}\n\nexport interface SealedContent {\n readonly header: SealedContentHeaderV1;\n /** AES-256-GCM output: the padded frame followed by the 16-byte tag. */\n readonly ciphertext: Uint8Array;\n}\n\n/** Seal one category of a payload once. A retry must resend these bytes, never seal again (§9.2). */\nexport async function sealContent(input: SealContentInput): Promise<SealedContent> {\n return sealContentWithRandomness(input, { salt: randomBytes(SEALED_SALT_BYTES), nonce: randomBytes(SEALED_NONCE_BYTES) });\n}\n\n/**\n * {@link sealContent} with a caller-chosen salt and nonce, for test vectors\n * only. Neither the root nor the subpath exports it: a reused nonce under one\n * content key breaks AES-GCM.\n * @internal Stripped from the published declarations.\n */\nexport async function sealContentWithRandomness(input: SealContentInput, randomness: SealedContentRandomness): Promise<SealedContent> {\n const binding = parseBinding(input.binding);\n assertMaxContentLength(input.maxContentLength);\n if (!binding.categories.includes(input.category)) {\n throw invalidInput('Sealed content category is not one of the task sealing categories');\n }\n const plaintextText = canonicalPlaintext(input.plaintext);\n const content = utf8(plaintextText);\n if (content.byteLength > input.maxContentLength) throw invalidInput('Sealed content exceeds its plaintext limit');\n const frame = encodeSealedFrame(content);\n const { salt, nonce } = randomness;\n const parsed = safeParseTotal(SealedContentHeaderV1Schema, {\n v: SEALED_CONTENT_VERSION,\n suite: SEALED_CONTENT_SUITE,\n category: input.category,\n scope: { id: input.scope.id, epoch: input.scope.epoch, keyId: await deriveScopeKeyId(input.scopeKey) },\n chainHead: { seq: input.chainHead.seq, hash: input.chainHead.hash },\n sender: input.sender,\n salt: encodeBase64Url(salt),\n nonce: encodeBase64Url(nonce),\n paddedLength: frame.byteLength,\n contentMac: await contentMacOf(input.scopeKey, input.category, binding, plaintextText),\n });\n if (!parsed.success) throw invalidInput('Sealed content header input is invalid');\n const contentKey = await deriveSealedContentKey(input.scopeKey, salt);\n try {\n const ciphertext = await aesGcm('encrypt', contentKey, nonce, aadBytes(parsed.data, binding), frame);\n return { header: parsed.data, ciphertext };\n } finally {\n contentKey.fill(0);\n frame.fill(0);\n content.fill(0);\n }\n}\n\n/** The receiver failure codes of design §8.3. */\nexport type SealedContentOpenFailure =\n | 'sealed_key_unavailable'\n | 'sealed_open_failed'\n | 'sealed_content_mac_mismatch'\n | 'sealing_policy_mismatch';\n\n/**\n * An opened content, with the header that the AEAD authenticated. The caller\n * reads `chainHead` and `sender` from it for the sender-view check (§7.3).\n */\nexport type SealedContentOpenResult =\n | { readonly ok: true; readonly plaintext: JsonObject; readonly header: SealedContentHeaderV1 }\n | { readonly ok: false; readonly reason: SealedContentOpenFailure };\n\n/** The task's frozen `sealing` scope (§6.2). Its `categories` are {@link SealedBinding.categories}. */\nexport interface SealedScopePolicy {\n readonly scopeId: string;\n /** The lowest epoch the task accepts: the epoch of the offer's C1 content. */\n readonly epoch: number;\n}\n\nconst SealedScopePolicySchema = z.strictObject({ scopeId: NonEmptyStringSchema, epoch: PositiveIntegerSchema });\n\nexport interface OpenSealedContentInput {\n /** The header as received. It is untrusted. */\n readonly header: unknown;\n readonly ciphertext: Uint8Array;\n /** The scope key the receiver holds for `header.scope`. */\n readonly scopeKey: Uint8Array;\n /** Partly written by the Host (`sealing.categories`, `notAfter`), so it is untrusted too. */\n readonly binding: SealedBinding;\n /** From the task's `sealing`, which the Host writes. Untrusted. */\n readonly sealing: SealedScopePolicy;\n readonly maxContentLength: number;\n}\n\n/** @internal Shared with `sealed-blob.ts`. Stripped from the published declarations. */\nexport function failure(reason: SealedContentOpenFailure): { readonly ok: false; readonly reason: SealedContentOpenFailure } {\n return { ok: false, reason };\n}\n\n/**\n * Open one sealed content, fail closed. In order: a binding and a task scope\n * that parse (`sealing_policy_mismatch`); header shape (`sealed_open_failed`);\n * the category within the task's categories, and the header scope equal to\n * the task's scope at its epoch or later (both `sealing_policy_mismatch`); key\n * id of the held scope key (`sealed_key_unavailable`); ciphertext length; AEAD\n * under the rebuilt AAD; the five frame checks; canonical JSON of a plain\n * object (all `sealed_open_failed`); and the content MAC\n * (`sealed_content_mac_mismatch`).\n * There is no plaintext fallback, and nothing here throws for hostile input.\n */\nexport async function openSealedContent(input: OpenSealedContentInput): Promise<SealedContentOpenResult> {\n assertMaxContentLength(input.maxContentLength);\n const parsedBinding = safeParseTotal(SealedBindingSchema, input.binding);\n const parsedSealing = safeParseTotal(SealedScopePolicySchema, input.sealing);\n if (!parsedBinding.success || !parsedSealing.success) return failure('sealing_policy_mismatch');\n const binding = parsedBinding.data;\n const sealing = parsedSealing.data;\n const parsed = safeParseTotal(SealedContentHeaderV1Schema, input.header);\n if (!parsed.success) return failure('sealed_open_failed');\n const header = parsed.data;\n if (\n !binding.categories.includes(header.category)\n || header.scope.id !== sealing.scopeId\n || header.scope.epoch < sealing.epoch\n ) {\n return failure('sealing_policy_mismatch');\n }\n if ((await deriveScopeKeyId(input.scopeKey)) !== header.scope.keyId) return failure('sealed_key_unavailable');\n if (input.ciphertext.byteLength !== header.paddedLength + AEAD_TAG_BYTES) return failure('sealed_open_failed');\n\n const contentKey = await deriveSealedContentKey(input.scopeKey, decodeBase64Url(header.salt, 'salt'));\n let frame: Bytes;\n try {\n frame = await aesGcm('decrypt', contentKey, decodeBase64Url(header.nonce, 'nonce'), aadBytes(header, binding), input.ciphertext);\n } catch {\n return failure('sealed_open_failed');\n } finally {\n contentKey.fill(0);\n }\n try {\n const content = decodeSealedFrame(frame, header.paddedLength, input.maxContentLength);\n const plaintext = content === undefined ? undefined : parseCanonicalPlaintext(content);\n if (plaintext === undefined) return failure('sealed_open_failed');\n if ((await contentMacOf(input.scopeKey, header.category, binding, plaintext.text)) !== header.contentMac) {\n return failure('sealed_content_mac_mismatch');\n }\n return { ok: true, plaintext: plaintext.value, header };\n } finally {\n frame.fill(0);\n }\n}\n","/**\n * Member key custody (#654 design §7.1, §7.7; owner decisions 10c and §50a D).\n *\n * A member holds two P-256 keys. The ECDSA signing key is its identity: the\n * member id derives from its public key, so it never rotates, and a new\n * enrollment is a new member (§7.5). The ECDH KEM key opens scope key\n * packages and rotates by epoch.\n *\n * `MemberKeyStore` is the port each member's custody implements. The browser\n * keeps non-extractable `CryptoKey`s (10c). A device keeps the private JWKs in\n * its OS credential store and imports them non-extractable for each use\n * (§7.7). The device record below is that stored form: one canonical JSON\n * text, so every read is one coherent snapshot of both keys.\n *\n * `openMemberKeyRecord` proves each private scalar against its stored public\n * point (an ECDSA sign and verify, an ECDH round trip), so a record whose\n * scalar was swapped opens nothing. It never throws for hostile input.\n *\n * KEM rotation has two steps, in the order of §7.5 (#654 E2d-5).\n * `beginMemberKemRotation` stores the next KEM key at `kemEpoch + 1` beside\n * the current one. The member registers its public key and re-wraps its scope\n * keys to it, and only then does `finishMemberKemRotation` make it current\n * and drop the old private key. A crash in between loses nothing, and the\n * next process resumes the same rotation.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson } from '../attestation';\nimport { safeParseTotal } from '../total-parse';\nimport { webCryptoSubtle, type WebCryptoKey } from '../webcrypto';\nimport { P256PublicJwkSchema, base64UrlBytes, invalidInput, randomBytes, type P256PublicJwk } from './primitives';\n\nexport const MEMBER_KEY_RECORD_VERSION = 1;\n\n/**\n * Whose keys a store holds. A device member's binding names its SDK device\n * id; a client member's has none, as in its bundle.\n */\nexport interface MemberKeyBinding {\n readonly tenantId: string;\n readonly deviceId?: string;\n}\n\nexport interface MemberKeys {\n readonly binding: MemberKeyBinding;\n /** Signs chain entries and key packages. The private key is not extractable. */\n readonly signing: { readonly publicJwk: P256PublicJwk; readonly privateKey: WebCryptoKey };\n /** Opens key packages. The private key is not extractable. `epoch` starts at 1. */\n readonly kem: MemberKemKey;\n /** The KEM key of a rotation that has begun and not finished, at `kem.epoch + 1`. */\n readonly nextKem?: MemberKemKey;\n}\n\nexport interface MemberKemKey {\n readonly epoch: number;\n readonly publicJwk: P256PublicJwk;\n readonly privateKey: WebCryptoKey;\n}\n\n/** The custody port of one member's keys. Each store expects one writer. */\nexport interface MemberKeyStore {\n /** The keys bound to `binding`, or `undefined` when the store holds none for it. A malformed record throws. */\n load(binding: MemberKeyBinding): Promise<MemberKeys | undefined>;\n /** The keys bound to `binding`. A store that holds none for it creates new ones, which replace any other binding's keys. */\n loadOrCreate(binding: MemberKeyBinding): Promise<MemberKeys>;\n}\n\nconst PrivateJwkSchema = z.strictObject({\n kty: z.literal('EC'),\n crv: z.literal('P-256'),\n x: base64UrlBytes(32),\n y: base64UrlBytes(32),\n d: base64UrlBytes(32),\n});\ntype PrivateJwk = z.infer<typeof PrivateJwkSchema>;\n\nconst KemEpochSchema = z.number().int().positive().max(Number.MAX_SAFE_INTEGER);\n\nconst MemberKeyRecordV1Schema = z\n .strictObject({\n v: z.literal(MEMBER_KEY_RECORD_VERSION),\n tenantId: z.string().min(1),\n deviceId: z.string().min(1).optional(),\n signingJwk: PrivateJwkSchema,\n kemEpoch: KemEpochSchema,\n kemJwk: PrivateJwkSchema,\n nextKem: z.strictObject({ epoch: KemEpochSchema, jwk: PrivateJwkSchema }).optional(),\n })\n .refine((record) => record.nextKem === undefined || record.nextKem.epoch === record.kemEpoch + 1);\ntype MemberKeyRecordV1 = z.infer<typeof MemberKeyRecordV1Schema>;\n\nconst BindingSchema = z.object({ tenantId: z.string().min(1), deviceId: z.string().min(1).optional() });\n\n/** JWK export and ECDSA verify, which core's public `WebCryptoSubtle` does not declare; the same runtime object. */\ninterface KeySubtle {\n generateKey(algorithm: object, extractable: boolean, usages: string[]): Promise<{ publicKey: WebCryptoKey; privateKey: WebCryptoKey }>;\n exportKey(format: 'jwk', key: WebCryptoKey): Promise<{ readonly [field: string]: unknown }>;\n importKey(format: 'jwk', keyData: object, algorithm: object, extractable: boolean, usages: string[]): Promise<WebCryptoKey>;\n sign(algorithm: object, key: WebCryptoKey, data: Uint8Array): Promise<ArrayBuffer>;\n verify(algorithm: object, key: WebCryptoKey, signature: ArrayBuffer, data: Uint8Array): Promise<boolean>;\n deriveBits(algorithm: object, baseKey: WebCryptoKey, length: number): Promise<ArrayBuffer>;\n}\n\nfunction keySubtle(): KeySubtle {\n return webCryptoSubtle() as unknown as KeySubtle;\n}\n\nconst ECDSA_P256 = { name: 'ECDSA', namedCurve: 'P-256' } as const;\nconst ECDSA_SHA256 = { name: 'ECDSA', hash: 'SHA-256' } as const;\nconst ECDH_P256 = { name: 'ECDH', namedCurve: 'P-256' } as const;\n\nasync function generatePrivateJwk(algorithm: object, usages: string[]): Promise<PrivateJwk> {\n const pair = await keySubtle().generateKey(algorithm, true, usages);\n const { kty, crv, x, y, d } = await keySubtle().exportKey('jwk', pair.privateKey);\n return PrivateJwkSchema.parse({ kty, crv, x, y, d });\n}\n\n/**\n * A new member's record for `binding`: a fresh signing key and a fresh KEM\n * key at epoch 1, as one canonical JSON text. The text holds both private\n * scalars; only the member's own custody stores it.\n */\nexport async function generateMemberKeyRecord(binding: MemberKeyBinding): Promise<string> {\n const parsed = safeParseTotal(BindingSchema, binding);\n if (!parsed.success) throw invalidInput('Member key binding is invalid');\n const { tenantId, deviceId } = parsed.data;\n return canonicalizeJson({\n v: MEMBER_KEY_RECORD_VERSION,\n tenantId,\n ...(deviceId === undefined ? {} : { deviceId }),\n signingJwk: await generatePrivateJwk(ECDSA_P256, ['sign', 'verify']),\n kemEpoch: 1,\n kemJwk: await generatePrivateJwk(ECDH_P256, ['deriveBits']),\n });\n}\n\nfunction publicJwkOf(jwk: PrivateJwk): P256PublicJwk {\n return P256PublicJwkSchema.parse({ kty: jwk.kty, crv: jwk.crv, x: jwk.x, y: jwk.y });\n}\n\nfunction bytesEqual(left: ArrayBuffer, right: ArrayBuffer): boolean {\n const a = new Uint8Array(left);\n const b = new Uint8Array(right);\n return a.length === b.length && a.every((byte, index) => byte === b[index]);\n}\n\nasync function importSigningKey(jwk: PrivateJwk): Promise<MemberKeys['signing']> {\n const subtle = keySubtle();\n const publicJwk = publicJwkOf(jwk);\n const privateKey = await subtle.importKey('jwk', { ...jwk, ext: false }, ECDSA_P256, false, ['sign']);\n const publicKey = await subtle.importKey('jwk', publicJwk, ECDSA_P256, true, ['verify']);\n const probe = randomBytes(32);\n if (!(await subtle.verify(ECDSA_SHA256, publicKey, await subtle.sign(ECDSA_SHA256, privateKey, probe), probe))) {\n throw new TypeError('signing scalar does not match its public point');\n }\n return { publicJwk, privateKey };\n}\n\nasync function importKemKey(jwk: PrivateJwk): Promise<Omit<MemberKemKey, 'epoch'>> {\n const subtle = keySubtle();\n const publicJwk = publicJwkOf(jwk);\n const privateKey = await subtle.importKey('jwk', { ...jwk, ext: false }, ECDH_P256, false, ['deriveBits']);\n const publicKey = await subtle.importKey('jwk', publicJwk, ECDH_P256, true, []);\n const probe = await subtle.generateKey(ECDH_P256, false, ['deriveBits']);\n const viaMember = await subtle.deriveBits({ name: 'ECDH', public: probe.publicKey }, privateKey, 256);\n const viaProbe = await subtle.deriveBits({ name: 'ECDH', public: publicKey }, probe.privateKey, 256);\n if (!bytesEqual(viaMember, viaProbe)) throw new TypeError('KEM scalar does not match its public point');\n return { publicJwk, privateKey };\n}\n\n/**\n * The keys of a stored record, imported non-extractable, or `undefined` when\n * the text is not a canonical v1 record, or a private scalar does not match\n * its public point. Never throws for hostile input.\n */\nexport async function openMemberKeyRecord(text: unknown): Promise<MemberKeys | undefined> {\n const record = parseRecord(text);\n if (record === undefined) return undefined;\n try {\n const signing = await importSigningKey(record.signingJwk);\n const kem = { epoch: record.kemEpoch, ...(await importKemKey(record.kemJwk)) };\n const binding = record.deviceId === undefined ? { tenantId: record.tenantId } : { tenantId: record.tenantId, deviceId: record.deviceId };\n if (record.nextKem === undefined) return { binding, signing, kem };\n return { binding, signing, kem, nextKem: { epoch: record.nextKem.epoch, ...(await importKemKey(record.nextKem.jwk)) } };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Begin a KEM rotation: the record with a new KEM key at `kemEpoch + 1`\n * beside the current one. A record whose rotation has begun comes back\n * unchanged, so a resumed rotation keeps its key. A record that is not\n * canonical v1 text throws.\n */\nexport async function beginMemberKemRotation(text: string): Promise<string> {\n const record = parseRecord(text);\n if (record === undefined) throw invalidInput('Member key record is invalid');\n if (record.nextKem !== undefined) return text;\n return canonicalizeJson({ ...record, nextKem: { epoch: record.kemEpoch + 1, jwk: await generatePrivateJwk(ECDH_P256, ['deriveBits']) } });\n}\n\n/**\n * Finish the KEM rotation to `epoch`: the next key becomes current, and the\n * old private key is gone from the record. A repeat after the rotation\n * finished comes back unchanged. Any other `epoch` returns `undefined`. A\n * record that is not canonical v1 text throws.\n */\nexport function finishMemberKemRotation(text: string, epoch: number): string | undefined {\n const record = parseRecord(text);\n if (record === undefined) throw invalidInput('Member key record is invalid');\n if (record.nextKem === undefined) return record.kemEpoch === epoch ? text : undefined;\n if (record.nextKem.epoch !== epoch) return undefined;\n const { nextKem, ...rest } = record;\n return canonicalizeJson({ ...rest, kemEpoch: nextKem.epoch, kemJwk: nextKem.jwk });\n}\n\n/** The record of canonical v1 text, or `undefined`. Never throws. */\nfunction parseRecord(text: unknown): MemberKeyRecordV1 | undefined {\n if (typeof text !== 'string') return undefined;\n try {\n const parsed = safeParseTotal(MemberKeyRecordV1Schema, JSON.parse(text));\n return parsed.success && canonicalizeJson(parsed.data) === text ? parsed.data : undefined;\n } catch {\n return undefined;\n }\n}\n","/**\n * Member fingerprints and the two-way approval code (#654 design §7.2, §7.8;\n * owner decision 10a).\n *\n * Fingerprint of one member:\n *\n * 1. `digest = SHA-256(MEMBER_FINGERPRINT_DOMAIN || canonicalJson({ v: 1, tenantId, signingKey: { x, y } }))`.\n * 2. Take the first 25 bytes as 5 groups of 5 bytes.\n * 3. Read each group as a big-endian integer, take it modulo 100000, and pad\n * it to 5 decimal digits.\n *\n * The result is 25 digits in 5 groups, about 83 bits. The KEM key is not in\n * the fingerprint; the bundle's `kemSig` binds it. So a KEM rotation keeps the\n * fingerprint.\n *\n * Approval code: approval is two-way. Both screens show the same 50 digits:\n * the two members' fingerprints, ordered by member id, in 10 groups of 5. The\n * approver signs `add` only after both sides confirm the same code, and the\n * new member pins the approver's signing key only after it confirms (11b).\n * A device's local approval command shows the same code.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJsonBytes } from '../attestation';\nimport { safeParseTotal } from '../total-parse';\nimport { deriveMemberId } from './member-chain';\nimport { P256PublicJwkSchema, concat, invalidInput, sha256, utf8, type P256PublicJwk } from './primitives';\n\nexport const MEMBER_FINGERPRINT_DOMAIN = 'byok-member-fingerprint-v1\\n';\n\nconst FINGERPRINT_GROUPS = 5;\nconst GROUP_BYTES = 5;\nconst GROUP_MODULUS = 100000n;\n\n/** The caller data, read once into plain values. */\nconst FingerprintInputSchema = z.object({ tenantId: z.string().min(1), signingPublicJwk: P256PublicJwkSchema });\n\nexport interface MemberFingerprintInput {\n readonly tenantId: string;\n readonly signingPublicJwk: P256PublicJwk;\n}\n\n/** The 25-digit fingerprint of one member, as 5 groups of 5 digits joined by single spaces. */\nexport async function memberFingerprint(input: MemberFingerprintInput): Promise<string> {\n return (await fingerprintGroups(input)).groups.join(' ');\n}\n\n/**\n * The 50-digit two-way approval code of two members of one tenant: their\n * fingerprints ordered by member id, as 10 groups of 5 digits joined by\n * single spaces. The order of the arguments does not matter.\n */\nexport async function memberApprovalCode(\n tenantId: string,\n first: P256PublicJwk,\n second: P256PublicJwk,\n): Promise<string> {\n const members = await Promise.all([first, second].map((signingPublicJwk) => fingerprintGroups({ tenantId, signingPublicJwk })));\n if (members[0]!.memberId === members[1]!.memberId) throw invalidInput('An approval code needs two different members');\n members.sort((a, b) => (a.memberId < b.memberId ? -1 : 1));\n return members.flatMap((member) => member.groups).join(' ');\n}\n\n/** The member id and the 5 fingerprint groups of one member. */\nasync function fingerprintGroups(input: MemberFingerprintInput): Promise<{ memberId: string; groups: string[] }> {\n const parsed = safeParseTotal(FingerprintInputSchema, input);\n if (!parsed.success) throw invalidInput('Member fingerprint needs a tenant id and a P-256 signing key');\n const { tenantId, signingPublicJwk } = parsed.data;\n // deriveMemberId checks that the key is a point on P-256.\n const memberId = await deriveMemberId(signingPublicJwk);\n const digest = await sha256(\n concat(\n utf8(MEMBER_FINGERPRINT_DOMAIN),\n canonicalizeJsonBytes({ v: 1, tenantId, signingKey: { x: signingPublicJwk.x, y: signingPublicJwk.y } }),\n ),\n );\n const groups: string[] = [];\n for (let group = 0; group < FINGERPRINT_GROUPS; group += 1) {\n let value = 0n;\n for (const byte of digest.subarray(group * GROUP_BYTES, (group + 1) * GROUP_BYTES)) value = (value << 8n) | BigInt(byte);\n groups.push((value % GROUP_MODULUS).toString().padStart(5, '0'));\n }\n return { memberId, groups };\n}\n","/**\n * The pairing verification secret `pv` (#654 design §7.2, D2).\n *\n * The client generates `pv` when it shows a pairing code, and shows\n * `<pairing code>.<pv>`. The user gives that string to the device. The device\n * sends only the pairing code to the Host and keeps `pv`. The Host never sees\n * `pv`, so it cannot replace a member public key during pairing.\n *\n * Text form: RFC 4648 base32 of the 16 bytes, without padding. That is 26\n * characters. The encoder writes upper case. The decoder also accepts lower\n * case, because a person may type the string. The two unused low bits of the\n * last character must be zero, so one value has one upper-case text form.\n *\n * The parser splits on the LAST `.`, because base32 has no `.` and a pairing\n * code may contain one. It requires `pv`: the daemon decides from its own\n * configuration that a pairing needs `pv`, and never infers it from the text.\n *\n * The two pairing MACs (§7.2 steps 3 and 4) key HMAC-SHA-256 with `pv`. The\n * design writes their inputs with `||`. Here each input is a domain tag and\n * the canonical JSON of named fields, so field boundaries are unambiguous and\n * a device MAC never verifies as a client MAC.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJsonBytes } from '../attestation';\nimport { CONTENT_HASH_PATTERN } from '../blob';\nimport { safeParseTotal } from '../total-parse';\nimport { webCryptoSubtle, type WebCryptoKey } from '../webcrypto';\nimport type { MemberKeyBundleV1 } from './member-bundle';\nimport { MemberKeyBundleV1Schema } from './member-bundle';\nimport {\n base64UrlBytes,\n concat,\n copy,\n decodeBase64Url,\n encodeBase64Url,\n hmacSha256,\n invalidInput,\n randomBytes,\n utf8,\n type Bytes,\n} from './primitives';\n\nexport const PAIRING_VERIFICATION_SECRET_BYTES = 16;\nexport const PAIRING_VERIFICATION_TEXT_LENGTH = 26;\n\nconst BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n// Checked on the raw text, before upper-casing: Unicode case mapping turns\n// some non-ASCII characters into ASCII letters (`ſ` to `S`, `ff` to `FF`).\nconst PV_TEXT_PATTERN = /^[A-Za-z2-7]{26}$/u;\n\n/** 128 fresh CSPRNG bits. */\nexport function generatePairingVerificationSecret(): Bytes {\n return randomBytes(PAIRING_VERIFICATION_SECRET_BYTES);\n}\n\nexport function encodePairingVerificationSecret(pv: Uint8Array): string {\n if (pv.byteLength !== PAIRING_VERIFICATION_SECRET_BYTES) {\n throw invalidInput(`Pairing verification secret must be ${PAIRING_VERIFICATION_SECRET_BYTES} bytes`);\n }\n let out = '';\n let buffer = 0;\n let bits = 0;\n for (const byte of pv) {\n buffer = (buffer << 8) | byte;\n bits += 8;\n while (bits >= 5) {\n bits -= 5;\n out += BASE32_ALPHABET[(buffer >>> bits) & 31];\n }\n buffer &= (1 << bits) - 1;\n }\n return out + BASE32_ALPHABET[(buffer << (5 - bits)) & 31];\n}\n\nexport function decodePairingVerificationSecret(text: string): Bytes {\n if (!PV_TEXT_PATTERN.test(text)) {\n throw invalidInput(`Pairing verification secret must be ${PAIRING_VERIFICATION_TEXT_LENGTH} base32 characters`);\n }\n const upper = text.toUpperCase();\n const out = new Uint8Array(PAIRING_VERIFICATION_SECRET_BYTES);\n let buffer = 0;\n let bits = 0;\n let index = 0;\n for (const char of upper) {\n buffer = (buffer << 5) | BASE32_ALPHABET.indexOf(char);\n bits += 5;\n if (bits >= 8) {\n bits -= 8;\n out[index++] = (buffer >>> bits) & 0xff;\n }\n buffer &= (1 << bits) - 1;\n }\n if (buffer !== 0) throw invalidInput('Pairing verification secret has nonzero trailing bits');\n return out as Bytes;\n}\n\n/** `<pairingCode>.<pv>`, the string the client shows and the user gives to the device. */\nexport function formatPairingInput(pairingCode: string, pv: Uint8Array): string {\n if (pairingCode.length === 0) throw invalidInput('Pairing code must not be empty');\n return `${pairingCode}.${encodePairingVerificationSecret(pv)}`;\n}\n\nexport interface PairingInput {\n /** The only part the device sends to the Host. */\n readonly pairingCode: string;\n /** Kept on the device; never sent to the Host. */\n readonly pv: Bytes;\n}\n\n/** Split `<pairingCode>.<pv>` on the last `.`. Both parts are required. */\nexport function parsePairingInput(text: string): PairingInput {\n const dot = text.lastIndexOf('.');\n if (dot <= 0) throw invalidInput('Pairing input must be <pairing code>.<verification secret>');\n return { pairingCode: text.slice(0, dot), pv: decodePairingVerificationSecret(text.slice(dot + 1)) };\n}\n\n/** Domain tag of the MAC the device sends: step 3, `HMAC(pv, device bundle, tenantId, deviceId)`. */\nexport const DEVICE_PAIRING_MAC_DOMAIN = 'byok-pairing-device-mac-v1\\n';\n/** Domain tag of the MAC the client sends: step 4, `HMAC(pv, client bundle, chain head)`. */\nexport const CLIENT_PAIRING_MAC_DOMAIN = 'byok-pairing-client-mac-v1\\n';\n\n/** A pairing MAC on the wire: base64url of the 32-byte HMAC-SHA-256 tag. */\nconst PairingMacSchema = base64UrlBytes(32);\n\nexport interface DevicePairingMacInput {\n readonly tenantId: string;\n readonly deviceId: string;\n /** The device's own bundle. Its `deviceId` must equal `deviceId`. */\n readonly member: MemberKeyBundleV1;\n}\n\nexport interface ClientPairingMacInput {\n /** The client's own bundle. A client bundle has no `deviceId`. */\n readonly member: MemberKeyBundleV1;\n /** The chain head after the client signed `add(device)`. */\n readonly chainHead: { readonly seq: number; readonly hash: string };\n}\n\nconst ChainHeadSchema = z.strictObject({\n seq: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n hash: z.string().regex(CONTENT_HASH_PATTERN),\n});\n\n/** The caller data of the two MAC inputs, read once into plain values. */\nconst DeviceMacInputSchema = z.object({ tenantId: z.string().min(1), deviceId: z.string().min(1), member: MemberKeyBundleV1Schema });\nconst ClientMacInputSchema = z.object({ member: MemberKeyBundleV1Schema, chainHead: ChainHeadSchema });\n\nfunction devicePairingMacInput(input: DevicePairingMacInput): Bytes {\n const parsed = safeParseTotal(DeviceMacInputSchema, input);\n if (!parsed.success || parsed.data.member.deviceId !== parsed.data.deviceId) {\n throw invalidInput('Device pairing MAC input must name the device member\\'s own device id');\n }\n const { tenantId, deviceId, member } = parsed.data;\n return concat(utf8(DEVICE_PAIRING_MAC_DOMAIN), canonicalizeJsonBytes({ tenantId, deviceId, member }));\n}\n\nfunction clientPairingMacInput(input: ClientPairingMacInput): Bytes {\n const parsed = safeParseTotal(ClientMacInputSchema, input);\n if (!parsed.success || parsed.data.member.deviceId !== undefined) {\n throw invalidInput('Client pairing MAC input must hold a client member and a chain head');\n }\n const { member, chainHead } = parsed.data;\n return concat(utf8(CLIENT_PAIRING_MAC_DOMAIN), canonicalizeJsonBytes({ member, chainHead: { seq: chainHead.seq, hash: chainHead.hash } }));\n}\n\nfunction checkPv(pv: Uint8Array): void {\n if (pv.byteLength !== PAIRING_VERIFICATION_SECRET_BYTES) {\n throw invalidInput(`Pairing verification secret must be ${PAIRING_VERIFICATION_SECRET_BYTES} bytes`);\n }\n}\n\nexport async function computeDevicePairingMac(pv: Uint8Array, input: DevicePairingMacInput): Promise<string> {\n checkPv(pv);\n return encodeBase64Url(await hmacSha256(pv, devicePairingMacInput(input)));\n}\n\nexport async function computeClientPairingMac(pv: Uint8Array, input: ClientPairingMacInput): Promise<string> {\n checkPv(pv);\n return encodeBase64Url(await hmacSha256(pv, clientPairingMacInput(input)));\n}\n\n/**\n * Check a received device MAC. Parse the received bundle with\n * `parseMemberKeyBundle` first. Returns `false` for a wrong or malformed MAC,\n * or a bundle that does not name `deviceId`. Only a malformed `pv` throws.\n */\nexport async function verifyDevicePairingMac(pv: Uint8Array, input: DevicePairingMacInput, mac: unknown): Promise<boolean> {\n checkPv(pv);\n return hmacVerify(pv, () => devicePairingMacInput(input), mac);\n}\n\n/**\n * Check a received client MAC. Parse the received bundle with\n * `parseMemberKeyBundle` first. Returns `false` for a wrong or malformed MAC,\n * a device bundle, or a malformed chain head. Only a malformed `pv` throws.\n */\nexport async function verifyClientPairingMac(pv: Uint8Array, input: ClientPairingMacInput, mac: unknown): Promise<boolean> {\n checkPv(pv);\n return hmacVerify(pv, () => clientPairingMacInput(input), mac);\n}\n\n/**\n * WebCrypto HMAC verify compares in constant time. Core's public\n * `WebCryptoSubtle` interface does not declare `verify`, so this module types\n * the same runtime object locally, as `primitives.ts` does for ECDSA.\n */\ninterface HmacVerifySubtle {\n importKey(format: 'raw', keyData: Bytes, algorithm: object, extractable: boolean, usages: string[]): Promise<WebCryptoKey>;\n verify(algorithm: string, key: WebCryptoKey, signature: Bytes, data: Bytes): Promise<boolean>;\n}\n\nasync function hmacVerify(key: Uint8Array, buildData: () => Bytes, mac: unknown): Promise<boolean> {\n const parsed = safeParseTotal(PairingMacSchema, mac);\n if (!parsed.success) return false;\n let data: Bytes;\n try {\n data = buildData();\n } catch {\n return false;\n }\n const subtle = webCryptoSubtle() as unknown as HmacVerifySubtle;\n const hmacKey = await subtle.importKey('raw', copy(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);\n return subtle.verify('HMAC', hmacKey, decodeBase64Url(parsed.data, 'mac'), data);\n}\n","/**\n * Member chain walk (#654 design §7.3, §7.4, §7.5, §11.2, E2b; owner\n * decisions 11a and 11b).\n *\n * `applyMemberChainEntries` checks entries forward from a state and returns\n * the new state. Each entry must:\n *\n * - be the next entry: same tenant, `seq = head.seq + 1`, `prev = head.hash`\n * (from the empty state: `seq = 1`, `prev = null`);\n * - be signed by a current member (an `add`ed member that is not removed), or\n * be the genesis entry (11a, below);\n * - have the subject shape and the rule of its op (below);\n * - for `scope-policy` and `shred`, after the subject rules, be signed by a\n * member of the scope (below).\n *\n * One bad entry rejects the whole batch. The caller's state does not change.\n *\n * Genesis (11a): from the empty state only, the first entry is a self-signed\n * `add`: `subject.member.memberId === signer`, verified with the subject's\n * own signing key. Self-signing proves only that the member holds the key.\n * Trust comes from the anchor (11b, `verifyMemberChainFromAnchor`). An active\n * Host can write a false first entry first; that only denies service.\n *\n * Precondition (D10, #655 D-I2): one tenant is one user. v1 has no per-user\n * permissions, so any current member may sign `add` and `remove`. A Host\n * that maps two users to one tenant breaks this: one user's client could\n * change the other user's devices.\n *\n * Scope signers (owner batch §50f A): a `scope-policy` or `shred` of an\n * existing scope must be signed by a member in that scope's current policy.\n * The first `scope-policy` of a new scope must be signed by a member in its\n * own member list. Another signer fails with `member_chain_signer_invalid`.\n * So a member cannot change or shred, on the chain, a scope it is not in.\n * The rule does not cover two cases (design §7.9):\n *\n * - The Host deletes a scope's key packages on any well-shaped `shred` and\n * does not check the signature (owner batch §50g). That deletion still\n * depends on the other members being honest.\n * - The first member that creates a scope id takes it. E2d confirms a\n * scope's current policy before it seals to the scope.\n *\n * When every member of a scope's current policy has been removed, nobody can\n * update or shred that scope again (design §7.9).\n *\n * Op rules:\n *\n * - `add` `{ member }`: a valid bundle (`parseMemberKeyBundle`) of a member\n * that is not current and was never removed. A removed member id is final;\n * a re-paired device is a new member (§7.5).\n * - `remove` `{ memberId }`: a current member. A member may remove itself,\n * but the last member may not: the member set never becomes empty after\n * genesis (owner decision 14A).\n * - `rotate` `{ memberId, kemPublicJwk, kemEpoch, kemSig }`: signed by that\n * member itself; `kemEpoch` is its current KEM epoch + 1; the KEM key is\n * not the current one; `kemSig` is the member's signature over the new KEM\n * key (10a).\n * - `scope-policy` `{ scopeId, categories, members }`: categories in the\n * order of `SEALED_CATEGORIES`, no repeats; members sorted, no repeats,\n * each a current member (§7.4); the scope is not shredded.\n * - `shred` `{ scopeId }`: a scope with a policy that is not shredded. After\n * it, no `scope-policy` for that scope is valid (§11.2).\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson, type JsonObject } from '../attestation';\nimport { safeParseTotal } from '../total-parse';\nimport {\n KemEpochSchema,\n KemSigSchema,\n parseMemberKeyBundle,\n verifyMemberKem,\n type MemberKeyBundleV1,\n} from './member-bundle';\nimport { MEMBER_ID_PATTERN, deriveMemberId, verifyMemberChainEntry, type MemberChainEntryV1 } from './member-chain';\nimport { P256PublicJwkSchema, type P256PublicJwk } from './primitives';\nimport { SEALED_CATEGORIES, type SealedCategory } from './sealed-content';\n\nexport interface MemberChainScope {\n readonly categories: readonly SealedCategory[];\n /** Member ids from the latest `scope-policy` entry, sorted. Some may be removed since. */\n readonly members: readonly string[];\n /** `seq` of that entry. */\n readonly policySeq: number;\n}\n\nexport interface MemberChainHead {\n readonly seq: number;\n readonly hash: string;\n}\n\nexport interface MemberChainState {\n readonly tenantId: string;\n /** `null` before the genesis entry. */\n readonly head: MemberChainHead | null;\n /** Current members by member id, with their current KEM key. */\n readonly members: ReadonlyMap<string, MemberKeyBundleV1>;\n readonly removed: ReadonlySet<string>;\n readonly scopes: ReadonlyMap<string, MemberChainScope>;\n readonly shredded: ReadonlySet<string>;\n}\n\nexport type MemberChainWalkFailure =\n | 'member_chain_entry_invalid'\n | 'member_chain_link_invalid'\n | 'member_chain_signer_invalid'\n | 'member_chain_signature_invalid'\n | 'member_chain_subject_invalid';\n\nexport type MemberChainWalkResult =\n | { readonly ok: true; readonly state: MemberChainState }\n | { readonly ok: false; readonly reason: MemberChainWalkFailure; readonly index: number };\n\nconst MemberIdSchema = z.string().regex(MEMBER_ID_PATTERN);\nconst ScopeIdSchema = z.string().min(1);\n\nconst AddSubjectSchema = z.strictObject({ member: z.unknown() });\nconst RemoveSubjectSchema = z.strictObject({ memberId: MemberIdSchema });\nconst RotateSubjectSchema = z.strictObject({\n memberId: MemberIdSchema,\n kemPublicJwk: P256PublicJwkSchema,\n kemEpoch: KemEpochSchema,\n kemSig: KemSigSchema,\n});\nconst ScopePolicySubjectSchema = z.strictObject({\n scopeId: ScopeIdSchema,\n categories: z.array(z.enum(SEALED_CATEGORIES)).min(1),\n members: z.array(MemberIdSchema).min(1),\n});\nconst ShredSubjectSchema = z.strictObject({ scopeId: ScopeIdSchema });\nconst SignerSchema = z.object({ signer: MemberIdSchema });\nconst GenesisSchema = z.object({ op: z.literal('add'), subject: AddSubjectSchema });\nconst HeadSchema = z.object({ seq: z.number(), hash: z.string() });\nconst EntriesSchema = z.array(z.unknown());\n/** The caller data of the anchor check, read once. `self` and `authenticatedHead` are parsed after this read. */\nconst AnchorInputSchema = z.object({\n tenantId: z.string(),\n entries: EntriesSchema,\n self: z.unknown(),\n approverSigningPublicJwk: P256PublicJwkSchema,\n authenticatedHead: z.unknown().optional(),\n});\n\n/** The state before the genesis entry of `tenantId`'s chain. */\nexport function emptyMemberChainState(tenantId: string): MemberChainState {\n return { tenantId, head: null, members: new Map(), removed: new Set(), scopes: new Map(), shredded: new Set() };\n}\n\n/** The latest policy's members that are still current: the members that get key packages for the scope. */\nexport function memberChainScopeRecipients(state: MemberChainState, scopeId: string): readonly MemberKeyBundleV1[] {\n const scope = state.scopes.get(scopeId);\n if (scope === undefined) return [];\n return scope.members.flatMap((memberId) => {\n const member = state.members.get(memberId);\n return member === undefined ? [] : [member];\n });\n}\n\n/** Apply `entries` in order after `state`. Never throws for hostile entries. */\nexport async function applyMemberChainEntries(state: MemberChainState, entries: readonly unknown[]): Promise<MemberChainWalkResult> {\n const list = safeParseTotal(EntriesSchema, entries);\n if (!list.success) return { ok: false, reason: 'member_chain_entry_invalid', index: 0 };\n const result = await walk(state, list.data, () => false);\n return result.ok ? { ok: true, state: result.state } : result;\n}\n\n/** The genesis signer: the subject of a self-signed `add`, only from the empty state (11a). */\nasync function genesisSigner(state: WalkState, raw: unknown, signer: string): Promise<MemberKeyBundleV1 | undefined> {\n if (state.head !== null || state.members.size > 0) return undefined;\n const entry = safeParseTotal(GenesisSchema, raw);\n const member = entry.success ? await parseMemberKeyBundle(entry.data.subject.member) : undefined;\n return member !== undefined && member.memberId === signer ? member : undefined;\n}\n\ninterface WalkState {\n tenantId: string;\n head: MemberChainHead | null;\n members: Map<string, MemberKeyBundleV1>;\n removed: Set<string>;\n scopes: Map<string, MemberChainScope>;\n shredded: Set<string>;\n}\n\n/** The first entry that `mark` accepted: its index in the batch, its `seq` and its entry hash. */\ninterface MarkedEntry {\n readonly index: number;\n readonly seq: number;\n readonly hash: string;\n}\n\ntype WalkOutcome =\n | { readonly ok: true; readonly state: MemberChainState; readonly marked: MarkedEntry | undefined }\n | { readonly ok: false; readonly reason: MemberChainWalkFailure; readonly index: number };\n\n/**\n * The walk. `mark` sees each verified entry before it applies, with the\n * signer's key; the outcome reports the first index it marked.\n */\nasync function walk(\n state: MemberChainState,\n entries: readonly unknown[],\n mark: (entry: MemberChainEntryV1, signerKey: P256PublicJwk) => boolean,\n): Promise<WalkOutcome> {\n const next: WalkState = {\n tenantId: state.tenantId,\n head: state.head,\n members: new Map(state.members),\n removed: new Set(state.removed),\n scopes: new Map(state.scopes),\n shredded: new Set(state.shredded),\n };\n let marked: MarkedEntry | undefined;\n for (const [index, raw] of entries.entries()) {\n const signer = safeParseTotal(SignerSchema, raw);\n if (!signer.success) return { ok: false, reason: 'member_chain_entry_invalid', index };\n const signerBundle = next.members.get(signer.data.signer) ?? (await genesisSigner(next, raw, signer.data.signer));\n if (signerBundle === undefined) return { ok: false, reason: 'member_chain_signer_invalid', index };\n const verified = await verifyMemberChainEntry(raw, signerBundle.signingPublicJwk);\n if (!verified.ok) return { ok: false, reason: verified.reason, index };\n const entry = verified.entry;\n const expected = next.head === null ? { seq: 1, prev: null } : { seq: next.head.seq + 1, prev: next.head.hash };\n if (entry.tenantId !== next.tenantId || entry.seq !== expected.seq || entry.prev !== expected.prev) {\n return { ok: false, reason: 'member_chain_link_invalid', index };\n }\n if (marked === undefined && mark(entry, signerBundle.signingPublicJwk)) marked = { index, seq: entry.seq, hash: verified.hash };\n const applied = await applySubject(next, entry);\n if (applied !== true) return { ok: false, reason: applied === false ? 'member_chain_subject_invalid' : applied, index };\n next.head = { seq: entry.seq, hash: verified.hash };\n }\n return { ok: true, state: next, marked };\n}\n\n/**\n * `true` when the entry applied, `false` when its subject breaks the op rule.\n * A scope change with a valid subject from a member outside the scope (§50f\n * A) is `member_chain_signer_invalid`; the subject rules are checked first.\n */\nasync function applySubject(state: WalkState, entry: MemberChainEntryV1): Promise<boolean | 'member_chain_signer_invalid'> {\n switch (entry.op) {\n case 'add': {\n const subject = safeParseTotal(AddSubjectSchema, entry.subject);\n const member = subject.success ? await parseMemberKeyBundle(subject.data.member) : undefined;\n if (member === undefined || state.members.has(member.memberId) || state.removed.has(member.memberId)) return false;\n state.members.set(member.memberId, member);\n return true;\n }\n case 'remove': {\n const subject = safeParseTotal(RemoveSubjectSchema, entry.subject);\n if (!subject.success || !state.members.has(subject.data.memberId) || state.members.size === 1) return false;\n state.members.delete(subject.data.memberId);\n state.removed.add(subject.data.memberId);\n return true;\n }\n case 'rotate': {\n const subject = safeParseTotal(RotateSubjectSchema, entry.subject);\n if (!subject.success || subject.data.memberId !== entry.signer) return false;\n const member = state.members.get(subject.data.memberId);\n if (member === undefined || subject.data.kemEpoch !== member.kemEpoch + 1) return false;\n // A rotation to the current key keeps the old private key valid for new packages.\n const { kemPublicJwk } = subject.data;\n if (kemPublicJwk.x === member.kemPublicJwk.x && kemPublicJwk.y === member.kemPublicJwk.y) return false;\n if (!(await verifyMemberKem(member, subject.data))) return false;\n state.members.set(member.memberId, {\n ...member,\n kemPublicJwk: subject.data.kemPublicJwk,\n kemEpoch: subject.data.kemEpoch,\n kemSig: subject.data.kemSig,\n });\n return true;\n }\n case 'scope-policy': {\n const subject = safeParseTotal(ScopePolicySubjectSchema, entry.subject);\n if (!subject.success || state.shredded.has(subject.data.scopeId)) return false;\n const { categories, members } = subject.data;\n if (!strictlyIncreasing(categories.map((category) => SEALED_CATEGORIES.indexOf(category)))) return false;\n if (!strictlyIncreasing(members) || !members.every((memberId) => state.members.has(memberId))) return false;\n // An existing scope's current policy names who may change it; a new scope's own list names who may create it.\n if (!(state.scopes.get(subject.data.scopeId)?.members ?? members).includes(entry.signer)) return 'member_chain_signer_invalid';\n state.scopes.set(subject.data.scopeId, { categories, members, policySeq: entry.seq });\n return true;\n }\n case 'shred': {\n const subject = safeParseTotal(ShredSubjectSchema, entry.subject);\n if (!subject.success) return false;\n const scope = state.scopes.get(subject.data.scopeId);\n if (scope === undefined) return false;\n if (!scope.members.includes(entry.signer)) return 'member_chain_signer_invalid';\n state.scopes.delete(subject.data.scopeId);\n state.shredded.add(subject.data.scopeId);\n return true;\n }\n }\n}\n\n/** Sorted with no repeats. Member ids are ASCII, so `<` is code-point order. */\nfunction strictlyIncreasing<T extends number | string>(values: readonly T[]): boolean {\n return values.every((value, index) => index === 0 || values[index - 1]! < value);\n}\n\nexport type MemberChainAnchorFailure = MemberChainWalkFailure | 'member_chain_anchor_missing' | 'member_chain_head_mismatch';\n\nexport type MemberChainAnchorResult =\n | {\n readonly ok: true;\n readonly state: MemberChainState;\n /** `seq` of the anchor entry: the `add` of this member, signed by the pinned approver. */\n readonly anchorSeq: number;\n }\n | { readonly ok: false; readonly reason: MemberChainAnchorFailure; readonly index?: number };\n\nexport interface VerifyMemberChainFromAnchorInput {\n readonly tenantId: string;\n /** The whole chain, from the genesis entry (seq 1). */\n readonly entries: readonly unknown[];\n /** This member's own bundle, exactly as it was approved. */\n readonly self: MemberKeyBundleV1;\n /** The approver's signing key, pinned out of band: by the pv MAC or by the two-way fingerprint (10a). */\n readonly approverSigningPublicJwk: P256PublicJwk;\n /**\n * A chain head the approver authenticated out of band, for example the\n * head in the client pairing MAC. When given, it must be the anchor entry.\n */\n readonly authenticatedHead?: MemberChainHead;\n}\n\n/**\n * Verify a chain as a member that joined after the genesis entry (11b):\n *\n * 1. The member pins the approver's signing key K out of band.\n * 2. Entry E is an `add` whose `member` is byte-identical to `self` (KEM key\n * included) and whose signer is `memberId(K)`, verified with K.\n * 3. The walk from genesis reaches E, so E is on the chain path.\n * 4. The entries after E verify forward by signature.\n *\n * The first E counts; `self` can be added only once. Never throws for\n * hostile entries.\n */\nexport async function verifyMemberChainFromAnchor(input: VerifyMemberChainFromAnchorInput): Promise<MemberChainAnchorResult> {\n const parsed = safeParseTotal(AnchorInputSchema, input);\n if (!parsed.success) return { ok: false, reason: 'member_chain_anchor_missing' };\n const { tenantId, entries, self, approverSigningPublicJwk: approver, authenticatedHead } = parsed.data;\n let approverId: string;\n let selfText: string;\n try {\n approverId = await deriveMemberId(approver);\n selfText = canonicalizeJson(self as JsonObject);\n } catch {\n return { ok: false, reason: 'member_chain_anchor_missing' };\n }\n // The walk verified each entry with `signerKey`, so an entry that matches here verifies with the approver's key.\n const isAnchor = (entry: MemberChainEntryV1, signerKey: P256PublicJwk): boolean => {\n if (entry.op !== 'add' || entry.signer !== approverId || signerKey.x !== approver.x || signerKey.y !== approver.y) return false;\n try {\n return canonicalizeJson((entry.subject as { member?: unknown }).member as JsonObject) === selfText;\n } catch {\n return false;\n }\n };\n const outcome = await walk(emptyMemberChainState(tenantId), entries, isAnchor);\n if (!outcome.ok) return outcome;\n const anchor = outcome.marked;\n if (anchor === undefined) return { ok: false, reason: 'member_chain_anchor_missing' };\n if (authenticatedHead !== undefined) {\n const head = safeParseTotal(HeadSchema, authenticatedHead);\n if (!head.success || head.data.seq !== anchor.seq || head.data.hash !== anchor.hash) {\n return { ok: false, reason: 'member_chain_head_mismatch', index: anchor.index };\n }\n }\n return { ok: true, state: outcome.state, anchorSeq: anchor.seq };\n}\n"]}
|