/** * Two-party withdrawal ceremony. * * The conservative counterpart to `unilateralWithdrawal`: a non-owner — * including a read-only `client`/`viewer` who cannot self-serve a deletion — * files a durable REQUEST; an owner/admin reviews it and either APPROVES * (extract-and-dispose under firm authority) or REJECTS it. Every step is * audited in the tamper-evident ledger. * * requester: vault.user.requestWithdrawal({ scope, disposition?, legalBasis? }) * owner: vault.user.listWithdrawalRequests() * vault.user.approveWithdrawal(requestId, { reKey }) → { bundle, snapshot? } * vault.user.rejectWithdrawal(requestId, { reason }) * * Requests live in the reserved `_user_withdrawal_requests` namespace. The * record body is plaintext metadata (collection names + disposition + legal * basis — none secret in this trust model; the owner sees the data anyway) and * carries NO passphrase: the re-key passphrase is supplied by the approver at * approval time and conveyed to the requester out-of-band, so no secret is * stored at rest. */ import type { Vault } from '../../kernel/vault.js'; import { NoydbError } from '../../kernel/errors.js'; import { type WithdrawResult } from './withdraw-accessible.js'; export declare const WITHDRAWAL_REQUESTS_COLLECTION = "_user_withdrawal_requests"; /** Raised when a request is missing, already decided, or expired. */ export declare class WithdrawalRequestError extends NoydbError { constructor(message: string); } export type WithdrawalRequestStatus = 'pending' | 'approved' | 'rejected'; export interface WithdrawalRequest { readonly requestId: string; readonly requester: string; readonly collections: readonly string[]; readonly disposition: 'delete' | 'freeze'; readonly legalBasis?: string; readonly status: WithdrawalRequestStatus; readonly requestedAt: string; readonly expiresAt?: string; readonly decidedAt?: string; readonly decidedBy?: string; readonly rejectReason?: string; readonly snapshotSha256?: string; } export interface RequestWithdrawalOptions { readonly scope?: { readonly collections?: readonly string[]; }; readonly disposition?: 'delete' | 'freeze'; readonly legalBasis?: string; /** Time-to-live in ms; after this the request can no longer be approved. */ readonly expiresInMs?: number; } export interface RequestWithdrawalResult { readonly requestId: string; readonly status: WithdrawalRequestStatus; readonly expiresAt?: string; } /** * Requester side. Files a durable request for the caller's accessible scope. * Gated by `user-request-withdrawal` (checked in the UserApi wrapper). */ export declare function requestWithdrawal(vault: Vault, opts?: RequestWithdrawalOptions): Promise; /** Owner side. List filed requests (optionally by status). */ export declare function listWithdrawalRequests(vault: Vault, opts?: { status?: WithdrawalRequestStatus; }): Promise; export interface ApproveWithdrawalOptions { /** Re-key the handed-back bundle to a passphrase the requester will use. */ readonly reKey?: { readonly passphrase: string; }; } /** * Owner side. Extract the requester's recorded scope under firm authority, * dispose of the source per the request's disposition, mark the request * approved, and return the re-keyed bundle to hand back. Gated by * `approve-user-withdrawal` (checked in the UserApi wrapper) + owner/admin role. */ export declare function approveWithdrawal(vault: Vault, requestId: string, opts?: ApproveWithdrawalOptions): Promise; export interface RejectWithdrawalOptions { readonly reason?: string; } /** Owner side. Decline a pending request (no data is touched). */ export declare function rejectWithdrawal(vault: Vault, requestId: string, opts?: RejectWithdrawalOptions): Promise;