Skip to main content

Portable Encryption overview

KnoxCall’s Portable Encryption turns any value into a single, self-describing kc: ciphertext string you can drop into a database column, a log line, or a message queue with no schema change — and which carries everything needed to decrypt it except the private key. It is public-key encryption: you encrypt against a tenant public key, and only KnoxCall (holding the matching private key, wrapped under your tenant master key) can decrypt. That means plaintext can be sealed before it ever reaches KnoxCall — including in a browser. Use it for:
  • “Encrypt anything, store it anywhere” — PII, PHI, PAN, API responses, free-form blobs. The ciphertext is portable across systems.
  • Structure-preserving encryption — send a whole JSON object; get the same shape back with every scalar leaf replaced by a kc: string.
  • Frontend scope reduction — seal card/PII data in the page so it never touches your servers (paired with the browser SDK).
  • Crypto-agility — every kc: value carries its scheme version, so the format can evolve without breaking stored data.

Quick example

# Encrypt — structure-preserving. Scalar leaves become kc: strings.
curl -X POST https://api.knoxcall.com/v1/encrypt \
  -H "Authorization: Bearer $KC_API_KEY" -H "Content-Type: application/json" \
  -d '{ "data": { "card": "4242424242424242", "amount": 1299 } }'
# → { "data": { "card": "kc:1:s:...:$", "amount": "kc:1:n:...:$" }, "key": "kc-default", "key_version": 1 }

# Decrypt — non-kc values pass through untouched.
curl -X POST https://api.knoxcall.com/v1/decrypt \
  -H "Authorization: Bearer $KC_API_KEY" -H "Content-Type: application/json" \
  -d '{ "data": { "card": "kc:1:s:...:$", "amount": "kc:1:n:...:$" } }'
# → { "data": { "card": "4242424242424242", "amount": 1299 } }

# Inspect — metadata about a ciphertext WITHOUT decrypting it.
curl -X POST https://api.knoxcall.com/v1/inspect \
  -H "Authorization: Bearer $KC_API_KEY" -H "Content-Type: application/json" \
  -d '{ "value": "kc:1:s:...:$" }'
# → { "encrypted": true, "scheme": "kc", "version": 1, "datatype": "s", "key_ref": {...}, "fingerprint": "..." }
If you don’t name a key, KnoxCall auto-provisions a default ecdh-p256 key on first use — the happy path is zero-config. To pin a key, pass "key": "my-key" (create it with key_type: "ecdh-p256" via Crypto Keys).

Data roles

Pass an optional role on encrypt to bind a data-role into the ciphertext (e.g. pci, eu). The role is folded into the key derivation, so the value can only be decrypted by presenting the same role — the policy travels with the data, not just at the gateway.
curl ... -d '{ "data": "4242...", "role": "pci" }'   # encrypt under role "pci"
curl ... -d '{ "data": "kc:...:$", "role": "pci" }'  # must pass role "pci" to decrypt

Client-side reveal without an API key

Browsers and agents should never hold an API key. To let a frontend reveal one value, your backend mints a single-use, payload-pinned capability token and hands it over:
# Backend (API key): mint a token bound to exactly one ciphertext.
curl -X POST https://api.knoxcall.com/v1/client-tokens \
  -H "Authorization: Bearer $KC_API_KEY" -H "Content-Type: application/json" \
  -d '{ "action": "decrypt", "data": "kc:1:s:...:$", "ttl_seconds": 300 }'
# → { "token": "kct_...", "expires_at": "...", "action": "decrypt" }

# Browser (no API key): exchange the token ONCE for the plaintext.
curl -X POST https://api.knoxcall.com/v1/client/decrypt \
  -H "Authorization: Bearer kct_..." -H "Content-Type: application/json" \
  -d '{ "data": "kc:1:s:...:$" }'
# → { "data": "4242424242424242" }
The token is consumed on first use, expires within minutes, and only matches the exact ciphertext it was minted for. A leak reveals at most that one value, once. The same flow works for vault tokens with action: "detokenize"POST /v1/client/detokenize.

Dual-custody vaults

A vault created with custody_mode: "dual" issues kc: ciphertext as its token and stores no value at all — you keep the ciphertext, KnoxCall keeps only the key. A breach of KnoxCall alone leaks nothing, and detokenize is a pure decrypt (no database lookup).

Learn more