Menu QaldyDocs

The gate and write-only secrets

How a key you paste once is sealed so that nothing but the gate can open it, for one call, and why even a database dump yields nothing usable.

A connector needs a key: a Telegram bot token, a Sheets service account, an API key. Qaldy's rule is that the app never holds it, and nobody can read it back, including you.

What happens when you paste a key

  1. You paste the key once, on Connectors. The console shows Write-only afterwards, never the value.
  2. The API seals it with HPKE (RFC 9180) to the gate's public key, bound to your workspace and that connector, and stores only the ciphertext. The API holds the gate's public key and has no way to open what it sealed.
  3. When an app makes an allowed call, the gate opens the sealed key in memory, adds it to the upstream request, sends the call, scrubs the key out of the reply, and wipes its buffer.
  4. Nothing that appears in a log, an audit row or a trace carries the key. The gate records the route template (for example telegram/sendMessage), never the upstream URL or headers.

Because a sealed key is bound to its workspace and connector, a copy moved to another workspace does not open. For an HTTP API connection it is bound to the host too, so the control plane cannot be talked into sending your key to another address.

What this protects against

  • A database dump or backup leak yields ciphertext only.
  • A hostile or mistaken app cannot print a key, because it was never there.
  • A teammate with the wrong role cannot read a key: no screen and no API route returns one.
  • A key echoed back by the upstream is scrubbed from the reply before the app sees it.

What it does not protect against

  • A key you type into the console passes through the API for the length of one request, on its way to being sealed. A live compromise of the API at that moment sees it. The guarantee covers stored secrets.
  • The gate holds the unsealing key for the cell. It is one high-value target by design, kept away from the API and the database.
  • The service you call sees the key. That is how it authenticates you.

Rotating and removing

Replace the key seals a new one, and the old one keeps serving until the new one has been tried through the gate and works, so apps do not stop. Disconnect deletes the sealed key and tells you which apps will stop working. If you are unsure whether a key leaked, replace it at the provider and in Qaldy; there is no "reveal" to check against, by design. An admin can also record an expiry date for a reminder, and press the panic button to delete every sealed key of the workspace at once: see Replace a key, set an expiry, press the panic button.

What else the gate holds

The gate sits in front of every app, so it is also where two other promises are kept. It holds the spending cap: a workspace over its cap gets a calm page instead of a bill. And it holds the shield: per-person, per-address and per-app rate limits, a daily limit, and a flood detector, so a shared link in the wrong hands cannot run up a bill. Both survive an outage of Qaldy's API (see When the control plane is down).

The same idea for webhooks

A webhook that starts an automation has a signing secret. Because the party that checks a signature has to be able to read the secret, that one is different: the API can open it. It is stored encrypted under a key that is not in the database, shown once, never logged. See Webhooks and heartbeats.

The proofs that check these claims (C1 to C6 in the proof list) search the bundle, the isolate, every reply, every database column and every log for the bytes of a test key.

Type to search. Up and down to choose, Enter to open, Esc to close.