Proof-of-Deletion Certificate Runbook
When a right-to-be-forgotten request completes, Orbit can issue a signed proof-of-deletion certificate: the receipt a data subject or supervisory authority accepts as evidence that the erasure ran end-to-end. This runbook walks a compliance owner through the full operational sequence: triggering the erasure, watching it finalize, issuing the certificate, reading and verifying it, and handling the case where an erasure did not complete cleanly. The normative reference for every endpoint used here is Data Subject Access Requests. This page is the step-by-step runbook around the certificate itself. All endpoints below are rooted athttps://api.orbit.devotel.io/api/v1/compliance.
1. Why a proof of deletion matters
Article 17 obliges you to erase personal data when the right applies, and Article 12 obliges you to demonstrate to the data subject that you did. In practice the demonstration is two hops:- Orbit (your processor) shows you the erasure. The erasure
executor hard-deletes the subject’s rows across every subsystem,
anchors the deletion in the tamper-evident audit chain, and flips
the request to
executed. - You (the controller) show the certificate onward. The certificate packages that execution into a dated, signed, per-subsystem statement you can file in your privacy register and hand to the data subject or supervisory authority.
2. Trigger path
An erasure enters the queue through any of the three DSAR intake paths, all of which feed the same pipeline:- Operator-filed —
POST /compliance/dsarwithrequest_type: "delete", then the identity decisionPOST /compliance/dsar/{id}/verificationwith{ "decision": "verified" }(delete requests are higher-assurance and wait for this decision). - Public self-service portal — the subject files
deletethrough the two-factor OTP flow; the queued request arrives pre-verified. - WhatsApp — a contact tapping Delete my data in a
conversation maps to
request_type: "delete"automatically.
pending:
Transfer and finalize sequence
After cooling-off elapses, the executor claims the request and runs the transfer:pending → executing → executed
with terminal branches cancelled (operator cancel during
pending) and failed (see
section 6). The
executor ticks every five minutes; every subsystem delete (messages,
conversations, call logs and recordings, CDP events, consent
records, suppression and DNC rows, voiceprints, knowledge-base
documents, vector memory, and the contact row itself) commits in a
single transaction, then the executor writes the audit-chain anchor
and stamps executed_at. Poll the list until the row reads
executed:
executed can be certified. Anything earlier returns
409 with code ERASURE_NOT_EXECUTED, which is your signal that the
runbook is at the wrong step, not that issuance is broken.
3. Issue the certificate
RBAC — every erasure endpoint in this runbook, including
certificate issuance, requires an owner or admin API key.
Member-keyed calls are rejected before they reach the compliance
data.
GET /compliance/dsar/erasure-requests/{id}/certificate derives the
certificate on demand from the immutable executed row and its audit
anchor, and signs it with a detached HMAC-SHA256 tag. Nothing is
persisted, so issuing twice never creates contradictory artifacts
(see section 8).
200 OK:
4. Reading the artifact
5. Verifying the certificate
Two independent checks, in increasing order of strength: Audit-log cross-reference (yours to run). The certificate’saudit_log_id is a row in your organization’s audit chain with
action gdpr.erasure_executed; its resource_counts must match the
certificate’s records_erased.by_resource, and its timestamps must
match executed_at. Every issuance also appends a
compliance.dsar_erasure_certificate_issued row naming the
certificate_id, so your audit export shows who issued which
certificate and when. Pull the chain through your usual audit
export (audit export,
audit log guide) and compare. A certificate
whose anchor is missing or whose counts disagree with the chain
should be treated as altered or mis-cited.
Signature recompute (held by the signing key holder). The tag
is a self-signature by Devotel Orbit: the HMAC key is the Orbit
platform signing key, so a third party cannot recompute it
independently, exactly as with any processor-attested receipt. The
recipe is published so the computation is transparent and so the
platform can confirm a presented certificate in a regulatory
exchange:
- Canonicalise the
certificateobject with RFC 8785 (JCS) style rules: object keys sorted ascending, no insignificant whitespace. - Compute HMAC-SHA256 over the string
orbit.dsar.erasure-certificate.v1.<canonical-json>. - Base64url-encode and compare with
signature.valueusing a timing-safe equality check.
orbit.dsar.erasure-certificate.v1) is mixed into every tag, so a
valid certificate signature can never double as a valid tag on any
other Orbit-signed surface. A mismatched or malformed tag verifies
false; verification never fails open.
6. When the erasure did not complete cleanly
Read failures against the actual lifecycle. There is no separate partial-completion status: a request ispending,
executing, executed, cancelled, or failed, and exceptions on
an executed erasure surface as fields on the certificate, not as a
status.
Nothing half-deletes. Every subsystem delete for one contact
commits in a single transaction: either all of them commit or none
do. A crash or fault midway rolls the whole erasure back and the
executor retries on a later tick, up to three attempts. If the
request parks in failed, the list’s failure_reason names why:
a faulting execution, an interrupted execution whose retries were
exhausted, or a deletion that committed but whose audit-chain
anchor could not be written. A failed request cannot be
certified;
issuance returns 409 ERASURE_NOT_EXECUTED. Escalate a parked
request inside your statutory clock: the 30-day GDPR window keeps
running while the row waits.
Exceptions on an executed certificate. Because the transaction
is all-or-nothing, an executed erasure never has silently skipped
subsystem deletes, but it can carry honest flags:
- A
nullcount inrecords_erased.by_resourcemeans that subsystem’s table does not exist on your tenant. Nothing existed to purge; the certificate says so rather than pretending a count. - The external-store purge counters — spillover event blobs and encrypted call-recording blobs that could not be confirmed on that pass, or a null flag on the vector-memory, knowledge-base, or billing-metadata wipe — name stores Orbit could not yet attest. Orbit retries these on subsequent passes without rolling back the committed deletion; a non-zero failed counter is your cue to re-check the list before handing the certificate outward.
destination_propagation.failedorskippedentries mean a downstream destination rejected or was not configured for the fan-out. Re-run propagation per CDP erasure propagation, then issue the certificate again: the new artifact keeps the samecertificate_idand folds the updated trail under a freshissued_atand signature.
7. Presenting the certificate
In a regulator or customer conversation, present three things together:- The certificate JSON, verbatim, as issued. Note the
regulationentries that match the counterpart’s claim (GDPR Art. 17, CCPA §1798.105 / CPRA). - The audit-chain export for
audit_log_id, showing thegdpr.erasure_executedanchor and its per-resource counts. - Your cover note as controller: who requested, when, which
verification path proven identity, and the erasure window. The
certificate’s
requested_at,requested_by_user_id, andattempt_countsupply the facts; your privacy register supplies the legal basis.
8. Retention and erasure of the certificate itself
The certificate is not persisted: there is no certificate store to retain, rotate, or delete, and no stale-copy hazard on the platform side. Re-issuing at any time reproduces the samecertificate_id for the same execution, so citations never dangle.
What ages is the anchor, not the certificate. The erasure request
row and the audit chain follow your organization’s retention
posture (data retention policy).
While the anchor is retained you can re-issue and cross-reference
freely; after your retention window closes the anchor ages out and
the cross-reference path in section 5 narrows to the signature
check. The practical rule: issue and file the certificate into
your privacy register while the anchor is live, and treat the
filed copy as your record. Your own filed copies are yours to
retain or erase like any other privacy-register artifact,
including erasing them if a later DSAR demands the closure of the
underlying request’s paperwork.
Boundary: DSAR erasure vs CDP reverse propagation
DSAR erasure deletes what Orbit holds for the subject inside your tenant: the contact row, every linked subsystem, and the derived stores (recordings blobs, CDP spillover, vector memory). CDP reverse propagation is the separate, downstream leg that fans the same deletion out as delete or suppression calls to the CRM and marketing destinations you activated; its per-destination results are folded into the certificate’sdestination_propagation
section so one signed artifact attests both legs. The propagation
leg, its destinations, and its retry model are documented in
CDP erasure propagation; this
runbook covers issuing and presenting the artifact that closes
both legs.
Related
- Data Subject Access Requests (DSAR) — the normative reference for intake, verification, and the erasure endpoints.
- CDP erasure propagation — the downstream fan-out whose outcomes fold into the certificate.
- Audit export — pulling the chain your verification cross-reference reads from.
- Assembling a GDPR Posture End to End — where erasure closure sits in the full sequence.