Skip to main content

Security & Privacy

The hard security and privacy guarantees the SDK makes, and what your integration is expected to do on its side. Most of these are machine-checked in the SDK's own CI on every build.

1. Key discipline

  • Treatink.init accepts only publishable keys (pk_test_… / pk_live_…). Any sk_… or other non-pk_ value throws key_scope_violation synchronously — a secret key can never boot the browser SDK.
  • The browser bundle contains no secret-key code path and cannot import @treatink/sdk/server; this is enforced by an automated check on every build.
  • Keys travel only in the Authorization: Bearer header — never in URLs, query strings, logs, or error messages (redaction is unit-tested).

Your side: keep sk_… keys on the server only. The single secret-key operation is submitOrder.

2. Photo privacy

  • No image bytes on the device. Drafts persisted to localStorage hold references only (asset ids, layout metadata) — never photo bytes, never a blob:/data: URL. A persistence test asserts stored values are small JSON.
  • Photos travel only to Treatink infrastructure (the API host and its presigned storage host) over TLS, and only at save time — nothing uploads while the shopper is still editing.
  • No third-party requests. An automated end-to-end test asserts the only origins the SDK contacts are the configured API/CDN/storage hosts (plus local blob: URLs). No analytics, no trackers, no external font CDNs — the modal's fonts are bundled.
  • tk.drafts.clear() removes all saved draft references for shared-device cleanup (kiosks, shared computers). See the ready-made privacy disclosure text for your storefront's privacy notice.

3. Host-page isolation

  • The modal renders in the light DOM (no iframe), so it shares your document. Collisions are mitigated with a scoped reset inside the tk- root, exclusively tk--prefixed class names, and a very high default zIndex (overridable via theming).
  • XSS discipline: all user and catalog text — personalization text, product titles, tags, your copy overrides — is rendered as text nodes (textContent), never innerHTML. The SDK uses no eval and no Function constructor, and a lint rule bans raw HTML injection.
  • Personalization text is length-limited and drawn to canvas as a plain string — there is no markup path.

4. Transport & uploads

  • Presigned upload URLs are used immediately, never logged or persisted, and are short-lived.
  • A failed upload surfaces an upload_failed error — no silent retry of writes. Idempotent GETs retry with backoff and jitter.
  • The client validates content_type and size (≤ 25 MB) before declaring an asset, and computes the sha256 locally.

5. Distribution integrity

  • Each release publishes an SRI hash for the browser bundle — pin your script tag with the integrity attribute as shown in the Quickstart.
  • Ship the recommended CSP: with a self-hosted bundle, script-src 'self', plus connect-src for the Treatink API and storage hosts and img-src for the Treatink CDN and blob: previews. Confirm the storage host with Treatink before publishing your policy.
  • The script is async/defer safe and never calls document.write.