Applied AI Governance — Dashboard Embedding for External Users
01 / 12

Navigation

→ / SpaceNext slide
←Previous slide
HomeFirst slide
EndLast slide
SwipeTouch navigation
Click anywhere or press Esc to close

Embedding Dashboards
for External Users

Embed an AI/BI Dashboard in your host application for viewers who have no Databricks account — with per-viewer data scoping and zero second login prompts.

Your host application authenticates users via your own identity provider. The backend mints scoped Databricks tokens on their behalf. Viewers never see Databricks, never need a Databricks account.

Companion to the Cross-IdP Federation deck. That deck gives viewers a real Databricks identity with automatic row-level security. This deck gives viewers no Databricks identity at all.

Agenda

What this deck covers.

1
The dual-login problem

Why a foreign IdP surfaces a second, unfamiliar sign-in screen inside the embedded iframe.

2
Two embedding models

Basic Embedding versus Embedding for External Users — who authenticates to Databricks, and how.

3
The token-exchange architecture

Three actors, three server-side API calls — the viewer’s browser never touches Databricks directly.

4
The scoping model

How per-viewer data narrowing is enforced — and where the platform does not enforce it for you.

5
Prerequisites and gotchas

What to confirm before you build, and the operational details that are easy to miss.

The problem

When host and account IdPs differ, a second login emerges.

When your host application’s IdP differs from the Databricks account’s SSO IdP, basic dashboard embedding sends the viewer’s browser to authenticate directly against the account’s IdP. If the viewer is already signed into your app via a different IdP, they hit an unbranded, unfamiliar login prompt inside the iframe.
2
identity providers per session
1
viewer already authenticated to

Why this matters beyond user friction

The second login is unbranded and unfamiliar. Viewers on your platform — internal staff, partners, downstream clients — now face an unexpected authentication detour inside your app.

The setup

Your host application

Custom React app (or other platform). All users authenticate once via your own identity provider (Okta, Azure AD, Auth0, or in-house).

The Databricks account

Its account-level SSO is configured against a different IdP — not the one your host app uses.

The embed

Dashboard is embedded via iframe. The viewer’s browser is asked to authenticate directly to Databricks’ IdP — not the host app’s IdP.

This is expected behavior of basic embedding, not a platform defect. Basic embedding authenticates viewers directly against the account’s IdP. The fix is switching to a different embedding model, not reconciling the two IdPs.

What — the two embedding models

Databricks offers two embedding models. They handle a foreign IdP differently.

Basic Embedding Embedding for External Users
Who authenticates to Databricks The viewer, directly, against the account’s SSO IdP The app’s own server, using its own Databricks identity
Viewer needs a Databricks identity? Yes — this is the second login prompt No
Where the prompt appears Inside the iframe, whenever the IdP session is stale Never — token is injected server-side
Data access model Viewer’s own UC permissions SP’s UC permissions, narrowed per-query by an app-supplied parameter
Setup Share dialog → generate embed code Publish the dashboard, create an app identity in Databricks, add server code that requests tokens

If the host app’s IdP differs from the Databricks account’s SSO IdP, Basic Embedding cannot avoid a second login — that is how the model is designed to work. The fix is switching to a model where the viewer’s Databricks identity is never in play.

What — the fix, in plain terms

Three actors. The viewer never talks to Databricks.

Your host application has two parts: the page viewed in a browser (frontend), and a server running your code (backend). The backend is invisible to viewers — it’s the only part that ever authenticates to Databricks. Below is the full flow.

Viewer’s browser — what the viewer sees
Your backend — your app’s server code, invisible to the viewer
Databricks — where the dashboard and data live
Viewer’s browser → Your backend Already signed in via your own IdP. Requests a dashboard to be embedded.
Your backend → Databricks Authenticates as itself using a secret (a service principal, or SP). Gets back a generic access token.
Your backend → Databricks Passes the viewer’s email and a scoping attribute (e.g., their client ID, department, or tenant). Gets back a ticket scoped to that viewer.
Your backend → Databricks Trades that ticket for a short-lived dashboard token (valid ~1 hour). Gets back the embed token.
Your backend → Viewer’s browser Sends the embed token to the viewer’s browser.
Viewer’s browser → Databricks Uses the token to load the dashboard. No login screen. Ever.

The viewer’s browser talks to your app and to Databricks’ dashboard viewer. It never sends credentials anywhere, never sees a login prompt, never even knows Databricks exists.

Why this matters

Four concrete reasons, not just a preference.

No second login for viewers

Viewers never authenticate to Databricks. The browser uses a scoped token you hand it, talks to your app, and loads the dashboard. No login screen.

No viewer provisioning in Databricks

The Service Principal is Databricks’ only identity. Add downstream clients, partners, or new user cohorts to your app without SCIM-syncing a single user into Databricks.

Works with any host IdP

The token exchange doesn’t care which IdP signed in your viewers. Okta, Azure AD, Auth0, custom — from Databricks’ side, the flow is identical.

Works across organizational boundaries

Your viewers may sit in different identity tenants, different organizations, or have no centralized identity at all. Account-level federation and JIT provisioning tools have limits when viewers span multiple tenants. This pattern has no tenant or federation constraint.

Why — when to use which

Three patterns. Pick the one that matches your use case.

Use this deck — External-User Embedding

Viewers have no Databricks account

Your app owns the viewer’s entire identity. Scoping is a single attribute (client ID, region, department). Dashboards only, no Genie Agents.

Use the Cross-IdP Federation deck

Viewers need platform-enforced row-level security

Viewers are SCIM-synced to Databricks with real current_user() identities. Unity Catalog row filters fire automatically. Genie Agents, SQL, Dashboards all work.

Use this deck even if IdPs differ

Your branding forbids any Databricks domain in the flow

Viewers stay entirely within your app’s domain. No redirects, no Databricks-branded URLs, no third-party prompts visible to your users.

Use Basic Embedding

Viewers share your Databricks account’s IdP

When your host app and Databricks already use the same IdP, there is no second identity. Basic Embedding is simpler and gives viewers their own real permissions.

How — implementation

The exact calls behind the app server’s three steps.

Verified against Databricks’ reference implementation. This is server code — the viewer’s browser never runs any of it.

Step 1 — SP token
POST {workspace}/oidc/v1/token
Authorization: Basic base64(client_id:secret)

grant_type=client_credentials&scope=all-apis
Step 2 — viewer context
GET {workspace}/api/2.0/lakeview/
  dashboards/{id}/published/tokeninfo
  ?external_viewer_id={email}
  &external_value={scoping_attr}
Authorization: Bearer {step_1_token}
Step 3 — scoped embed token
POST {workspace}/oidc/v1/token
Authorization: Basic base64(client_id:secret)

grant_type=client_credentials
&authorization_details={step_2_response}

authorization_details is Step 2’s response, passed through unmodified. Response: {access_token, token_type, expires_in, created_at}. access_token goes to the embedding SDK — never to the browser as anything else.

external_viewer_id is audit-only. It does not scope access by itself — only external_value, matched in dashboard SQL, does.

How — scoping model

This is application-enforced scoping, not Unity Catalog row filters.

Dashboard SQL — the scoping pattern
SELECT customer_id, region, total_revenue
FROM sales.customer_data
WHERE department = __aibi_external_value

If a query forgets the __aibi_external_value filter, that viewer sees everything the SP can see. There is no platform-level backstop — every query has to be reviewed.

Publish-time decision: individual data permissions (SP holds the union of access, filtering does the narrowing) vs. shared data permissions (the publisher’s access applies to every viewer uniformly — wrong choice whenever viewers must see different data).

Contrast: the Cross-IdP Federation deck’s pattern

Cross-IdP token exchange (Cross-IdP Federation deck)

  • Viewer does get a real Databricks identity (SCIM-synced)
  • current_user() = the human
  • UC row filters fire automatically, for every query, platform-enforced
  • Requires the viewer’s IdP to publish a JWKS (RS256/ES256)

Dashboard external embedding (this deck)

  • Viewer never gets a Databricks identity — SP only
  • current_user() would return the SP, not the human
  • Scoping fires only if the dashboard’s SQL includes the parameter
  • Works with any host IdP — no JWKS requirement at all
How — before you build

Six prerequisites to confirm before implementation.

1
Publish the dashboard

The embedding APIs only work against a published dashboard, not a draft.

2
Choose individual data permissions at publish time

Not shared. This is the setting that makes per-viewer scoping possible at all — and it’s a republish to change later, not a toggle.

3
Identify the scoping attribute up front

What column or value distinguishes one viewer’s data from another’s? Where does that scoping value live: in an IdP claim, your app’s user table, or a Databricks-side lookup table?

4
Create the Service Principal and grant the union of access

Can View on the dashboard, Can Use on the warehouse, UC SELECT across everything any viewer might need — the ceiling that external_value then narrows.

5
Approve your app’s domain for embedding

Workspace Settings → Security → External Access → Embed Dashboards. Add your app’s domain to the allowed list. Specify subdomains if needed (e.g., *.example.com).

6
Confirm third-party cookies work for your viewers

The embedding SDK relies on them. If your viewer base runs strict browser policies that block third-party cookies, test this before deployment.

How — gotchas

Operational details that are easy to miss.

IssueWhat to know
“Ask Genie Agents” requires basic embeddingConversational dashboard search (Genie Agents) works under basic embedding. For external-user embedding, use static or parameterized dashboards.
Token TTL ~1 hourThe SDK calls getNewToken() ~5 min before expiry. Your backend must re-run the full 3-step token exchange; there is no “refresh token” shortcut.
SP blast radiusThe SP holds the union of every viewer’s access. If credentials leak, all tenant data is exposed unless every dashboard query enforces the __aibi_external_value filter.
Query review is mandatoryThere is no platform-level backstop. If a dashboard query forgets the scoping filter, that viewer sees everything the SP can see. Every query must be reviewed.
SP credentials stay server-sideclient_id and client_secret never leave your backend. Only the minted embed_token is sent to the browser.
Publish-time decisionIndividual vs. shared data permissions is set when you publish. Changing it later requires republishing the dashboard, not toggling a setting.
ONE LOGIN. YOUR BACKEND AUTHENTICATES. ZERO PROMPTS.
Your backend mints scoped tokens. Your viewers never authenticate to Databricks.
Databricks Applied AI Governance Series · AI/BI Dashboard Embedding