Embed Portal - Getting Started
This document outlines a Beta feature currently in progress. Until the Beta label is removed from both this notice and the feature in the Holistics' platform, it should not be regarded as part of our official documentation. Please note that this feature is subject to rapid, iterative changes, and the most current version may vary from what is described here. Contact [email protected] to try it out!
Embed Portal features require explicit Git integration to be enabled. If you're using external Git, ensure your repository has write access and disable protected branch restrictions.
Getting Started with Embed Portal
This guide walks you through creating your first Embed Portal, from definition to integration in your application.
Overview
Creating an Embed Portal involves four main steps:
- Define your portal in a
.embed.aml
file - Publish your portal to production
- Generate embed credentials
- Integrate the portal into your application
Step 1: Define Your Portal
Create the Portal File
Create a new file in your Development tab with the naming convention: *.embed.aml
Example: sales_analytics.embed.aml
EmbedPortal sales_portal {
objects: [
sales_overview, // dashboard
revenue_trends, // dashboard
sales_data, // dataset
],
}
Basic Portal Syntax
Required Elements:
EmbedPortal
block with a unique nameobjects
array containing the dashboard and dataset names
Since objects are unique across your Holistics instance, you can simply list the object names. Holistics automatically detects whether each object is a dashboard or dataset.
Step 2: Configure Row-Level Permissions (Optional)
If you need to restrict data access, you'll need to set up user attributes and define permissions in your datasets. User attributes will be used to configure permissions to fit each embed viewer's access requirements. These user attributes will be passed to the embed portal via embed token in Step 4.
Define User Attributes First
Before using user attributes in dataset permissions, you must define them in Holistics. See: User Attributes Documentation
Dataset Permission Example
Dataset sales_data {
// ... your models and dimensions ...
permission regional_access {
field: ref('orders', 'region')
operator: 'matches_user_attribute'
value: 'region'
}
permission company_access {
field: ref('orders', 'company_id')
operator: 'matches_user_attribute'
value: 'company_id'
}
}
Key Points:
- The
value
must match a user attribute name you defined in Settings - The
field
should reference the field in your dataset that you want to restrict
Portal Permission Settings
You can configure default permission settings directly in your Embed Portal (Beta) file. These default user attributes can be overridden in the embed token.
EmbedPortal customer_analytics {
objects: [
sales_data, // dataset
],
// Optional: Set default user attributes (can be overridden in embed token)
default_user_attributes {
region: 'US',
},
}
Step 3: Publish Your Portal
Publishing Workflow
Follow the standard publishing process to deploy your portal to production. See: Publishing to Production
After publishing, you'll need to enable embed credentials for your portal.
Step 4: Generate Embed Token
Enable Embed Credentials
Navigate to: Tools → Embedded Analytics
Enable the single embed credential to get your Key ID and Secret for integration.
Backend Integration
In your application backend, generate embed tokens using this structure:
// Basic embed payload
const embed_payload = {
object_name: 'customer_analytics',
object_type: 'EmbedPortal',
embed_user_id: 'user_123',
embed_org_id: 'company_456',
user_attributes: {
region: 'US',
company_id: 456,
},
settings: {
default_timezone: "UTC",
enable_export_data: false,
}
};
// Generate token (implementation depends on your backend)
const token = jwt.sign(embed_payload, embed_secret, { algorithm: 'HS256' });
Parameters
Parameter | Type | Description | Required |
---|---|---|---|
object_name | string | Name of your EmbedPortal | ✅ |
object_type | string | Must be 'EmbedPortal' | ✅ |
embed_user_id | string | Unique identifier for the user | For SSBI features |
embed_org_id | string | Unique identifier for user's organization | For org workspaces |
user_attributes | object | Values for row-level permissions | If using RLP |
settings | object | Portal configuration settings | Optional |
permissions.enable_personal_workspace | boolean | Enable personal workspace for user | Optional |
permissions.org_workspace_role | string | User's role in organization workspace: 'no_access' , 'viewer' , 'editor' | Optional |
🔒 Understanding Workspace Security Isolation
Security Design: Personal workspaces are intentionally isolated by the combination of embed_user_id
+ embed_org_id
to maintain strict data security boundaries and prevent data breaches.
Why This Security Model?
- One user, one organization: Each user is assigned to exactly one organization at a time, eliminating dual-organization access
- Technical isolation mechanism:
embed_user_id
+embed_org_id
combination creates separate data containers per organization - Prevents data leakage: Without this isolation, users could move data between organizations via personal workspace
// ✅ Secure isolation - each organization gets separate workspaces:
// John working for Company A
const john_at_company_a = {
embed_user_id: '[email protected]',
embed_org_id: 'company_a',
permissions: { enable_personal_workspace: true }
// Result:
// - Access to Company A's shared workspace
// - Personal workspace scoped to Company A only
// - Cannot see any Company B data
};
// Same John working for Company B
const john_at_company_b = {
embed_user_id: '[email protected]',
embed_org_id: 'company_b',
permissions: { enable_personal_workspace: true }
// Result:
// - Access to Company B's shared workspace
// - NEW personal workspace scoped to Company B only
// - Cannot see any Company A data
// - Cannot share Company A data to Company B via personal workspace
};
// ❌ Without this security model:
// If John had 1 shared personal workspace across both companies,
// he could save Company A data to personal workspace,
// then share it with Company B colleagues - creating data breach!
Implementation Best Practice: Design your embed_org_id
structure to reflect your actual organizational boundaries. Each user should have one stable organization ID throughout their lifecycle. Use user_attributes
for RLP permissions and feature tiers instead of changing the organization boundary. Use org_workspace_role: 'no_access'
to hide shared workspace before you decide to enable shared workspace.
User Attributes for Permissions
Match the user attributes in your payload to the permission values in your datasets:
// If your dataset has this permission:
permission regional_access {
field: ref('orders', 'region')
operator: 'matches_user_attribute'
value: 'region'
}
// Your payload should include:
user_attributes: {
region: 'US', // Matches the 'region' value in the permission
}
Bypassing Permissions with __ALL__
You can bypass specific row-level permissions by setting the user attribute to __ALL__
:
user_attributes: {
region: '__ALL__', // This will let this user view all data regardless of region
company_id: 456, // Still applies company_id restrictions
}
Step 5: Frontend Integration
Basic iframe Implementation
<!-- Generate this URL in your backend -->
<iframe
src="https://holistics.io/embed/{key_id}?token={generated_token}"
width="100%"
height="600"
frameborder="0">
</iframe>
Dynamic Token Generation
// Frontend JavaScript example
async function loadPortal(userId, orgId) {
// Call your backend to generate token
const response = await fetch('/api/embed-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
portal: 'customer_analytics',
user_id: userId,
org_id: orgId
})
});
const { embedUrl } = await response.json();
// Update iframe source
document.getElementById('portal-iframe').src = embedUrl;
}
Step 6: Enable Self-Service Features (Optional)
To allow embedded users to create and edit their own dashboards, add self-service parameters to your embed payload.
Personal Workspace
Enable users to create private dashboards:
const embed_payload = {
object_name: 'customer_analytics',
object_type: 'EmbedPortal',
embed_user_id: 'user_123', // Required for personal workspace
permissions: {
enable_personal_workspace: true,
},
user_attributes: {
company_id: 456,
region: 'US',
}
};
What this enables:
- Users can create dashboards visible only to themselves
- Users can explore data and save results to personal dashboards
- Personal dashboards are isolated per user
Organization Workspace
Enable users to collaborate and share dashboards within their organization:
const embed_payload = {
object_name: 'customer_analytics',
object_type: 'EmbedPortal',
embed_user_id: 'user_123',
embed_org_id: 'company_456', // Required for org workspace
permissions: {
enable_personal_workspace: true,
org_workspace_role: 'editor', // or 'viewer' or 'no_access'
},
user_attributes: {
company_id: 456,
region: 'US',
}
};
Organization Roles:
'no_access'
- Cannot access organization workspace'viewer'
- Can view shared dashboards, cannot create or edit'editor'
- Can create, edit, and delete dashboards in organization workspace
What this enables:
- Users can create dashboards shared with their entire organization
- Organization members can collaborate on shared analytics
- Strict data isolation between different organizations
Preview Your Portal
Sandbox Preview in Holistics
- Go to Tools → Embedded Analytics
- Find your published portal
- Click Preview to test in Holistics interface
- Adjust settings and user attributes to test different scenarios
The sandbox allows you to test your portal configuration before integrating it into your application.
Next Steps
Once your basic portal is working:
- Enable Self-Service Features - Add personal and organization workspaces
- Configure Advanced Permissions - Set up complex multi-tenant scenarios (coming soon)
- Customize User Experience - Adjust settings and portal behavior (coming soon)
Ready to add self-service capabilities? See the Data Exploration guide.