cancel
Showing results for 
Search instead for 
Did you mean: 
Warehousing & Analytics
Engage in discussions on data warehousing, analytics, and BI solutions within the Databricks Community. Share insights, tips, and best practices for leveraging data for informed decision-making.
cancel
Showing results for 
Search instead for 
Did you mean: 

External embedding for reports using federated credentials fails

iamgoce
New Contributor III

Hi,

We are implementing external dashboard embedding in Azure Databricks and want to avoid using client secrets by leveraging **Azure Managed Identity** with **OAuth token federation** for generating the embedded report token.

Following OAuth token federation documentation, we successfully obtain an AAD token using:

credential = ManagedIdentityCredential(client_id=CONFIG['service_principal_id'])
aad_token_res = credential.get_token("api://AzureADTokenExchange/.default")
aad_token = aad_token_res.token

Then, we exchange this token for a Databricks **all-apis** token using:

federated_params = {
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
"client_id": CONFIG["service_principal_id"],
"subject_token": aad_token,
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
"scope": "all-apis"
}

Next, we call `/published/tokeninfo` with `external_viewer_id` and `external_value` to retrieve `authorization_details` and `custom_claim`. This step works as expected and returns the same data as when using Basic Auth with a service principal secret.

However, when we perform the **scoped token exchange** using OAuth federation:

scoped_params = {
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
"client_id": "<Databricks SP UUID>",
"custom_claim": "urn:aibi:external_data:testss:test:DASHBOARD_ID",
"subject_token": aad_token,
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
"authorization_details": json.dumps(token_info["authorization_details"]),
}

The resulting JWT **does not include the `custom.claim`**. It only contains `authorization_details` and `scope`. In contrast, when using Basic Auth + SP secret, the scoped token includes:

"custom": {
"claim": "urn:aibi:external_data:<external_value>:<external_viewer_id>:<dashboard_id>"
}

Without this claim, embedding fails with:

{"message":"BAD_REQUEST","name":"Dashboard ID is missing in token claim."}

Question

Is this a known limitation of the current public preview for OAuth token federation? If so, is there an ETA for supporting **custom claim injection** in scoped tokens for external embedding?

Code Summary (Federation Flow):

scoped_params = {
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
"client_id": "<Databricks SP UUID>",
"custom_claim": "urn:aibi:external_data:testss:test:DASHBOARD_ID",
"subject_token": aad_token, # MI token for api://AzureADTokenExchange/.default
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
"authorization_details": json.dumps(token_info["authorization_details"]),
}

response = [requests.post](
f"{instance_url}/oidc/v1/token",
headers={"Content-Type": "application/x-www-form-urlencoded"},
data=scoped_params
)

Decoded JWT (Federation):

{
"client_id": "…",
"scope": "…",
...
"authorization_details": […]
}

Decoded JWT (Basic Auth):

{
"custom": {
"claim": "urn:aibi:external_data:testss:test:<dashboard_id>"
},
"client_id": "…",
"scope": "…",
"authorization_details": […]
...
}

References:

- [Embedding dashboards for external users](https://learn.microsoft.com/en-us/azure/databricks/dashboards/embedding/external-embed)
- [OAuth token federation overview](https://learn.microsoft.com/en-us/azure/databricks/dev-tools/auth/oauth-federation)
- [Configure federation policy](https://learn.microsoft.com/en-us/azure/databricks/dev-tools/auth/oauth-federation-policy)

0 REPLIES 0