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),
)3. Defer under a legal hold
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 erasableWhen 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 verifiesThe certificate is tamper-evident on its own. Add an RS256 signature (the
cryptoextra) so anyone can verify it with your public key - see Certificates of Erasure.
Next
- How it works - the engine, audit chain, and anonymization.
- Django integration - run it against your models with
@pii.