← All field notes

Why we don't store what we sign

The case for a stateless issuance API, and what it costs us in convenience to get there.

Every credential Inflowra issues contains personal data: names, roles, licence classes, dates of birth. The conventional way to build an issuance service is to write all of that to a database on the way through — for audit trails, for reissuance, for support tickets. We decided not to, and that decision shapes almost everything else about the API.

The default is a database

Most issuance platforms persist the full credential payload. It feels safe: if a holder loses a credential you can reissue it, if a dispute comes up you can pull the record, and your dashboard can show every claim you've ever signed. But it also means the issuer becomes a honeypot. A breach of the platform is now a breach of every subject's data, and every compliance review of your product has to include ours.

What a stateless issuer looks like

A request to Inflowra carries the claims and the holder's DID. We validate the payload against your registered schema, sign it inside the key service, and return the credential in the response. The claims exist in our memory for the duration of the request — milliseconds — and are never written to disk. Our request logs record that an issuance happened, for which issuer, against which schema. They do not record what was in it.

What our logs actually contain
{
  "event": "credential.issued",
  "issuer": "did:web:acme.inflowra.io",
  "schema": "EmployeeCredential@1.2",
  "format": "vc+sd-jwt",
  "claims": "[redacted — never logged]",
  "timestamp": "2026-06-12T10:04:11Z"
}

What it costs us

Statelessness is not free, and it's worth being honest about the trade. We cannot reissue a lost credential — your system has to re-send the claims. We cannot show you claim-level history in a dashboard. And support gets harder: when something looks wrong with a credential, we can only reason from the schema and the signature, not from a stored copy.

  • No reissuance on our side — issuance is repeatable from your system of record instead.
  • Audit trails describe events, not payloads.
  • Debugging leans on schemas and verification results, not stored credentials.

Revocation without storage

The obvious question: how do you revoke something you didn't keep? With status lists. Every credential we issue can reference a BitstringStatusList entry — a single bit in a signed, hosted list. Flipping the bit revokes the credential without either of us needing the credential itself. The list holds no personal data, just positions.

The result is an issuer that is boring to attack and easy to put in front of a privacy review. What you send us is what gets signed — and then it's gone.