I am testing Row-Level Security (RLS) using the Power BI REST API but noticed that roles are not being applied. The query executes with full admin access instead of enforcing the assigned role.
Expected Behavior: The query should return filtered results based on the assigned role.
Actual Behavior: The query executes as if no RLS roles were assigned, returning full dataset access.
What I Checked:
- Verified that the role exists and is correctly assigned.
- Ensured the API token is generated with the correct role.
- Executed the same DAX query in PowerBI desktop while the role was active and it returned results as expected
- Confirmed that RLS is enabled in the semantic model settings.
parts of the script I am using as following:
# Iterate through each employee
foreach ($row in $truthTable) {
$principalName = $row.PrincipalName
$expectedRows = $row.ExpectedRows
# Apply RLS role for the user
$tokenRequest = @{
datasets = @(
@{
id = $datasetId
roles = @(
@{
name = $role
members = @(
@{
identity = $principalName
}
)
}
)
}
)
}
$tokenRequestJson = $tokenRequest | ConvertTo-Json -Depth 10
# Generate the token for the user
$tokenResult = Invoke-PowerBIRestMethod -Url "groups/$workspaceId/datasets/$datasetId/GenerateToken" -Method Post -Body $tokenRequestJson -ContentType "application/json"
# Query the dataset
$query = @{
queries = @(
@{
query = "EVALUATE ROW(""RowCount"", DISTINCTCOUNT(Table[column]))"
}
)
}
# Execute the query with the generated token
$result = Invoke-PowerBIRestMethod -Url "groups/$workspaceId/datasets/$datasetId/executeQueries" -Method Post -Body $queryJson -ContentType "application/json"
# Compare actual vs expected
$actualRows = ($result | ConvertFrom-Json).results[0].tables[0].rows[0].RowCount
if ($actualRows -eq $expectedRows) {
Write-Output "Test passed for $principalName"
} else {
Write-Output "Test failed for $principalName. Expected $expectedRows, got $actualRows"
}
}
and the output:
Token generated for *****.de
{
"@odata.context":"***X0=","tokenId":"***-5730bfaf8db6","expiration":"2025-02-07T17:24:38Z"
}
Query Result for ******.de:
{
"results": [
{
"tables": [
{
"rows": [
{
"[RowCount]": 169
}
]
}
]
}
]
}
Test failed for ******.de. Expected 18, got 169