Skip to main content
Embeds are built for B2B products that show one Vizkraft dashboard to many end customers. Security is not a single switch: it is two primary layers plus supporting controls. Open the app: app.vizkraft.com · Product: vizkraft.com

The two primary layers

1. API key (who may mint sessions)

  • Format: vk_embed_…
  • Lives only on your backend (env / secrets manager)
  • Used solely to call POST /api/embed/session
  • Never shipped to the browser, mobile app, or @vizkraft/embed
Anything in the browser is visible in DevTools. If tenant C1 had your API key, they could mint a session for tenant C2. The safe pattern is: API key on your server → short-lived session stamped with C1 → SDK uses only that session token.

2. Liquid tags (what data the session may see)

  • Named placeholders you define in Vizkraft (e.g. customer_id, department_id)
  • Your backend supplies values at mint time from your auth
  • Vizkraft binds those claims into the session and applies them server-side to every chart query (direct column or foreign-key join)
  • End-user filters in the iframe can only narrow further—they cannot widen past liquid scope
Mandatory tags must be present at mint or the request fails. Optional tags, if omitted, leave that dimension unscoped for that session—configure mandatory tags for true tenant isolation.

End-to-end security flow

Supporting controls

Threat model (short)

What product managers configure

  1. Enable embedding and set allowed origins
  2. Add liquid tags (prefer mandatory for tenant keys)
  3. Confirm per-chart coverage (Direct or Via FK)—see Liquid tags and coverage
  4. Create an API key; give it to engineering out of band (never in a public ticket)
  5. Review audit for unexpected mints
Walkthrough: Admin setup

What engineers must do

  1. Store the API key on the server only
  2. Mint with liquid values from your auth—never trust the browser for tenant id
  3. Mount @vizkraft/embed with getSessionToken
Full steps: Developer guide

How to verify

Use these checks before you go live with partners:
  1. Mint two sessions with different liquid values (for example customer_id=C1 and customer_id=C2) and confirm each session only shows that tenant’s data.
  2. Confirm a request that omits a mandatory liquid tag is rejected.
  3. Open the embed from an allowlisted origin, then from a non-allowlisted origin—and confirm the second is blocked.
  4. Confirm uncovered charts stay hidden when that setting is off.
  5. Optionally walk the same path in the Partner demo before you wire production.