Embedded Dashboards, Explained: Internal Tool or Production System?
Embedded dashboards name two different jobs. In your own internal tool it's a UI task. In a product customers pay for it's a multi-tenant production system whose hard parts sit server-side.
Ship native customer-facing dashboards and self-serve reporting fast with Embeddable
Start buildingKey takeaways
- An embedded dashboard is an analytics view rendered inside a host application, so the host app owns identity, layout and navigation rather than the BI tool.
- Internal embedding shows data to trusted colleagues; customer-facing embedding shows it to paying tenants, which transfers isolation, cost and metric correctness onto you.
- The four embedding methods (iframe, JavaScript SDK, web component, headless API) trade UX control against maintenance burden, so choose by the auth model you need.
- Tenant isolation belongs in a signed, short-lived embed token enforced server-side; if the browser can change the data boundary, you have a convention rather than security.
- Four things predictably break at scale: tenant leakage, cookie and CSP breakage, per-tenant query cost, and metric drift between the embed and the product UI.
What Is an Embedded Dashboard?
"Embedded dashboard" is one of those phrases that sounds like a component and turns out to be an architecture. Two teams can both say they've shipped one and be describing work that differs by an order of magnitude.
Embedded dashboards are analytics views rendered inside a host application rather than in a separate business intelligence (BI) tool, so the host app controls authentication, layout and navigation while the analytics layer supplies queries, charts and interactivity. They're delivered through an iframe, a JavaScript SDK, a web component, or a headless API. The term covers two different engineering problems: an internal embed seen only by colleagues, and a customer-facing embed where tenant isolation, permissions, query cost and consistent metric definitions must be guaranteed server-side.
The part worth sitting with is who owns what. Your application owns the user's identity, the session, the navigation, the URL, the design system. The analytics layer is a guest inside it. That inversion is the whole reason embedding is harder than it looks: a BI tool in its own tab can assume it knows who the viewer is, and an embed cannot. It has to be told, by you, in a way a browser can't tamper with.
Most vendors document this well enough. Tableau's Connected Apps, for instance, exist precisely because the host has to vouch for the viewer. What the definition never tells you is how much of that vouching becomes your problem.
Internal Embedded Dashboards vs Customer-Facing Embedded Dashboards
The same two words cover two jobs. One ships to colleagues behind your VPN; the other ships to every tenant paying you, and the failure modes have nothing in common.
| Internal embedded dashboard | Customer-facing embedded dashboard | |
|---|---|---|
| Audience | Employees in an admin or ops tool | Your customers' users, inside your product |
| Tenancy | Single tenant (you) | Many tenants, hard boundaries between them |
| Permission model | Role-based, coarse, often inherited from the identity provider (IdP) | Per-tenant row-level security plus per-user roles, enforced server-side |
| SLA | Best effort; a slow morning is an annoyance | Your product's SLA; a broken chart is a support ticket |
| Theming | Vendor default is fine | Must match the host app pixel-for-pixel, sometimes per-brand |
| Cost behaviour | Bounded by headcount | Scales with tenants, seats and refresh frequency |
| Metric correctness | Analysts reconcile it in a meeting | Must agree with the number the customer sees elsewhere in your UI |
| Blast radius of a bug | Wrong internal decision | Cross-tenant data exposure, breach notification, churn |
Internal embedding is a user-interface task, and usually the tail end of a self-service analytics programme: the data already has an audience that is allowed to see all of it, and the dashboard is a convenience laid over the top. Customer-facing embedding is a production system, because the moment the viewers are external users rather than colleagues, isolation, permissions, theming fidelity, query cost and metric correctness all become yours to guarantee.
That line is why the internal tool rarely transfers. Metabase, for example, is genuinely good at giving an internal team fast answers over cloud warehouses, and plenty of engineering orgs run it happily for years. What changes on the way to a customer-facing embed is documented by Metabase itself: multi-tenant "Tenants" is a Pro and Enterprise feature, so a team running the open-source or Starter edition internally cannot carry that setup across without also changing plan. Once there, isolation is a choice between three mechanisms you configure — row and column security, impersonation, or database routing — and a tenant user cannot move between tenants, while permissions are additive, so a user in several groups ends up with the most permissive access of any of them. Identity federation is application code you write: Metabase configures a single identity provider, and supporting customers who bring their own means your app authenticates against theirs and mints a signed JWT that Metabase accepts, provisioning users on the fly. Different problem. Different guarantees.
How Dashboard Embedding Works: Four Methods Compared
There are four ways to get a dashboard into your application, and they sit on a single axis: the more control you take over the user experience, the more of the integration you maintain yourself. Nothing else about the choice is free.
| Method | Control over UX | Auth model | Theming fidelity | Maintenance burden |
|---|---|---|---|---|
| iframe | Low. You control position and size; the vendor controls everything inside the frame. | Signed embed URL or a cross-site session cookie. Cookie-based flows are the fragile ones. | Limited to whatever theme options the vendor exposes. Fonts and spacing rarely match. | Low to start, then spiky: Content Security Policy (CSP) rules, third-party-cookie blocking, blank frames. |
| JavaScript SDK | Medium. You mount a dashboard into a div and drive it via an API. | Your server mints a short-lived signed token (commonly a JSON Web Token, JWT) carrying tenant and role claims. | Good. Theme objects, CSS variables, sometimes your own fonts. | Medium. SDK version upgrades, token refresh, breaking changes at the boundary. |
| Web component | Medium-high. A custom element in your DOM, styled from your app, framework-agnostic. | Same signed-token model; the element receives the token as an attribute or property. | High, if the component exposes styling hooks rather than a locked shadow root. | Medium. Shadow DOM styling quirks and framework interop are the usual tax. |
| Headless API / component-level | Total. You call an API for governed query results and render with your own components. | You own it. Server-side authorisation on every request, no browser-supplied scope. | Perfect, because it's your design system. | Highest at the chart layer, lowest at the trust layer, if the API enforces isolation for you. |
One of these cannot carry a tenant-facing embed on its own: the cross-site iframe leaning on a session cookie. It is already broken for a meaningful share of your end users, because Safari and Firefox block third-party cookies by default and so does Chrome Incognito. That is a permanent browser-dependent failure rather than a deadline you can wait out. Signed-token approaches don't have that problem.
So, method by method, against the tenant-facing bar: iframe embedding on a signed URL is viable for a simple read-only view and nothing more, and the same iframe on a cookie is not viable at all; the JavaScript SDK and the web component both clear the bar, provided the token is minted server-side and never assembled in the browser; and the headless API clears it with the fewest assumptions, because no data boundary is ever expressed in the browser in the first place.
So choose on the auth model and the control you need, not on whichever method your BI vendor happens to expose. That's a real constraint: some platforms only ship an iframe. Sisense has genuinely deep embedding options and a mature SDK; the question is still whether the model on offer matches the one your product requires.
Our bias, for what it's worth: if customers are behind it, start from the token.
Multi-Tenant Permissions and Row-Level Security: How Tenant Isolation Has to Be Enforced
A dashboard shows monthly active users. The chart is filtered by a tenant_id parameter your front end passes in when it mounts the component. In staging, with two seeded accounts, it's perfect. Then a curious customer opens dev tools, changes the parameter, and reloads.
That's the anti-pattern, and it demos identically to the correct version. The fix isn't a better filter; it's moving the boundary somewhere the browser can't reach.
Here's the pattern we'd defend in any design review, and it is the same one serious multi-tenant applications converge on. Your application already knows who the user is (they're logged in). Your server mints a short-lived, signed token — a JSON Web Token (JWT) is the usual implementation — with the tenant identity and role as claims, signed with a key the browser never sees. The token goes to the embed. The analytics layer verifies the signature, reads the tenant claim from the verified payload, and applies row-level security server-side, injecting the tenant predicate into every query before it reaches the warehouse. Server-side tokens are what make that boundary real: the front end can ask for anything it likes and still cannot widen its own scope, because nothing it sends is trusted as identity. Expiry is short (minutes, not days) so a leaked token has a small blast radius, and refresh runs through the same server path.
Two details people skip. Enforce the predicate on the views the dashboard actually queries, not just the base tables — a helpfully denormalised reporting view is the classic hole, because it exposes the underlying data without the access rules that protect the tables beneath it. And log the verified tenant on every query, because "prove customer A never saw customer B's rows" is a question enterprise security reviews genuinely ask, and you can only answer it from audit logs you were already writing.
Notice what this makes data access mean in an embed. It is not a setting on a dashboard; it is a property of the token, enforced at query time, over whatever data sources the analytics layer happens to sit on. That is why an embed pulling from multiple data sources is not harder to secure than one pulling from a single cloud warehouse, provided the predicate is applied server-side in every case — and why sensitive data belonging to one tenant is only ever as safe as the least careful query path.
Most serious platforms support this shape. Cube documents row-level security through query-time context; our own product overview covers signed security tokens and per-tenant row filtering the same way. The mechanism matters more than the vendor.
So the test is blunt. If a tenant's data boundary can be changed by anything the browser sends, you don't have tenant isolation. You have a convention, and conventions get edited in dev tools.
How this works in practice
See how a code-first embedded layer enforces tenant isolation
Embeddable mints short-lived signed tokens server-side and applies row-level filters at query time, with dashboards defined in code in your own repo. Worth a look if you are weighing the mechanics of what to build or buy.
What Breaks When Embedded Dashboards Scale: The Four Failures Behind a Real Customer Embed
Embedded dashboards rarely fail on the chart. They fail underneath it, and they usually fail on the day a large customer arrives with an unusual org structure, a strict browser policy, or a question about why two screens disagree.
Four failures are predictable enough that we'd ask about each before committing to an approach:
- Tenant leakage through permission-model drift. Isolation is correct at launch, then someone adds a "partner" role, a parent-child account hierarchy, or a reseller who legitimately sees three tenants. Each change edits the filter logic, and edits are where the boundary quietly moves. If the permission model lives in dashboard configuration rather than in versioned code with tests, nobody can answer "who could see this yesterday?" without opening a UI and squinting.
- CSP and third-party-cookie breakage. A cross-site iframe has to satisfy two policies owned by two different parties, and mixing them up is the fastest way to spend a day debugging the wrong one. The analytics origin sets
Content-Security-Policy: frame-ancestorson its own response to name which parents are allowed to frame it; your application setsframe-srcto name which origins it is allowed to embed. Either one can produce the same blank rectangle. A cookie-based session inside that frame then needs a third-party cookie to survive. Safari's Intelligent Tracking Prevention blocks third-party cookies by default (WebKit), Firefox confines them to a per-site cookie jar via Total Cookie Protection (Mozilla), and Chrome blocks them in Incognito (Google), while Google kept cookie choice in Chrome and retired most Privacy Sandbox technologies in October 2025 (Privacy Sandbox). So this isn't a deadline you're waiting on. It's a browser-dependent bug that presents as a blank frame for one customer and works fine on your machine. - Per-tenant query cost under concurrency. One tenant with 400 million rows and a 30-day default range can make every other tenant's dashboard slow. Warehouse spend becomes a per-customer variable you didn't price for, and caching that ignores tenant identity is the wrong fix applied fast.
- Metric drift between the embed and the product UI. The billing page says 1,204 active users, the dashboard says 1,187, both are defensible, and the support ticket is now about trust rather than a number. This happens whenever metric logic is defined twice: once in application code, once in the analytics layer. A semantic layer holding one governed definition is the fix; generating a chart per request from whatever the model infers is the fastest way to get two, which is where AI dashboard generators break down once the number has to match the invoice.
The pattern is the point. Every one of those four lives below the chart, in auth, permissions, query execution and metric definition, which is exactly where a charting library has nothing to say. Ask about all four in the evaluation, not in the incident review.
What You Maintain After the First Embed Ships
The launch is the cheap part. What you've actually signed up for is a monthly bill in engineering time.
Start with auth. Signed embed tokens are short-lived by design, so something in your app has to mint, refresh and gracefully recover from expiry, including the half-hour a customer leaves a tab open on a second monitor. Then the permission model moves: sales adds a plan tier, a customer asks for a read-only viewer role, an enterprise buyer wants their own admins managing access, and every one of those changes touches the code that decides which rows a token can see. Per-tenant performance is next, because your largest tenant will be orders of magnitude bigger than your median one and the query plan that worked for both on day one stops working for one of them. Add theming upkeep every time the host app redesigns, plus versioning metric definitions so "active user" means the same thing in the dashboard and the billing page.
None of that is exotic. It's just permanent, and it's why we think ongoing maintenance belongs in the build-versus-buy decision from the first design review, not after the second enterprise customer. Our own docs cover row-level security and a real slice of this; the question is how much of the rest stays yours.
Choosing an Embedded Dashboard Approach, and Why the Existing BI Tool Is Not the Answer
Score candidates on the trust layer, not the chart gallery. Here's the order we'd run it in:
- Isolation model. Ask the vendor to show you where the tenant boundary is enforced. If the answer involves a parameter the browser can send, stop there.
- Auth model. Short-lived signed tokens, server-issued, with single sign-on (SSO) or OAuth on the host side. Check how token refresh behaves mid-session, not just on page load.
- Control over the experience. Can your team change layout, interactions and theming in code, in your repo, under review? Or is the surface locked behind someone else's builder?
- Cost behaviour under concurrency. Model 500 tenants querying on Monday morning, not one analyst exploring on a Tuesday. Ask what's cached, per tenant, and for how long.
- Metric governance. One definition of active user, shared by the embed and the rest of your product, versioned like code.
- Maintenance burden. Who owns the upgrade when Chrome, your identity provider or your warehouse changes underneath you?
Sigma Embedded is genuinely strong on spreadsheet-style exploration for business users, and that matters if your buyers live in spreadsheets. It's still a different question from whether the isolation model survives a design review.
So: treat "we already have a BI tool" as an unproven claim about internal reporting until someone demonstrates tenant isolation, permissions, cost behaviour and metric governance under a customer-facing load. Embedded BI is the label the category has settled on, and it is worth noticing how much it hides: it names the surface and says nothing about the trust layer, which is the half you end up owning. The same caution applies one category over, where the question is product analytics vs embedded analytics — a tool that tells you how your product is used is answering a different question from one that shows your customer their own data.
We built Embeddable so teams control the experience and hand off the infrastructure layer underneath.
Frequently asked questions
What is the difference between an embedded dashboard and embedded analytics?
An embedded dashboard is one delivered surface: charts rendered inside a host app. Embedded analytics is the whole capability behind it, including the query layer, permissions, metric definitions and self-serve exploration.
How do you secure an embedded dashboard in a multi-tenant application?
Mint a short-lived signed token server-side carrying the tenant and user identity, then apply row-level security on the server for every query. Never let the browser send the tenant ID as a parameter the backend trusts.
Is an iframe good enough for customer-facing embedded dashboards?
Sometimes, for a simple read-only view. But iframes give you the least control over layout and interaction, and cross-site sessions are fragile in browsers that block third-party cookies by default.
Why do embedded dashboards go blank inside an iframe?
Usually a Content Security Policy directive on one side or the other — the analytics origin's frame-ancestors refusing your host, or your own frame-src refusing the analytics origin — or a cross-site session cookie being dropped by the browser. Check the console and network tab before blaming the analytics tool.
Can we use our existing internal BI tool for customer-facing dashboards?
Treat that as unproven until the tool demonstrates per-tenant isolation, role-aware permissions, theming fidelity and predictable query cost under concurrency. An internal reporting licence answers a different question.