Crypto-shredding
Crypto-shredding is cryptographic erasure: destroying a scope's encryption key so every ciphertext it protects becomes unrecoverable, without deleting rows from an immutable audit chain. Caisson's field-crypto module requests KEK deletion through a scope tied to one tenant, never a shared key, and records the provider-proven deletion state without PII. A recoverable soft-delete receipt is not labeled permanent erasure.
In code
export async function cryptoShred(
provider: KmsKeyProvider,
request: CryptoShredRequest,
): Promise<CryptoShredReceipt> {
const req = parseStrict(cryptoShredRequestSchema, request);
const { shreddedThroughVersion, deletion } =
await provider.scheduleKeyDeletion(req.keyScopeId);
const auditPayload: JsonValue = {
event: ERASURE_CRYPTO_SHRED,
deletion,
method: SHRED_METHOD,
tenantId: req.tenantId,
subjectId: req.subjectId,
reason: req.reason,
occurredAt: req.occurredAt,
shreddedThroughVersion,
};
return { shreddedThroughVersion, deletion, auditPayload };
}How it holds
Refuses a shared scope, not just a tenant's own
The KMS port's scheduleKeyDeletion requires an explicit, non-empty keyId; the AWS driver throws rather than falling back to the configured default CMK (ADR-0197), so a per-tenant or per-subject shred can never reach past its own scope into another tenant's key material.
Selective because provisioning is per scope
KmsKeyProvider provisions one wrapped DEK version per tenant (or per subject, for a finer erasure grain), and scheduleKeyDeletion targets only that scope's KEK. Request-time abort budgets are not attached to destructive calls; the authorized host must persist the receipt and reconcile any pending provider state.
The audit record carries no PII
cryptoShred's payload holds only opaque ids, the legal reason, the request instant, the covered version, and the provider's deletion state, never the erased data itself. It can remain in the immutable WORM chain without recreating the protected plaintext or overstating a recoverable soft delete.
Fail-closed scope and provisioning checks run first
parseStrict rejects malformed or mismatched tenant/subject scopes, then KmsKeyProvider requires a durable current-version marker before scheduleKeyDeletion can reach the provider. Caller authorization and durable retry reconciliation remain explicit host responsibilities.