| Package | What it does |
|---|---|
@knoxcall/browser | Pure client-side ECIES sealing (P-256 → HKDF-SHA256 → AES-256-GCM), single-use reveal via KnoxClient, and the framework-agnostic Elements iframe protocol |
@knoxcall/react | <CardCollect> and <Reveal> — iframe-isolated React components built on the browser package |
kc: ciphertext in the page, using your tenant’s public key — plaintext never reaches your servers. The kc: string is byte-compatible with KnoxCall’s server-side format, so only KnoxCall (holding the private key) can decrypt it. These are client-side packages, not management-API SDKs — they never hold an API key.
Install
Not yet published to npm — install from a monorepo checkout by path.
@knoxcall/browser requires WebCrypto (any modern browser, or Node ≥ 18 for SSR/tests); @knoxcall/react needs react >= 18 and @knoxcall/browser as a peer.Seal in the browser
1. Server side — fetch the sealing bundle with your API key (the bundle contains only public material, so it is safe to hand to the page):encrypt() accepts strings, finite numbers, booleans, null, and JSON-serializable objects/arrays; the original type is preserved through decryption. See Browser-Side Encryption for the underlying format.
Capture cards with <CardCollect>
<CardCollect> embeds a KnoxCall-hosted cross-origin iframe that captures card details and seals the PAN inside the iframe. Your page — and any XSS on it — only ever receives the ciphertext (plus display-safe last4 / brand). That collapses your frontend PCI scope toward SAQ A.
Reveal with capability tokens
Reading a value back in the browser never uses an API key. Your backend mints a single-use, payload-pinned capability token (kct_…) bound to the exact ciphertext or vault token, and hands only that token to the page:
KnoxClient:
<Reveal> component, which renders the plaintext to the user inside the iframe — your JavaScript never sees it:
KnoxClient refuses anything that is not a kct_… token before making a network call, so an API key pasted into the browser by mistake never leaves the page.
Security model
- No API key in the browser. Sealing needs only the public bundle; revealing needs only a short-lived
kct_capability token minted by your backend. Nothing shipped to the page can decrypt at will. - Single-use, payload-pinned reveal tokens. A
kct_token is bound to one specific ciphertext/vault token and is consumed on first use. - Context-bound ciphertexts. The HKDF
infopins tenant, app key, key version, datatype, and optionalpurpose(data-role, e.g."pci") into the derived key; thekc:header rides as AES-GCM AAD. Decrypting under the wrong purpose, key, or a tampered header simply fails. - Exact-origin iframe trust. Element messages are only accepted from an allowlisted origin (exact string match — no prefix or substring semantics, so
https://api.knoxcall.com.evil.comnever passes), from the expected iframe window, and only after strict shape validation. Outbound messages are posted with an explicittargetOrigin, never*.
Full reference
Component props, the rawpostMessage protocol (parseKnoxMessage, isTrustedElementOrigin, KNOX_MESSAGE), and development setup: sdk/knoxcall-browser/README.md and sdk/knoxcall-react/README.md in the monorepo.