Bold BI enables Row Level Security (RLS) to ensure users only access data they are authorized to see, using Data Filter and Custom Attribute. This guide explains how these mechanisms provide secure, user-specific data access for embedded dashboards.
Row-level security is achieved server-side by including the embed_datasource_filter
attribute in the token generation process. This attribute filters data rows based on user-specific criteria, ensuring secure, tamper-proof access without exposing filter logic to users.
Pass data filters via embed_datasource_filter
in the token generation method to enforce row-level security by filtering data dynamically and pass this token in frontend to render the dashboard.
Node
const crypto = require('crypto');
const https = require('https');
const http = require('http');
const url = require('url');
//Token Generation With Data Filter
app.post('/tokengeneration', function () {
var serverUrl = "< Bold BI server URL >";
var siteIdentifier = "< Bold BI server Site Identifier >";
var dashboardId = "< Dashboard Id >";
var useremail = "< Bold BI server user Email >";
var embedSecret = "< Embed Secret key >";
var filter = "[{shipCountry=India}]" // Add your filter data
var serverApiUrl = serverUrl + "/api/" + siteIdentifier;
var queryString = "embed_nonce=" + crypto.randomUUID();
queryString += "&embed_dashboard_id=" + dashboardId;
queryString += "&embed_user_email=" + useremail;
// Filter Query
queryString += "&embed_datasource_filter=" + filter;
var embedSignature = "&embed_signature=" + GetSignatureUrl(queryString,embedSecret);
var embedDetailsUrl = "/embed/authorize?" + queryString+embedSignature;
var serverProtocol = url.parse(serverApiUrl).protocol == 'https:' ? https : http;
serverProtocol.get(serverApiUrl + embedDetailsUrl, function (resultContent) {
let str = '';
resultContent.on('data', function (chunk) {
str += chunk;
});
resultContent.on('end', function () {
const resultJson = JSON.parse(str);
if (resultJson && resultJson.ApiStatus && resultJson.Data && resultJson.Data.access_token) {
response.json({ access_token: resultJson.Data.access_token });
}
});
});
})
function GetSignatureUrl(queryString,embedSecret)
{
var keyBytes = Buffer.from(embedSecret);
var hmac = crypto.createHmac('sha256', keyBytes);
data = hmac.update(queryString);
gen_hmac= data.digest().toString('base64');
return gen_hmac;
}
Filter Syntax:
Scenario | Query |
---|---|
Single Filter | &embed_datasource_filter=[{&Param=Value}] |
Multiple Filters | &embed_datasource_filter=[{&Param1=Value1&Param2=Value2}] |
List Format (IN) | &embed_datasource_filter=[{&Param=IN(Value1,Value2)}] |
Note: Filters must be enclosed in square brackets and curly braces. You can achieve the same RLS for custom columns using Dashboard Parameters. Please refer to this link to create dashboard parameter
Custom Attributes are name-value pairs saved for users or groups, or sites, dynamically changing data source via queries, expressions, or data source connections to enforce row-level security by tailoring data access to specific users or groups or sites.
Learn More About Custom Attribute: For detailed examples of using custom attributes in dashboard, refer to Custom Attribute Usage.
Pass Custom Attribute via embed_custom_attribute
in the token generation method to enforce row-level security by filtering data dynamically based on user or role and pass this token in frontend to render the dashboard.
Node
In this scenario, two users access the same dashboard with different databases sharing the same schema. We configured a custom attribute with the database name DB1 in the data source connection of the Bold BI server. In embedding, we dynamically assign a different database, DB2, using the embed_custom_attribute parameter, and the dashboard is rendered with the specified database details.
Note: Explore our demo to see how RLS is achieved with custom attributes.
const crypto = require('crypto');
const https = require('https');
const http = require('http');
const url = require('url');
//Token Generation With Custom Attribute
app.post('/tokengeneration', function () {
var serverUrl = "< Bold BI server URL >";
var siteIdentifier = "< Bold BI server Site Identifier >";
var dashboardId = "< Dashboard Id >";
var useremail = "< Bold BI server user Email >";
var embedSecret = "< Embed Secret key >";
var customAttribute = "[{\"database_name\":\"DB1\"}]" // Add Custom Attribute Name and Value
var serverApiUrl = serverUrl + "/api/" + siteIdentifier;
var queryString = "embed_nonce=" + crypto.randomUUID();
queryString += "&embed_dashboard_id=" + dashboardId;
queryString += "&embed_user_email=" + useremail;
//Custom Attribute Query
queryStringString += "&embed_custom_attribute="+ customAttribute;
var embedSignature = "&embed_signature=" + GetSignatureUrl(queryString,embedSecret);
var embedDetailsUrl = "/embed/authorize?" + queryString+embedSignature;
var serverProtocol = url.parse(serverApiUrl).protocol == 'https:' ? https : http;
serverProtocol.get(serverApiUrl + embedDetailsUrl, function (resultContent) {
let str = '';
resultContent.on('data', function (chunk) {
str += chunk;
});
resultContent.on('end', function () {
const resultJson = JSON.parse(str);
if (resultJson && resultJson.ApiStatus && resultJson.Data && resultJson.Data.access_token) {
response.json({ access_token: resultJson.Data.access_token });
}
});
});
})
function GetSignatureUrl(queryString,embedSecret)
{
var keyBytes = Buffer.from(embedSecret);
var hmac = crypto.createHmac('sha256', keyBytes);
data = hmac.update(queryString);
gen_hmac= data.digest().toString('base64');
return gen_hmac;
}
Syntax Examples:
Scenario | Syntax | Example |
---|---|---|
Single Attribute | [{\"Attribute_Name\":\"Value\"}] |
&embed_custom_attribute=[{\"database_name\":\"DB1\"}] |
Multiple Attributes | [{\"Attribute_Name1\":\"Value1\",\"Attribute_Name2\":\"Value2\"}] |
&embed_custom_attribute=[{\"department\":\"IT\",\"name\":\"David\"}] |
List Format (IN) | [{\"Attribute_Name\":\"IN('Value1','Value2')\"}] |
&embed_custom_attribute=[{\"department\":\"IN('CSE','EEE')\"}] |