Docs / Core concepts

Certificates of Destruction: verifiable proof, not just a completion flag

A deletion that only your vendor can attest to isn't much of a compliance artifact. Chameleon issues a signed, independently verifiable certificate for every completed deletion — and chains it to every certificate that came before it, so the record can't be quietly edited after the fact.


More than a completion flag

A signed, chained, independently verifiable record

Once a deletion request reaches its final state, Chameleon generates a certificate: a signed token asserting exactly what was destroyed, how, and what was checked along the way. It's signed with an asymmetric key held in a cloud key-management service, so the private key never leaves secure key storage and the signature can be verified by anyone holding the corresponding public key — no trust in Chameleon's server required at verification time.

Each certificate also references the hash of the certificate issued immediately before it for that tenant, forming a chain. Tampering with, or quietly removing, an old certificate would break every link after it — the same tamper-evidence property a hash chain gives any append-only ledger.


What a certificate actually claims
Decoded certificate payload
{
  "userId": "usr_8f2a1c",
  "tenantId": "acme-corp",
  "deletedAt": "2026-08-27T14:02:11Z",
  "keyDestructionMethod": "DEK_ERASURE",
  "chainSequence": 47,
  "previousCertificateHash": "3a1f...c9e2",
  "lineageCoverage": {
    "destinationsChecked": ["bigquery:analytics", "hubspot"],
    "knownDestinationTypes": ["bigquery", "gcs", "hubspot", "salesforce"]
  },
  "ghostDataScanCoverage": "NOT_TRACKED",
  "kid": "projects/.../cryptoKeyVersions/3"
}

Verifying a certificate

No API key required — only public, unauthenticated data

Verification is deliberately self-contained: fetch the current signing keys, check the certificate's signature against them, then walk the chain backward one hash at a time until you reach the very first certificate ever issued for that tenant, verifying every link's signature along the way. None of this requires a credential — the chain-lookup endpoint is safe to leave unauthenticated because a certificate's hash is only ever known to someone who already holds a real, valid certificate.

This means a customer, an auditor, or a court doesn't have to take Chameleon's word for a deletion having happened — the proof is checkable independently, using only public endpoints.


GET/.well-known/jwks.jsonNone — public

Returns the current set of public keys used to verify certificate signatures, in standard JWKS format.

Response 200
{
  "keys": [
    {
      "kid": "projects/.../cryptoKeyVersions/3",
      "kty": "RSA",
      "alg": "PS256",
      "use": "sig",
      "n": "...",
      "e": "AQAB"
    }
  ]
}

GET/certificate-chain/by-hash/:hashNone — public

Returns the certificate whose own hash matches :hash — used to walk the chain backward one link at a time toward the genesis certificate.

NameInTypeRequiredDescription
hashpathstringYesThe sha256 hash of the certificate to look up.
  • Returns 404 if no certificate with that hash was ever issued.
  • Safe to leave unauthenticated: a hash is only knowable to someone who already holds a real chained certificate.

GET/certificate/:userIdRequired — bearer token

Returns the exact certificate already issued for a user's completed deletion — re-fetched, not re-signed, so repeated calls return byte-identical output.

NameInTypeRequiredDescription
userIdpathstringYesThe user whose deletion certificate you're retrieving.

Coverage claims are stated exactly, not implied

lineageCoverage lists precisely which destinations were checked and what destination types Chameleon knows about — never a claim that every system a user's data ever touched was inventoried. ghostDataScanCoverage is explicitly marked NOT_TRACKED whenever no scan ran, so an empty findings list is never mistaken for “confirmed scanned, nothing found.”


On the roadmap: independent long-term verifiability

Three hardening items are planned to make certificates independently verifiable even further into the future: an external mirror of the signing keys published somewhere outside Chameleon's own infrastructure, a published key-rotation and compromise-response policy, and RFC 3161 trusted timestamping from an independent third party so a certificate's issuance time doesn't rely solely on Chameleon's own clock. None of these are required for a certificate to be valid and verifiable today — they're the next layer of rigor on top of what's already in place.


FAQ

Common questions

Do I need an API key to verify a certificate?

No. Verification only touches public, unauthenticated endpoints — the signing-key set and the chain-lookup endpoint. An API key is only needed to fetch a certificate for a user by ID in the first place, not to verify one you already have.

What stops someone from forging a certificate?

The signature. Certificates are signed with an asymmetric key held in a cloud key-management service — the private key material never leaves secure key storage, so producing a valid signature requires access to that key, not just knowledge of a certificate's contents.

What happens to old certificates when the signing key rotates?

Rotation creates a new primary signing key; certificates already issued keep verifying correctly because previous key versions remain valid for verification even after a new one becomes primary for signing.


Keep reading

How resources get declared, and what feeds into a certificate's lineage coverage.