Skip to main content
This guide walks through configuring Azure to trust Cube’s OIDC issuer using federated credentials on an Azure AD app registration, and shows the setup for the most common targets — Azure SQL and an Azure Blob Storage export bucket. If you haven’t enabled OIDC for your tenant yet, start with the OIDC overview.
Available on the Enterprise plan.

Prerequisites

  • The Cube tenant has OIDC enabled and an Azure token config exists under Admin → OIDC.
  • Permissions in your Azure AD tenant sufficient to create an app registration and add federated credentials, plus an Azure subscription where you can grant the app role assignments on resources.
  • Your Cube tenant slug — the leftmost label of your tenant’s console URL. Throughout this guide it’s referenced as <tenant-name> (and the full issuer URL as https://<tenant-name>.cubecloud.dev). Substitute your actual slug everywhere it appears.
Commands and federated-credential snippets in this guide use angle-bracket placeholders — <tenant-name>, <deployment-id>, etc. Replace each placeholder with your real value before running. Azure will accept these strings literally and the federation call will fail with a confusing error.

How Azure federation works

Azure doesn’t have a generic OIDC provider registration the way AWS does. Instead, you configure each app registration (or user-assigned managed identity) with a federated credential that pins the issuer URL, expected aud, and exact sub value. When Cube presents a JWT that matches all three, Azure AD swaps it for an access token scoped to the app registration.
Azure caps you at 20 federated credentials per app registration. For tenants with many deployments, see Scaling past 20 credentials below.

Step 1: Create or pick an app registration

You can use an existing app registration or create a new one — Cube doesn’t have any opinion as long as it has the federated credential and the role assignments.
az ad app create --display-name "Cube Cloud Deployment"
Note the Application (client) ID — this is your AZURE_CLIENT_ID. The Directory (tenant) ID is your AZURE_TENANT_ID. Both are visible in the Azure portal under Microsoft Entra ID → App registrations → Cube Cloud Deployment → Overview.

Step 2: Add a federated credential

The federated credential is what binds the app registration to a specific Cube subject. Each credential matches exactly one issuer + subject + audience triple — Azure doesn’t support wildcards or pattern matching here.
az ad app federated-credential create \
  --id <APP_OBJECT_ID> \
  --parameters '{
    "name": "cube-<tenant-name>-deployment-<deployment-id>",
    "issuer": "https://<tenant-name>.cubecloud.dev",
    "subject": "cube:deployment:<deployment-id>:component:cube_api",
    "audiences": ["api://AzureADTokenExchange"]
  }'
FieldValue
issuerYour Cube tenant’s URL: https://<tenant-name>.cubecloud.dev.
subjectThe exact sub claim Cube emits — typically cube:deployment:<deployment-id>:component:<component>.
audiencesAlways ["api://AzureADTokenExchange"] — this is the standard Azure AD token-exchange audience.
nameA human-readable label. Pick something that lets you find this credential later.
Each Cube component you want this app to authenticate as needs its own federated credential. So if a deployment runs both Cube API and Cube Store against the same Azure resource, you create two credentials — one with subject ending in :component:cube_api and one ending in :component:cube_store. Cube’s default sub claim is cube:deployment:<deployment_id>. To match the :component:<component> examples in this guide (or to add :region:<region>), open your Azure token config in Admin → OIDC and paste one of these templates into the Subject Claim Format field:
  • cube:deployment:{deployment_id}:component:{component} — for the cube:deployment:<deployment-id>:component:<component> examples below.
  • cube:deployment:{deployment_id}:component:{component}:region:{region} — to additionally pin a Cube Cloud region.
See the subject editor section for the full syntax.
Azure pins the federated credential’s subject field literally — changing the format means recreating every federated credential that references it. Create the new federated credential first, then change the Subject Claim Format on the token config.

Step 3: Set the deployment identity

Add two env vars to your deployment under Settings → Environment variables:
AZURE_TENANT_ID=00000000-0000-0000-0000-000000000000
AZURE_CLIENT_ID=11111111-1111-1111-1111-111111111111
  • AZURE_TENANT_ID — the Microsoft Entra ID (Azure AD) tenant where your app registration lives.
  • AZURE_CLIENT_ID — the Application (client) ID of the app registration.

Step 4: Assign roles on Azure resources

Grant the app registration the standard Azure RBAC roles it needs, the same way you’d grant any service principal access to a resource. Examples follow per target.

Azure SQL

1

Create the federated credential

See Step 2 — pin subject to cube:deployment:<deployment-id>:component:cube_api.
2

Create a contained user in Azure SQL

Connect to your Azure SQL database as an Entra-authenticated admin and create a user backed by the app registration:
CREATE USER [Cube Cloud Deployment] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [Cube Cloud Deployment];
GRANT EXECUTE ON SCHEMA::dbo TO [Cube Cloud Deployment];
The user name must match the app registration’s display name.
3

Configure the deployment

Set the MSSQL driver and identity env vars on the deployment:
CUBEJS_DB_TYPE=mssql
CUBEJS_DB_HOST=my-server.database.windows.net
CUBEJS_DB_NAME=my-db
CUBEJS_DB_PORT=1433
AZURE_TENANT_ID=00000000-0000-0000-0000-000000000000
AZURE_CLIENT_ID=11111111-1111-1111-1111-111111111111
The MSSQL driver uses the azure-active-directory-access-token auth type with the federated token Cube provides. No username, password, or client secret needed.

Azure Blob Storage export bucket

If your data source uses an export bucket for pre-aggregation unloads, grant the app registration Storage Blob Data Contributor on the storage account.
1

Grant role assignment

Assign Storage Blob Data Contributor on the storage account scope:
az role assignment create \
  --assignee <APP_CLIENT_ID> \
  --role "Storage Blob Data Contributor" \
  --scope "/subscriptions/<SUB_ID>/resourceGroups/<RG>/providers/Microsoft.Storage/storageAccounts/<ACCOUNT>"
For tighter scoping, narrow to a specific container with .../blobServices/default/containers/<container> instead of the whole storage account.
2

Configure the export bucket env vars

Point the export bucket env vars at your container:
CUBEJS_DB_EXPORT_BUCKET_TYPE=azure
CUBEJS_DB_EXPORT_BUCKET=https://<account>.blob.core.windows.net/<container>
AZURE_TENANT_ID=00000000-0000-0000-0000-000000000000
AZURE_CLIENT_ID=11111111-1111-1111-1111-111111111111
The Azure storage client picks up the same federated identity. See the export bucket reference for the full set of variables.
OIDC only covers Cube’s read side of the export bucket. The data warehouse itself (Snowflake on Azure, Synapse, …) runs the UNLOAD that writes objects to Blob Storage, and the warehouse cannot federate with Cube’s OIDC issuer. You still need to provide separate credentials for the unload so the warehouse can write to the container — typically a storage account key, SAS token, or a warehouse-side storage integration — via the standard export bucket env vars (e.g. CUBEJS_DB_EXPORT_BUCKET_AZURE_KEY, or the driver-specific storage-integration variables). OIDC then handles Cube’s download of the unloaded objects from the bucket.

Azure Blob Storage CSPS bucket

Cube Store CSPS lets you store pre-aggregations in your own Azure Blob Storage container. Cube Store gets a separate OIDC token whose sub claim ends in component:cube_store, so the federated credential can be locked down to that component — even if the same app registration were shared with the rest of the deployment, only Cube Store would match. Every Cube Store worker emits a sub of the form cube:deployment:<deployment-id>:component:cube_store. Unlike AWS IAM — which matches sub with a StringLike wildcard, so one role can cover the whole tenant — Azure pins the federated credential’s subject literally and has no tenant-wide *. So CSPS on Azure is per deployment: each deployment that writes pre-aggregations to the container needs its own federated credential carrying that deployment’s exact sub. If you expect many deployments, mind the 20-credential limit and see Scaling past 20 federated credentials.
1

Create the Cube Store federated credential

Add a federated credential on the app registration, pinning the subject to the deployment’s Cube Store component:
az ad app federated-credential create \
  --id <APP_OBJECT_ID> \
  --parameters '{
    "name": "cube-<tenant-name>-deployment-<deployment-id>-cube-store",
    "issuer": "https://<tenant-name>.cubecloud.dev",
    "subject": "cube:deployment:<deployment-id>:component:cube_store",
    "audiences": ["api://AzureADTokenExchange"]
  }'
Make sure the Azure token config’s Subject Claim Format includes the :component: segment (cube:deployment:{deployment_id}:component:{component}) — see Step 2 — otherwise the Cube Store sub won’t match this credential.
2

Grant the container permissions

Grant the app registration Storage Blob Data Contributor so Cube Store can read, write, and list pre-aggregation blobs. Scope it to the container for tightest isolation:
az role assignment create \
  --assignee <APP_CLIENT_ID> \
  --role "Storage Blob Data Contributor" \
  --scope "/subscriptions/<SUB_ID>/resourceGroups/<RG>/providers/Microsoft.Storage/storageAccounts/<ACCOUNT>/blobServices/default/containers/<container>"
Use the storage account scope (drop the /blobServices/default/containers/<container> suffix) if you’d rather one assignment cover multiple containers.
3

Enable CSPS on each deployment

For each deployment that should use this container, go to Settings → Pre-Aggregation Storage on the deployment and:
  • Toggle Enable CSPS on.
  • Storage Provider: Azure Blob Storage.
  • Storage Account: <account>.
  • Container: <container>.
  • Client ID: the app registration’s Application (client) ID.
  • Tenant ID: the Microsoft Entra ID (Azure AD) directory ID.
Click Test Connection to verify Cube Store can exchange its OIDC token with Azure AD and access the container, then Apply. Cube Store starts writing pre-aggregations to your container on the next refresh.

Scaling past 20 federated credentials

A single app registration accepts at most 20 federated credentials. Three patterns cover most growth scenarios:
  • One app registration per deployment. Each deployment gets its own app + role assignments. Clean isolation, but you have to provision a new app every time you add a deployment.
  • Multiple app registrations behind one set of role assignments. Group deployments by access pattern (e.g. read-only vs read-write); each group gets its own app, and the role assignments target the same resources.
  • User-assigned managed identities. Each managed identity has its own 20-credential limit, and you can attach many of them to your tenant. Useful when you want the resource permissions managed in Azure alongside other infrastructure rather than as RBAC on app registrations.
If you expect more than ~10 deployments in a single tenant, plan for one of these patterns up front — splitting later is a recreation, not a migration.

Verifying the setup

The fastest way to confirm the federated credential is wired up correctly is the Test connection button on the relevant settings page (data source wizard, BYO LLM provider). Behind the scenes, Cube issues a real OIDC token, exchanges it with Azure AD, and returns a precise error if anything is misconfigured. If the test fails:
SymptomLikely cause
AADSTS70021: No matching federated identity record foundThe federated credential’s issuer, subject, and audiences triple doesn’t match the JWT exactly. Compare with the iss / sub / aud of a token from the Test connection error response.
AADSTS700213: No matching federated identity record found ... subjectThe subject claim differs by even a single character. Azure doesn’t support wildcards — you need one credential per exact subject.
AADSTS50034: The user account does not existYou’re using the wrong AZURE_TENANT_ID. Double-check the directory ID on the app registration’s Overview blade.
AADSTS500011: The resource principal ... was not foundThe role assignment hasn’t been created on the target resource, or it’s still propagating. Wait a minute and retry; if it persists, re-check the --assignee and --scope values.
Federation events show up in Microsoft Entra ID → Sign-in logs under the Service principal sign-ins tab — filter by the app registration to see which deployments are authenticating, when, and which resources they hit.