Quickstart

This walks through a hard delete, a deferred erasure under an RBI hold, and a Certificate of Erasure - framework-agnostic, no backend required.

1. Create an engine

The ErasureEngine owns an append-only, hash-chained AuditLog.

from dpdpstack import ErasureEngine, AuditLog, RetentionPolicy, Action, rbi_kyc, issue_certificate

engine = ErasureEngine(AuditLog())

2. Hard-delete on withdrawal

For an ordinary purpose, erasure is a hard delete. Your code does the actual deletion inside executor - the engine only decides and records (zero-egress).

engine.request_erasure(
    subject="user_42",
    policy=RetentionPolicy(purpose="marketing", action=Action.DELETE),
    reason="consent_withdrawn",
    executor=lambda action: my_delete_user(42),
)

KYC data is different: RBI mandates 5-year retention, so erasure is deferred, not refused - and the legal basis is recorded.

res = engine.request_erasure(
    subject="user_42",
    policy=rbi_kyc("kyc"),
    reason="consent_withdrawn",
)

print(res.status)        # "deferred"
print(res.legal_basis)   # "RBI KYC Master Direction (5 years)"
print(res.erase_after)   # date 5 years out - when it becomes erasable

When the hold lapses, the same engine erases automatically and records the release (erasure.dispatched / legal_hold_expired).

4. Issue a Certificate of Erasure

A certificate is built from the audit chain - verifiable proof of what happened.

cert = issue_certificate(engine.audit, "user_42", "kyc")
print(cert.status)           # "deferred"
print(cert.chain_verified)   # True - the audit chain still verifies

The certificate is tamper-evident on its own. Add an RS256 signature (the crypto extra) so anyone can verify it with your public key - see Certificates of Erasure.

Next