import { type MemberKeyBundleV1 } from './member-bundle'; import { type P256PublicJwk } from './primitives'; import { type SealedCategory } from './sealed-content'; export interface MemberChainScope { readonly categories: readonly SealedCategory[]; /** Member ids from the latest `scope-policy` entry, sorted. Some may be removed since. */ readonly members: readonly string[]; /** `seq` of that entry. */ readonly policySeq: number; } export interface MemberChainHead { readonly seq: number; readonly hash: string; } export interface MemberChainState { readonly tenantId: string; /** `null` before the genesis entry. */ readonly head: MemberChainHead | null; /** Current members by member id, with their current KEM key. */ readonly members: ReadonlyMap; readonly removed: ReadonlySet; readonly scopes: ReadonlyMap; readonly shredded: ReadonlySet; } export type MemberChainWalkFailure = 'member_chain_entry_invalid' | 'member_chain_link_invalid' | 'member_chain_signer_invalid' | 'member_chain_signature_invalid' | 'member_chain_subject_invalid'; export type MemberChainWalkResult = { readonly ok: true; readonly state: MemberChainState; } | { readonly ok: false; readonly reason: MemberChainWalkFailure; readonly index: number; }; /** The state before the genesis entry of `tenantId`'s chain. */ export declare function emptyMemberChainState(tenantId: string): MemberChainState; /** The latest policy's members that are still current: the members that get key packages for the scope. */ export declare function memberChainScopeRecipients(state: MemberChainState, scopeId: string): readonly MemberKeyBundleV1[]; /** Apply `entries` in order after `state`. Never throws for hostile entries. */ export declare function applyMemberChainEntries(state: MemberChainState, entries: readonly unknown[]): Promise; export type MemberChainAnchorFailure = MemberChainWalkFailure | 'member_chain_anchor_missing' | 'member_chain_head_mismatch'; export type MemberChainAnchorResult = { readonly ok: true; readonly state: MemberChainState; /** `seq` of the anchor entry: the `add` of this member, signed by the pinned approver. */ readonly anchorSeq: number; } | { readonly ok: false; readonly reason: MemberChainAnchorFailure; readonly index?: number; }; export interface VerifyMemberChainFromAnchorInput { readonly tenantId: string; /** The whole chain, from the genesis entry (seq 1). */ readonly entries: readonly unknown[]; /** This member's own bundle, exactly as it was approved. */ readonly self: MemberKeyBundleV1; /** The approver's signing key, pinned out of band: by the pv MAC or by the two-way fingerprint (10a). */ readonly approverSigningPublicJwk: P256PublicJwk; /** * A chain head the approver authenticated out of band, for example the * head in the client pairing MAC. When given, it must be the anchor entry. */ readonly authenticatedHead?: MemberChainHead; } /** * Verify a chain as a member that joined after the genesis entry (11b): * * 1. The member pins the approver's signing key K out of band. * 2. Entry E is an `add` whose `member` is byte-identical to `self` (KEM key * included) and whose signer is `memberId(K)`, verified with K. * 3. The walk from genesis reaches E, so E is on the chain path. * 4. The entries after E verify forward by signature. * * The first E counts; `self` can be added only once. Never throws for * hostile entries. */ export declare function verifyMemberChainFromAnchor(input: VerifyMemberChainFromAnchorInput): Promise;