Skip to main content

Encryption threat model

This page states plainly what the kc: encryption, vaults, and capability tokens defend against, where the trust boundaries are, and what is explicitly out of scope. Naming the residual risk is deliberate — it is how you evaluate whether the control fits your compliance posture.

Trust boundary

Plaintext exists only transiently, inside the KnoxCall control plane, during an encrypt or decrypt call. At rest, KnoxCall holds:
  • Ciphertext (kc: values, vault wrapped_value blobs) — useless without the key.
  • Wrapped keys — app private keys and tenant master keys, each wrapped under the layer above (see the key hierarchy).
In dual-custody vaults, KnoxCall holds no value at all — you keep the ciphertext.

What it defends against

Residual risk (out of scope, stated honestly)

  • Simultaneous compromise of the platform master key and the database (env-key mode). If an attacker obtains both MASTER_KEY_B64 and a DB dump at the same time, wrapped keys become unwrappable and plaintext is recoverable. Mitigations that raise this bar: run in KMS-unseal mode (the master key lives in AWS/GCP/Azure KMS, not on disk), adopt BYOK (the tenant master key is wrapped by your KMS, revocable by you), and — on the roadmap — run the unseal/crypto core inside a hardware enclave with remote attestation so even a KnoxCall operator cannot read plaintext.
  • A fully-authorised caller. Encryption does not stop a request that legitimately holds the key and the right data-role. Constrain that with client permissions, API-key scopes, and capability tokens.
  • Plaintext you send us in the clear. The /v1/encrypt request body contains plaintext over TLS. To keep plaintext off our servers entirely, encrypt in the browser against the tenant public key (the kc: format is designed for exactly this) and send only kc: values.
  • Endpoint compromise on your side. If your own server or browser is compromised at the moment it handles plaintext, that is outside KnoxCall’s boundary.

Compliance mapping

These are control mappings — which requirement each mechanism speaks to — not attestations KnoxCall holds. KnoxCall holds no PCI DSS attestation; see the trust page for current status.
  • Keeping values out of downstream systems — tokenize into a managed vault, or seal client-side (kc: + browser SDK), so your own services store a token rather than the value. Note the limit: the proxy path never returns the value to you, but a credential that can detokenize can also read it directly via GET /v1/vaults/:vault/tokens/:token, so the guarantee is about where the value flows, not about what that credential can reach.
  • HIPAA / GDPR — encrypt PHI/PII at the field level; use data-roles for residency (eu) and cryptographic erasure (whole-vault) for deletion requests.
  • Audit — every encrypt, decrypt, tokenize, capability-token mint/consume, and API-path detokenize lands in the tamper-evident audit log. Detokenization inside a proxy request is audited per request with a token count, not per value.

Verify it yourself

The cryptographic construction is published in full in the ciphertext spec. The kc: format is self-describing, so you can independently parse a ciphertext, confirm the curve/IV/tag sizes, and check that the same plaintext encrypts to different ciphertexts every time (fresh ephemeral key + IV per value).