How to Set Up Microsoft Entra ID (Azure AD) SSO for Apache Superset

How to Set Up Microsoft Entra ID (Azure AD) SSO for Apache Superset
If your organisation runs on Microsoft 365, Entra ID (the service formerly called Azure Active Directory) is already the source of truth for who works there and what they may access. Superset should read from it rather than keeping its own list of passwords. Flask-AppBuilder, the framework under Superset, has an Azure OAuth handler built in, so the setup is configuration rather than code.

This guide is the Entra-specific companion to our Okta SSO guide. The general mechanics of Superset authentication, the reverse-proxy settings and the break-glass advice are the same and are not repeated in full here. What differs with Entra is the app registration, the way roles reach Superset, and the errors you will see.

The configuration applies to Superset 2.1 through 4.x, written against 4.x.

Groups or app roles?

Entra can put either the user’s group memberships or their app roles into the token. Flask-AppBuilder’s Azure handler reads the roles claim, which is app roles, and uses it as the list of keys to match against AUTH_ROLES_MAPPING.

App roles are also the better design for Superset:

  • No overage problem. Entra stops emitting the groups claim when a user is in more than a couple of hundred groups and replaces it with an overage indicator. Large organisations hit this routinely. App roles are specific to your application and never overflow.
  • Assignment lives on the application. You assign a group or a user to an app role in the Superset enterprise application. The Entra admin sees exactly who can reach Superset and as what, without decoding group names.
  • Role names are yours. Superset.Admin, Superset.Analyst, Superset.Viewer are clearer than a security group created five years ago for something else.

So this guide uses app roles. If you must use groups, the section near the end explains what to change.

Step 1: Register the application

In the Entra admin centre:

  • Go to Identity, Applications, App registrations and choose New registration.
  • Name it “Superset BI”. Under Supported account types choose Accounts in this organizational directory only (single tenant).
  • Under Redirect URI select Web and enter https://superset.example.com/oauth-authorized/azure. The final segment must match the provider name in superset_config.py, which is azure in this guide. Entra compares redirect URIs case-sensitively and exactly, including trailing slashes.
  • Register, then note the Application (client) ID and Directory (tenant) ID from the Overview page.
  • Under Certificates & secrets, create a client secret. Copy the value immediately; it is shown once. Set a calendar reminder for its expiry, because an expired secret is a total login outage.
  • Under Authentication, confirm ID tokens is ticked under implicit grant and hybrid flows. Superset uses the authorization-code flow, but FAB decodes the ID token for the user’s profile, so it must be issued.
  • Under Token configuration, add the optional claims email, family_name, given_name, preferred_username and upn to the ID token. This ensures FAB has a username and a display name even for guest or unusual accounts.

Define app roles

  • Under App roles, choose Create app role.
  • Create three roles with Allowed member types set to Users/Groups:
Display name Value Description
Superset Admin Superset.Admin Full administration
Superset Analyst Superset.Analyst Build charts and dashboards, run SQL
Superset Viewer Superset.Viewer View permitted dashboards

The Value is what appears in the token and what AUTH_ROLES_MAPPING matches.

Assign users and groups

  • Go to Identity, Applications, Enterprise applications, open “Superset BI”, then Users and groups.
  • Add your existing security groups, assigning each to one app role. A user can hold several roles by being in several groups.
  • Under Properties, set Assignment required to Yes. Anyone not assigned is refused by Entra before Superset is involved, which is the behaviour you want.

Step 2: Configure Superset

python
import os
from flask_appbuilder.security.manager import AUTH_OAUTH

AZURE_TENANT_ID = os.environ["AZURE_TENANT_ID"]
AZURE_AUTHORITY = f"https://login.microsoftonline.com/{AZURE_TENANT_ID}"

AUTH_TYPE = AUTH_OAUTH

OAUTH_PROVIDERS = [
    {
        "name": "azure",
        "icon": "fa-windows",
        "token_key": "access_token",
        "remote_app": {
            "client_id": os.environ["AZURE_CLIENT_ID"],
            "client_secret": os.environ["AZURE_CLIENT_SECRET"],
            "api_base_url": f"{AZURE_AUTHORITY}/oauth2",
            "client_kwargs": {
                "scope": "openid profile email User.Read",
            },
            "request_token_url": None,
            "access_token_url": f"{AZURE_AUTHORITY}/oauth2/v2.0/token",
            "authorize_url": f"{AZURE_AUTHORITY}/oauth2/v2.0/authorize",
            "jwks_uri": f"{AZURE_AUTHORITY}/discovery/v2.0/keys",
        },
    }
]

AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Gamma"

# Entra app role value -> Superset roles
AUTH_ROLES_MAPPING = {
    "Superset.Admin": ["Admin"],
    "Superset.Analyst": ["Alpha", "sql_lab"],
    "Superset.Viewer": ["Gamma"],
}
AUTH_ROLES_SYNC_AT_LOGIN = True

# Proxy and cookie settings (same as any OAuth deployment behind TLS termination)
ENABLE_PROXY_FIX = True
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = "Lax"

What is specific to Entra here:

  • The provider name must be azure for FAB’s built-in handler to recognise it and decode the ID token correctly.
  • The URLs are the v2.0 endpoints for your tenant. Do not use the common tenant unless you intend to accept users from any Entra directory, which for an internal BI tool you almost certainly do not.
  • jwks_uri is what FAB uses to verify the ID token signature. It must be the tenant’s discovery keys endpoint.
  • The roles claim is read automatically from the ID token by FAB’s Azure handler; nothing extra to configure.

App roles chosen — RBAC design is next

Entra ID settles who can log in; a Superset Architecture Review settles what capability and data-domain roles they land in, so access control doesn’t get bolted on ad hoc later.

Book a Superset Architecture Review

Step 3: Test

Restart Superset. The login page shows a single “Sign in with azure” button.

  • Sign in as a member of the admin group. Confirm the Admin menu is visible and the user appears in Settings, List Users with the Admin role.
  • In a private window, sign in as a viewer. Confirm only permitted dashboards appear.
  • Move a user between groups in Entra, sign them out and in. Roles should change, which confirms AUTH_ROLES_SYNC_AT_LOGIN.
  • Try a user who is not assigned to the application. Entra should refuse with an “assignment required” message before reaching Superset.

Entra-specific troubleshooting

Symptom Cause Fix
AADSTS50011: The redirect URI ... does not match Redirect URI mismatch, often case or trailing slash Copy the URI exactly; enable ENABLE_PROXY_FIX so Superset sends https://
AADSTS7000215: Invalid client secret Secret value copied wrongly, or the secret ID instead of the value Create a new secret and copy the value column
AADSTS700016: Application not found in the directory Wrong tenant ID in the URLs Use the Directory (tenant) ID from the app Overview page
AADSTS50105: The signed in user is not assigned to a role Assignment required is on and the user is unassigned Assign the user or their group under Enterprise applications
Everyone gets the Gamma role App roles not defined, or user assigned to the app without a role Define app roles and assign groups to specific roles
Login works, user has no name or email Optional claims not configured Add email, given_name, family_name, preferred_username under Token configuration
mismatching_state error Session cookie not returned on callback SESSION_COOKIE_SAMESITE = "Lax", SESSION_COOKIE_SECURE matching the scheme
Logins fail on a Monday morning Client secret expired over the weekend Rotate the secret; set the expiry reminder you skipped last time

If you must use groups instead of app roles

Some organisations mandate group-based access for all applications. Two changes:

  • In the app registration under Token configuration, add a groups claim to the ID token. Choose Groups assigned to the application rather than all security groups, which sidesteps the overage problem for most tenants.
  • Override oauth_user_info in a custom security manager so that role_keys reads the groups claim. Entra emits group object IDs, not names, so the keys in AUTH_ROLES_MAPPING become GUIDs:
python
import jwt
from superset.security import SupersetSecurityManager


class EntraGroupsSecurityManager(SupersetSecurityManager):
    def oauth_user_info(self, provider, response=None):
        if provider != "azure":
            return super().oauth_user_info(provider, response)
        id_token = response["id_token"]
        claims = jwt.decode(id_token, options={"verify_signature": False})
        return {
            "username": claims.get("preferred_username") or claims.get("upn") or claims["oid"],
            "first_name": claims.get("given_name", ""),
            "last_name": claims.get("family_name", ""),
            "email": claims.get("email") or claims.get("preferred_username", ""),
            "role_keys": claims.get("groups", []),
        }


CUSTOM_SECURITY_MANAGER = EntraGroupsSecurityManager

AUTH_ROLES_MAPPING = {
    "5d2f9c1a-...-admins-group-object-id": ["Admin"],
    "8b7e4a3c-...-analysts-group-object-id": ["Alpha", "sql_lab"],
}

The signature is not re-verified here because Authlib has already validated the token during the exchange; the decode is only to read claims. Keep a comment saying so, or the next reviewer will flag it.

Operational notes

  • Secret rotation is the main recurring task. Entra client secrets expire at 6, 12 or 24 months. Put the expiry in the same calendar as your TLS certificates.
  • Conditional Access policies in Entra (MFA, compliant device, location) apply to Superset automatically, which is a strong argument for SSO in regulated environments.
  • Deactivating a user in Entra blocks new logins immediately. Existing Superset sessions last until PERMANENT_SESSION_LIFETIME; keep it to a working day or less.
  • Service accounts that used password login against the Superset API need another path once AUTH_TYPE changes. Plan for it before the cutover.

Frequently Asked Questions

Should Superset roles come from Entra ID groups or app roles?

App roles, in almost every case. Flask-AppBuilder’s Azure handler reads the roles claim, which is populated by app roles, and matches it against AUTH_ROLES_MAPPING without any custom code. App roles also avoid the groups overage problem: Entra stops emitting the groups claim entirely once a user belongs to more than a couple of hundred groups, and replaces it with an overage indicator that Superset cannot use. Groups remain possible, but they need a custom security manager and group object IDs as mapping keys.

Why do all my users land in the Gamma role after Entra ID SSO?

Either no app roles are defined on the registration, or users are assigned to the enterprise application without being assigned to a specific role. Superset is doing what it was told: no roles claim arrives, nothing matches AUTH_ROLES_MAPPING, and AUTH_USER_REGISTRATION_ROLE applies. Check the claim first, by decoding the ID token from a test login, before changing any Superset configuration.

Why does Entra return AADSTS50011 when the redirect URI looks correct?

Entra compares redirect URIs exactly, including case and trailing slashes, and the URI Superset sends is built from the request it received. Behind a TLS-terminating proxy, Superset sends http:// unless ENABLE_PROXY_FIX = True is set, so a URI registered as https://superset.example.com/oauth-authorized/azure never matches. Set the proxy fix, then copy the URI character for character.

Do Entra Conditional Access policies apply to Apache Superset?

Yes. Because the login happens at Entra rather than in Superset, MFA, compliant-device and named-location policies are enforced before a token is ever issued, and Superset inherits them without configuration. That inheritance is one of the stronger arguments for putting Superset behind SSO in a regulated environment. The limit is session lifetime: revoking access in Entra blocks new logins immediately but does not terminate an existing Superset session, so keep PERMANENT_SESSION_LIFETIME short.

Build It With Andolasoft

Entra ID settles who can log in. The role design it feeds, row-level security, the caching and async query setup and upgrade readiness are the rest of the platform, and a Superset Architecture Review checks all of them in five working days with a written report. If the platform should simply be someone else’s problem, Managed Support covers patching, monitoring and the secret-rotation reminders that prevent a Monday-morning outage. For the wider set of controls around a deployment, see governance and security best practices for Superset.

If you are putting Superset behind Entra ID and would rather settle the role model at the same time than six months later, talk to us. We will review your app registration, the claims it emits and your current Superset roles, and give you a fixed-scope plan to a deployment your security team can sign off.