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
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
End-to-end security flow
Supporting controls
Threat model (short)
What product managers configure
- Enable embedding and set allowed origins
- Add liquid tags (prefer mandatory for tenant keys)
- Confirm per-chart coverage (Direct or Via FK)—see Liquid tags and coverage
- Create an API key; give it to engineering out of band (never in a public ticket)
- Review audit for unexpected mints
What engineers must do
- Store the API key on the server only
- Mint with liquid values from your auth—never trust the browser for tenant id
- Mount
@vizkraft/embedwithgetSessionToken
How to verify
Use these checks before you go live with partners:- Mint two sessions with different liquid values (for example
customer_id=C1andcustomer_id=C2) and confirm each session only shows that tenant’s data. - Confirm a request that omits a mandatory liquid tag is rejected.
- Open the embed from an allowlisted origin, then from a non-allowlisted origin—and confirm the second is blocked.
- Confirm uncovered charts stay hidden when that setting is off.
- Optionally walk the same path in the Partner demo before you wire production.
Related
- Viewer options — what end users can see and do
- Partner demo — try the mint path safely in Acme Analytics
- Share links — human URLs (not a substitute for multi-tenant SDK embeds)