Skip to main content

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.
This runbook describes Orbit’s platform controls. It is not legal advice. Whether a certificate discharges your obligations in a given proceeding depends on your jurisdiction and your role as controller or processor. Confirm with qualified counsel.
All endpoints below are rooted at https://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:
  1. 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.
  2. 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.
Without the second hop, your evidence is “the row is gone,” which a reviewer cannot inspect without access to your database. The certificate is the legible closure artifact: it names what was purged, when, under which request, and against which audit anchor, and it carries a detached signature so the artifact you present later is provably the one Orbit issued.

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/dsar with request_type: "delete", then the identity decision POST /compliance/dsar/{id}/verification with { "decision": "verified" } (delete requests are higher-assurance and wait for this decision).
  • Public self-service portal — the subject files delete through 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.
Once approved, the request’s erasure leg is tracked as its own resource with a cooling-off window (7 days by default) so a mistaken or disputed deletion can be cancelled while still 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:
Only a row in 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.
Issuance is a read, not a mutation: 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).
Expected result, 200 OK:
Save the response body verbatim. That JSON, untouched, is the artifact.

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’s audit_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:
  1. Canonicalise the certificate object with RFC 8785 (JCS) style rules: object keys sorted ascending, no insignificant whitespace.
  2. Compute HMAC-SHA256 over the string orbit.dsar.erasure-certificate.v1.<canonical-json>.
  3. Base64url-encode and compare with signature.value using a timing-safe equality check.
The domain-separation context (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 is pending, 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 null count in records_erased.by_resource means 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.failed or skipped entries 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 same certificate_id and folds the updated trail under a fresh issued_at and signature.
When a counterpart asks “did it really all go?”, the answer is the certificate plus its audit anchor: the certificate states the outcome, the anchor independently records it, and the two agree by construction.

7. Presenting the certificate

In a regulator or customer conversation, present three things together:
  1. The certificate JSON, verbatim, as issued. Note the regulation entries that match the counterpart’s claim (GDPR Art. 17, CCPA §1798.105 / CPRA).
  2. The audit-chain export for audit_log_id, showing the gdpr.erasure_executed anchor and its per-resource counts.
  3. 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, and attempt_count supply the facts; your privacy register supplies the legal basis.
Keep the posture honest: the certificate is a tenant-presented, platform-signed attestation. It is strong evidence that Orbit executed the erasure it records; whether that evidence discharges the obligation in your proceeding remains a determination for your counsel, consistent with Orbit’s tenant-owned compliance posture.

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 same certificate_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’s destination_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.