Skip to main content

Define base connection roles

When generating embed requests, set the connectionRoles parameter to either No Access or Viewer. This sets the default level of access for the connection and ensures that access to data must be granted on an individual user basis.

Send connection roles on every embed request

When a user creates an embed session, the connectionRoles on the latest request acts as the source of truth for that user’s connection access. This means:
  • A role can be downgraded by a later request (e.g. from Restricted Querier to Viewer).
  • A role can be removed entirely if the later request doesn’t mention the connection — either explicitly in connectionRoles or implicitly in the connection backing the requested contentPath.
If you embed multiple pieces of content on the same page (for example, a dashboard and a workbook in separate iframes), include an explicit connectionRoles object on every request. Each iframe generates its own embed login request, and a request that omits connectionRoles will overwrite the access granted by the others.
For example, imagine a page that embeds:
  • A workbook backed by connection A, which requires at least Restricted Querier access
  • A dashboard backed by connection B, which only requires Viewer access
If the dashboard’s embed request only specifies connectionRoles for connection B, the user’s role on connection A will be deleted as soon as that request resolves — and the workbook will lose access. To avoid this, send connectionRoles for both connection A and connection B on both the workbook and dashboard embed requests.

Leverage user attributes to control data access

To ensure appropriate data access for users, best practice is to leverage user attributes to systematically filter data.
  • Access filters, or row-level security, allow you to restrict the rows of data a user can access within a topic. Access filters apply the values assigned on a user attribute to the WHERE clause of every SQL query a user runs, filtering out to only the data designated to that user.
  • Access grants define topic- and field-level permissions for users

Implement security for multi-tenant instances

Segmenting data using hidden dashboard filters is not a secure practice.
Typically, companies choose one of the following strategies to set up multi-tenant customer data:
  • Row-level security - If all of the data is inside one table, you can assign a user attribute per user and client and use it as an access filter. Specifically make sure to set up a default access filter to control in Omni with default_topic_access_filters. Note that input columns automatically enforce access filter fields in their mapping keys to prevent cross-tenant data leakage.
  • Schema level security - If each client is in a separate, identical schemas then you can leverage dynamic schemas.
  • Database level security - If each client is in a separate database and the schemas are identical across databases, you can leverage dynamic database environments.
  • Model-level isolation - If each client needs a tailored view of the same base model, you can use shared extension models to create tenant-specific extensions that inherit core logic while allowing per-client customizations.

Build content on shared topics

Embedded dashboards won’t render correctly if the content you want to embed meets any of the following criteria:
  • Content contains fields not included in a topic in the shared model
  • Content built on SQL
  • Content that contains unpromoted changes to joins in the workbook’s model
To expose non-topic bound or SQL-based content, enable AccessBoost in the content’s Share settings. This has security implications, as you may expose data that you don’t want your embed users to access.

Save content to the Shared hub

Along with the above criteria for building content on topics, embedded dashboards must be saved in your instance’s Shared hub. Dashboards will not render correctly if they are saved in personal folders.

Scheduled deliveries and embed user entities

If you’re using dynamic shared extensions in embed and your embed users may access multiple entities, we recommend assigning only one entity per embed user. Scheduled deliveries run as the user who created them, using their current attributes at delivery time - including which dynamic shared extension to load. If the same embed user logs in under different entities, their entity attribute changes with each session. When a scheduled delivery runs, it uses whatever entity that user is currently associated with, which may not match the entity context the delivery was originally created under. To avoid this, generate a distinct embed user for each entity rather than reusing the same externalId across multiple entityId values.
Note: This applies broadly to any delivery that depends on user attributes — not just embed users with dynamic shared extensions.