PADISO.ai: AI Agent Orchestration Platform - Launching April 2026
Back to Blog
Guide 5 mins

SSO and SAML in Apache Superset: Enterprise Auth Done Right

Configure SSO and SAML in Apache Superset with Okta, Azure AD, and Google Workspace. Enterprise authentication, role mapping, and compliance-ready setup.

Padiso Team ·2026-04-17

SSO and SAML in Apache Superset: Enterprise Auth Done Right

Table of Contents

  1. Why SSO and SAML Matter for Enterprise Superset Deployments
  2. Understanding SAML and SSO Fundamentals
  3. Architecture and Prerequisites
  4. Configuring Apache Superset for SAML
  5. Okta Integration: Step-by-Step
  6. Azure AD Integration: Step-by-Step
  7. Google Workspace Integration: Step-by-Step
  8. Role Mapping and Access Control
  9. Security Hardening and Compliance
  10. Troubleshooting Common Issues
  11. Monitoring and Maintenance
  12. Next Steps and Recommendations

Why SSO and SAML Matter for Enterprise Superset Deployments

Apache Superset has become the analytics backbone for hundreds of organisations worldwide, but out-of-the-box authentication leaves you exposed. Default username-and-password logins create security debt, audit friction, and operational headaches at scale.

Enterprise teams need single sign-on (SSO) and SAML integration not as a nice-to-have, but as a non-negotiable baseline. Here’s why:

Security and access control: SSO eliminates password fatigue and reduces credential sprawl. When an employee leaves, you revoke access once in your identity provider (IdP)—not across a dozen tools. SAML assertions carry cryptographically signed identity claims, making token spoofing or man-in-the-middle attacks exponentially harder.

Compliance and audit readiness: SOC 2 and ISO 27001 auditors expect federated identity management with audit trails. SAML logs every authentication event. If you’re pursuing Security Audit via Vanta for SOC 2 and ISO 27001 compliance, SAML integration is table stakes.

Operational velocity: No more password resets, no more forgotten credentials. Your team logs into Superset the same way they log into Slack, Jira, and Gmail. Onboarding and offboarding become one-click events in your identity provider.

Role and permission synchronisation: SAML carries group membership and custom attributes. You can map Okta groups directly to Superset roles, ensuring data access follows org structure automatically.

At PADISO, we’ve configured Superset SSO for 50+ clients across finance, insurance, healthcare, and e-commerce. The difference between a secure, auditable deployment and a security nightmare is three to four days of careful setup. This guide walks you through it.


Understanding SAML and SSO Fundamentals

Before you configure anything, understand what you’re building.

What Is SAML?

SAML (Security Assertion Markup Language) is an XML-based protocol for exchanging authentication and authorisation data between an identity provider (IdP) and a service provider (SP).

In plain terms: Your identity provider (Okta, Azure AD, Google Workspace) is the trusted authority. Apache Superset is the application you want to protect. When a user tries to log into Superset, Superset redirects them to the IdP. The IdP verifies their identity, then sends a cryptographically signed SAML assertion back to Superset saying, “Yes, this is Alice from Engineering, she’s in the Finance and Admin groups.” Superset trusts that assertion and logs them in.

SAML 2.0 is the current standard. It uses XML, digital signatures, and HTTP redirects—not JSON or OAuth. That distinction matters for implementation.

SSO vs SAML: What’s the Difference?

SSO (Single Sign-On) is the user experience: log in once, access many systems. SAML is one protocol that enables SSO. You could also use OAuth 2.0 or OpenID Connect, but SAML is the enterprise standard because it was built for this use case.

The SAML Flow in Three Steps

  1. User initiates login: Alice visits superset.yourcompany.com and clicks “Login with SAML.”
  2. Superset redirects to IdP: Superset generates a SAML AuthnRequest and redirects Alice to Okta (or Azure AD, or Google). The request includes Superset’s entity ID and assertion consumer service (ACS) URL.
  3. IdP authenticates and asserts: Okta verifies Alice’s password (or uses MFA), then sends a signed SAML response back to Superset’s ACS endpoint. The response contains Alice’s username, email, groups, and any custom attributes.
  4. Superset validates and logs in: Superset verifies the SAML signature using Okta’s public certificate, extracts Alice’s identity and groups, creates a session, and grants access.

This entire flow takes milliseconds. The user sees a seamless redirect and ends up logged into Superset without ever entering a password.


Architecture and Prerequisites

What You Need Before Starting

On the Superset side:

  • Apache Superset 2.0 or later (earlier versions require additional patching)
  • Admin access to Superset’s configuration
  • Ability to modify superset_config.py or environment variables
  • Python packages: python3-saml and flask-appbuilder (already included in Superset)
  • A public URL for Superset (SAML requires HTTPS and a valid domain)

On the IdP side:

  • Admin access to your identity provider (Okta, Azure AD, or Google Workspace)
  • Ability to create SAML applications
  • Ability to manage groups and attribute mappings

Network and DNS:

  • Superset must be accessible from your IdP over HTTPS
  • Your IdP must be accessible from Superset (for metadata retrieval)
  • Valid SSL certificate for your Superset domain

High-Level Architecture

┌─────────────────────────────────────────────────────────────────┐
│ User's Browser                                                  │
│ Visits: https://superset.yourcompany.com                        │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ Apache Superset (Service Provider)                              │
│ - Detects unauthenticated user                                  │
│ - Generates SAML AuthnRequest                                   │
│ - Redirects to IdP                                              │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ Identity Provider (Okta / Azure AD / Google)                    │
│ - Authenticates user (password + MFA if enabled)                │
│ - Looks up user groups and attributes                           │
│ - Generates signed SAML Response                                │
│ - Redirects back to Superset ACS URL                            │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│ Apache Superset ACS Endpoint                                    │
│ - Receives SAML Response                                        │
│ - Validates signature using IdP certificate                     │
│ - Extracts username, email, groups                              │
│ - Maps groups to Superset roles                                 │
│ - Creates session and grants access                             │
└─────────────────────────────────────────────────────────────────┘

This architecture ensures zero passwords are transmitted to Superset, and all identity decisions remain in your IdP where they belong.


Configuring Apache Superset for SAML

Apache Superset uses Flask-AppBuilder for authentication. Flask-AppBuilder has built-in SAML support via the python3-saml library. The official Configuring Superset documentation covers the basics, but we’ll go deeper.

Step 1: Install Dependencies

If you’re running Superset in a container or virtual environment, ensure python3-saml is installed:

pip install python3-saml

If you installed Superset via pip, this is already included. If you’re using Docker, add it to requirements.txt or your Dockerfile.

Step 2: Create SAML Configuration File

SAML configuration lives in a settings.json file. Create a file at /path/to/superset/saml_settings.json:

{
  "sp": {
    "entityID": "https://superset.yourcompany.com/metadata/",
    "assertionConsumerService": {
      "url": "https://superset.yourcompany.com/acs/",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
    },
    "singleLogoutService": {
      "url": "https://superset.yourcompany.com/sls/",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    },
    "x509cert": "",
    "privateKey": ""
  },
  "idp": {
    "entityID": "https://your-idp.com/metadata/",
    "singleSignOnService": {
      "url": "https://your-idp.com/app/123/sso/saml",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    },
    "singleLogoutService": {
      "url": "https://your-idp.com/app/123/slo/saml",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    },
    "x509cert": "PASTE_IDP_CERTIFICATE_HERE"
  },
  "security": {
    "nameIdEncrypted": false,
    "authnRequestsSigned": false,
    "wantAssertionsSigned": true,
    "wantResponseSigned": true,
    "signMetadata": false,
    "wantNameId": true,
    "wantNameIdEncrypted": false,
    "requestedAuthnContext": true,
    "requestedAuthnContextComparison": "exact"
  }
}

We’ll populate the IdP-specific details in the next sections. For now, understand the key fields:

  • sp.entityID: Unique identifier for Superset in the SAML ecosystem. Convention is your domain + /metadata/.
  • sp.assertionConsumerService.url: Where the IdP sends the SAML response. This must be publicly accessible and match your IdP configuration.
  • idp.x509cert: The public certificate from your IdP. This is used to verify SAML responses are genuine.
  • security.wantResponseSigned and wantAssertionsSigned: Require cryptographic signatures. Always set to true in production.

Step 3: Configure Superset to Use SAML

Edit superset_config.py (or create environment variables if you’re using Docker). Add:

import os
from flask_appbuilder.security.manager import AUTH_SAML

# Enable SAML authentication
AUTH_TYPE = AUTH_SAML

# Path to SAML settings file
SAML_SETTINGS_FILE = '/path/to/superset/saml_settings.json'

# Metadata cache timeout (in seconds)
SAML_METADATA_CACHE_TIMEOUT = 3600

# Custom security manager for role mapping (we'll define this next)
SECURITY_MANAGER_CLASS = 'superset.security.SamlSecurityManager'

# Redirect to SAML login by default
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = 'Viewer'  # Default role for new users

# Optional: Enable SAML metadata endpoint
SAML_METADATA_EXPOSED = True

If you’re running Superset in Docker, set these as environment variables:

export AUTH_TYPE=AUTH_SAML
export SAML_SETTINGS_FILE=/etc/superset/saml_settings.json
export SECURITY_MANAGER_CLASS=superset.security.SamlSecurityManager

Step 4: Create a Custom Security Manager for Role Mapping

The standard SAML integration gets you authenticated, but role mapping requires a custom security manager. Create /path/to/superset/security.py:

from flask_appbuilder.security.sqla.models import User, Role
from flask_appbuilder.security.manager import AbstractSecurityManager
from superset.security import SupersetSecurityManager
from flask import g

class SamlSecurityManager(SupersetSecurityManager):
    """
    Custom security manager that maps SAML groups to Superset roles.
    """

    def get_user_from_saml_attributes(self, saml_attributes):
        """
        Extract user info from SAML attributes and map groups to roles.
        """
        # Extract email (or username) from SAML attributes
        email = saml_attributes.get('email', [''])[0]
        username = saml_attributes.get('uid', [email])[0]
        first_name = saml_attributes.get('firstName', [''])[0]
        last_name = saml_attributes.get('lastName', [''])[0]
        
        # Get groups from SAML (group attribute name depends on your IdP)
        saml_groups = saml_attributes.get('groups', [])
        
        # Find or create user
        user = self.find_user(username=username)
        if not user:
            user = self.add_user(
                username=username,
                email=email,
                first_name=first_name,
                last_name=last_name
            )
        
        # Map SAML groups to Superset roles
        self.update_user_roles(user, saml_groups)
        
        return user

    def update_user_roles(self, user, saml_groups):
        """
        Map SAML groups to Superset roles.
        """
        # Define your group-to-role mapping
        group_role_mapping = {
            'okta_superset_admins': 'Admin',
            'okta_superset_editors': 'Editor',
            'okta_superset_viewers': 'Viewer',
            'okta_data_analysts': 'Editor',
            'okta_finance': 'Viewer',
        }
        
        # Clear existing roles (optional; adjust based on your policy)
        user.roles = []
        
        # Assign roles based on group membership
        for saml_group in saml_groups:
            if saml_group in group_role_mapping:
                role_name = group_role_mapping[saml_group]
                role = self.find_role(role_name)
                if role and role not in user.roles:
                    user.roles.append(role)
        
        # If no role was assigned, assign default
        if not user.roles:
            default_role = self.find_role('Viewer')
            user.roles.append(default_role)
        
        self.update_user(user)

This custom manager intercepts SAML authentication, extracts groups from the SAML response, and automatically assigns Superset roles. No manual role management needed.

Step 5: Verify Superset Metadata

Once configured, Superset exposes its SAML metadata at:

https://superset.yourcompany.com/metadata/

Visit this URL in your browser. You should see XML containing your entity ID, ACS URL, and certificate. This is what you’ll paste into your IdP configuration.

If you see a 404, check that SAML_METADATA_EXPOSED = True is set in your config and Superset has restarted.


Okta Integration: Step-by-Step

Okta is the most common enterprise identity provider. Here’s how to configure it.

Step 1: Create a SAML Application in Okta

  1. Log into your Okta admin console
  2. Navigate to Applications > Applications and click Create App Integration
  3. Choose SAML 2.0
  4. Fill in the app name (e.g., “Apache Superset”)
  5. Click Next

Step 2: Configure SAML Settings in Okta

On the “Configure SAML” page, fill in:

Single sign on URL: https://superset.yourcompany.com/acs/

Audience URI (SP Entity ID): https://superset.yourcompany.com/metadata/

Name ID format: Select EmailAddress

Application username: Select Okta username

Leave other fields at defaults unless you have specific requirements. Click Next.

Step 3: Configure Attribute Statements

Attribute statements map Okta user properties to SAML assertion attributes. Add:

| Name | Value | |------|-------| | email | user.email | | uid | user.login | | firstName | user.firstName | | lastName | user.lastName | | groups | getFilteredGroups(“okta_superset.*”, “regex”) |

The groups attribute is critical. The expression getFilteredGroups("okta_superset.", "regex") will include all Okta groups matching the pattern okta_superset_ (e.g., okta_superset_admins, okta_superset_editors). This is how group membership flows into Superset.

Click Next.

Step 4: Assign Groups and Users

On the “Assign to People and Groups” page, select which Okta groups should have access to Superset. Typically:

  • okta_superset_admins → Admin role
  • okta_superset_editors → Editor role
  • okta_superset_viewers → Viewer role

You can also assign individual users. Click Finish.

Step 5: Download Okta’s Certificate and Metadata

After creating the app, you’ll see a “Sign On” tab. Scroll down to the SAML Signing Certificates section. Download the certificate (usually in .pem or .crt format).

Also note the Identity Provider metadata URL (looks like https://yourcompany.okta.com/app/abc123/sso/saml/metadata).

Step 6: Update Superset’s SAML Configuration

Edit /path/to/superset/saml_settings.json with Okta’s details:

{
  "sp": {
    "entityID": "https://superset.yourcompany.com/metadata/",
    "assertionConsumerService": {
      "url": "https://superset.yourcompany.com/acs/",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
    },
    "singleLogoutService": {
      "url": "https://superset.yourcompany.com/sls/",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    }
  },
  "idp": {
    "entityID": "http://www.okta.com/abc123",
    "singleSignOnService": {
      "url": "https://yourcompany.okta.com/app/abc123/sso/saml",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    },
    "singleLogoutService": {
      "url": "https://yourcompany.okta.com/app/abc123/slo/saml",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    },
    "x509cert": "PASTE_OKTA_CERTIFICATE_HERE"
  },
  "security": {
    "nameIdEncrypted": false,
    "authnRequestsSigned": false,
    "wantAssertionsSigned": true,
    "wantResponseSigned": true,
    "signMetadata": false,
    "wantNameId": true,
    "wantNameIdEncrypted": false,
    "requestedAuthnContext": true,
    "requestedAuthnContextComparison": "exact"
  }
}

For x509cert, paste the certificate content (without the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- lines).

Step 7: Test the Integration

Restart Superset and visit the login page. You should see a “Login with SAML” button. Click it, and you’ll be redirected to Okta. Log in with your Okta credentials, and you should be redirected back to Superset and logged in.

If it fails, check the Apache Superset SSO Integration Guide for common troubleshooting steps.


Azure AD Integration: Step-by-Step

Azure AD (now Microsoft Entra ID) is prevalent in Microsoft-heavy organisations. The setup is similar to Okta but with Azure-specific quirks.

Step 1: Register Superset as an Enterprise Application

  1. Log into the Azure portal
  2. Navigate to Azure Active Directory > Enterprise applications
  3. Click New application
  4. Search for SAML or choose Create your own application
  5. Select Integrate any other application you don’t find in the gallery
  6. Name it “Apache Superset” and click Create

Step 2: Configure Single Sign-On

In the app’s Single sign-on section, select SAML.

On the “Set up Single Sign-On with SAML” page:

1. Basic SAML Configuration:

  • Identifier (Entity ID): https://superset.yourcompany.com/metadata/
  • Reply URL (Assertion Consumer Service URL): https://superset.yourcompany.com/acs/
  • Sign on URL: https://superset.yourcompany.com/
  • Relay State (optional): Leave blank

2. SAML Certificates:

Download the Certificate (Base64) and note the Login URL and Azure AD Identifier.

Step 3: Configure Attribute Mappings

In the User Attributes & Claims section, edit the mappings:

Azure AD uses different claim names by default. Map them to what Superset expects:

| Claim Name | Source Attribute | |------------|------------------| | email | user.mail | | uid | user.userprincipalname | | firstName | user.givenname | | lastName | user.surname | | groups | user.groups |

For groups, you may need to add a custom claim. Click Add a group claim and select All groups or Groups assigned to the application.

Step 4: Configure Group Assignments

In the app’s Users and groups section, assign Azure AD groups to Superset. Create or use existing groups like:

  • Superset-Admins
  • Superset-Editors
  • Superset-Viewers

Assign users to these groups in Azure AD.

Step 5: Update Superset’s SAML Configuration

Edit /path/to/superset/saml_settings.json:

{
  "sp": {
    "entityID": "https://superset.yourcompany.com/metadata/",
    "assertionConsumerService": {
      "url": "https://superset.yourcompany.com/acs/",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
    },
    "singleLogoutService": {
      "url": "https://superset.yourcompany.com/sls/",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    }
  },
  "idp": {
    "entityID": "https://sts.windows.net/YOUR_TENANT_ID/",
    "singleSignOnService": {
      "url": "https://login.microsoftonline.com/YOUR_TENANT_ID/saml2",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    },
    "singleLogoutService": {
      "url": "https://login.microsoftonline.com/YOUR_TENANT_ID/saml2",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    },
    "x509cert": "PASTE_AZURE_CERTIFICATE_HERE"
  },
  "security": {
    "nameIdEncrypted": false,
    "authnRequestsSigned": false,
    "wantAssertionsSigned": true,
    "wantResponseSigned": false,
    "signMetadata": false,
    "wantNameId": true,
    "wantNameIdEncrypted": false,
    "requestedAuthnContext": true,
    "requestedAuthnContextComparison": "exact"
  }
}

Note: Azure AD doesn’t sign the entire response, only the assertion. Set wantResponseSigned to false.

Also update your custom security manager to map Azure group names:

group_role_mapping = {
    'Superset-Admins': 'Admin',
    'Superset-Editors': 'Editor',
    'Superset-Viewers': 'Viewer',
}

Step 6: Test the Integration

Restart Superset and test login. Azure AD’s redirect flow is slightly different from Okta, but the user experience is identical.

For detailed Azure AD SAML troubleshooting, refer to Microsoft’s official SAML documentation.


Google Workspace Integration: Step-by-Step

Google Workspace is simpler than Okta or Azure AD but less flexible for complex role mappings. Here’s how to set it up.

Step 1: Enable SAML in Google Workspace

  1. Log into Google Admin Console
  2. Navigate to Apps > Web and mobile apps > Custom SAML apps
  3. Click Create New Custom SAML App

Step 2: Configure SAML Details

On the “Enter Basic Information” page, name the app “Apache Superset” and click Continue.

On the “Google IdP Information” page, download the metadata XML file and note the SSO URL and Certificate.

Click Continue.

Step 3: Fill in Service Provider Details

ACS URL: https://superset.yourcompany.com/acs/

Entity ID: https://superset.yourcompany.com/metadata/

Name ID format: Select EMAIL

Name ID: Select Primary email

Click Continue.

Step 4: Map Attributes

Google Workspace has limited attribute mapping. Map:

| Google Directory Attribute | App Attribute | |----------------------------|---------------| | Primary Email | email | | First Name | firstName | | Last Name | lastName |

Google Workspace doesn’t natively support group claims in SAML. If you need group-based role mapping, you’ll need to use a custom attribute or manage roles manually in Superset.

Click Finish.

Step 5: Assign Organisations or Users

In the app’s settings, assign which Google Workspace organisations or users have access. You can restrict to specific OUs.

Step 6: Update Superset’s SAML Configuration

Edit /path/to/superset/saml_settings.json:

{
  "sp": {
    "entityID": "https://superset.yourcompany.com/metadata/",
    "assertionConsumerService": {
      "url": "https://superset.yourcompany.com/acs/",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
    },
    "singleLogoutService": {
      "url": "https://superset.yourcompany.com/sls/",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    }
  },
  "idp": {
    "entityID": "https://accounts.google.com/o/saml2?idpid=YOUR_IDP_ID",
    "singleSignOnService": {
      "url": "https://accounts.google.com/o/saml2/idp?idpid=YOUR_IDP_ID",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    },
    "singleLogoutService": {
      "url": "https://accounts.google.com/logout",
      "binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
    },
    "x509cert": "PASTE_GOOGLE_CERTIFICATE_HERE"
  },
  "security": {
    "nameIdEncrypted": false,
    "authnRequestsSigned": false,
    "wantAssertionsSigned": true,
    "wantResponseSigned": true,
    "signMetadata": false,
    "wantNameId": true,
    "wantNameIdEncrypted": false,
    "requestedAuthnContext": false,
    "requestedAuthnContextComparison": "exact"
  }
}

Get your YOUR_IDP_ID from the Google Admin Console’s SAML app settings.

Step 7: Test the Integration

Restart Superset and test. Google Workspace SAML is reliable but less feature-rich than Okta or Azure AD.


Role Mapping and Access Control

SSO authentication alone doesn’t solve access control. You need intelligent role mapping so that Okta groups automatically become Superset roles.

Why Role Mapping Matters

Without role mapping:

  • Every new employee needs manual role assignment in Superset
  • When an employee changes teams, their Superset role doesn’t update
  • Offboarding requires manual cleanup
  • Audit trails are fragmented across systems

With role mapping:

  • Superset roles sync automatically from your IdP
  • Org changes propagate instantly
  • Offboarding is one click in your IdP
  • Audit trails are centralised

Implementing Role Mapping

We covered the custom security manager earlier. Here’s a production-ready version:

from flask_appbuilder.security.sqla.models import User, Role
from superset.security import SupersetSecurityManager
from flask import g, session
import logging

logger = logging.getLogger(__name__)

class SamlSecurityManager(SupersetSecurityManager):
    """
    SAML security manager with group-to-role mapping.
    """

    # Define your group-to-role mappings here
    GROUP_ROLE_MAPPING = {
        'okta_superset_admins': ['Admin'],
        'okta_superset_editors': ['Editor'],
        'okta_superset_viewers': ['Viewer'],
        'okta_data_analysts': ['Editor', 'Viewer'],
        'okta_finance_team': ['Viewer'],
    }

    def get_user_from_saml_attributes(self, saml_attributes):
        """
        Extract and sync user from SAML attributes.
        Called by Flask-AppBuilder during SAML login.
        """
        # Extract core user info
        email = saml_attributes.get('email', [''])[0]
        username = saml_attributes.get('uid', [email])[0]
        first_name = saml_attributes.get('firstName', [''])[0]
        last_name = saml_attributes.get('lastName', [''])[0]
        
        if not username or not email:
            logger.error(f"SAML attributes missing username or email: {saml_attributes}")
            return None
        
        # Find or create user
        user = self.find_user(username=username)
        if not user:
            logger.info(f"Creating new user from SAML: {username}")
            user = self.add_user(
                username=username,
                email=email,
                first_name=first_name,
                last_name=last_name,
                active=True
            )
        else:
            # Update user info if changed
            user.email = email
            user.first_name = first_name
            user.last_name = last_name
            user.active = True
            self.update_user(user)
        
        # Extract and map groups
        saml_groups = saml_attributes.get('groups', [])
        if isinstance(saml_groups, str):
            saml_groups = [saml_groups]
        
        logger.info(f"User {username} has SAML groups: {saml_groups}")
        
        # Update roles based on group membership
        self._sync_user_roles(user, saml_groups)
        
        return user

    def _sync_user_roles(self, user, saml_groups):
        """
        Sync Superset roles based on SAML group membership.
        """
        # Collect roles from all matching groups
        target_roles = set()
        for saml_group in saml_groups:
            if saml_group in self.GROUP_ROLE_MAPPING:
                target_roles.update(self.GROUP_ROLE_MAPPING[saml_group])
        
        # If no roles matched, assign default
        if not target_roles:
            logger.warning(f"User {user.username} matched no role groups. Assigning default 'Viewer'.")
            target_roles.add('Viewer')
        
        # Get role objects
        role_objects = []
        for role_name in target_roles:
            role = self.find_role(role_name)
            if role:
                role_objects.append(role)
            else:
                logger.error(f"Role '{role_name}' not found in Superset")
        
        # Update user roles
        user.roles = role_objects
        self.update_user(user)
        logger.info(f"Updated roles for {user.username}: {[r.name for r in user.roles]}")

    def post_login(self, user, is_login_fragment=False):
        """
        Called after successful login. Log the event for compliance.
        """
        logger.info(f"User {user.username} logged in via SAML")
        return super().post_login(user, is_login_fragment)

This implementation:

  1. Auto-creates users from SAML attributes
  2. Maps groups to roles using a configurable dictionary
  3. Syncs roles on every login (so org changes take effect immediately)
  4. Logs everything for compliance audits
  5. Handles missing groups gracefully with a default role

Testing Role Mapping

To test:

  1. Create a test user in your IdP and add them to okta_superset_viewers
  2. Log in to Superset via SAML
  3. Check the Superset admin panel—the user should have the Viewer role
  4. Add that user to okta_superset_editors in your IdP
  5. Log out and log back in
  6. The user should now have the Editor role

If roles don’t update, check Superset’s logs for errors in _sync_user_roles.


Security Hardening and Compliance

SSO and SAML are secure by design, but a few extra steps ensure production readiness.

Enable Signed Requests

By default, Superset sends unsigned SAML AuthnRequests. For maximum security, sign them:

  1. Generate a self-signed certificate for Superset:
openssl req -new -x509 -days 3650 -nodes -out /etc/superset/sp.crt -keyout /etc/superset/sp.key
  1. Add to saml_settings.json:
"sp": {
  "x509cert": "PASTE_CONTENT_OF_sp.crt",
  "privateKey": "PASTE_CONTENT_OF_sp.key"
}
  1. Set in superset_config.py:
SAML_SETTINGS_FILE = '/etc/superset/saml_settings.json'
  1. Update your IdP to expect signed requests (optional but recommended).

Enforce HTTPS

SAML requires HTTPS. Ensure:

  • Superset has a valid SSL certificate
  • Redirect HTTP to HTTPS
  • Set PREFERRED_URL_SCHEME = 'https' in superset_config.py

Implement Session Timeout

Long-lived sessions increase risk. Set:

SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Lax'
PERMANENT_SESSION_LIFETIME = 3600  # 1 hour

Enable Audit Logging

Superset logs authentication events. Ensure logs are:

  • Centralised (e.g., sent to a SIEM)
  • Retained for 90+ days
  • Immutable

Configure logging in superset_config.py:

import logging
from logging.handlers import SysLogHandler

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

# Send logs to syslog for centralised collection
syslog_handler = SysLogHandler(address=('localhost', 514))
logging.getLogger('superset').addHandler(syslog_handler)

Regular Certificate Rotation

IdP certificates expire. Set a calendar reminder to:

  1. Check certificate expiry dates quarterly
  2. Download new certificates 30 days before expiry
  3. Update saml_settings.json and restart Superset

Many IdPs (Okta, Azure AD) allow automatic certificate rotation via metadata endpoints. If your IdP supports it, use metadata URLs instead of static certificates:

"idp": {
  "entityID": "https://your-idp.com/metadata/",
  "singleSignOnService": {
    "url": "https://your-idp.com/sso"
  }
}

Set in superset_config.py:

SAML_METADATA_URL = 'https://your-idp.com/saml/metadata'

Compliance Readiness

If you’re pursuing SOC 2 or ISO 27001 compliance, SAML integration ticks several boxes. Document:

  1. Authentication mechanism: SAML 2.0 with signed assertions
  2. Audit logging: All login attempts logged with timestamps and outcomes
  3. Access control: Roles automatically synced from identity provider
  4. Encryption: HTTPS in transit, no passwords stored
  5. Certificate management: Rotation schedule documented

For a complete Security Audit and compliance roadmap via Vanta, SAML integration is one of several controls. Pair it with encrypted backups, network segmentation, and incident response procedures.


Troubleshooting Common Issues

Issue 1: “Invalid SAML Response” or Signature Validation Fails

Cause: IdP certificate mismatch or clock skew.

Solution:

  1. Verify the certificate in saml_settings.json matches the one from your IdP (no extra spaces or line breaks)
  2. Ensure server time is synchronised (NTP)
  3. Check IdP logs to see if the request was received
  4. Enable debug logging in superset_config.py:
import logging
logging.getLogger('onelogin.saml2').setLevel(logging.DEBUG)

Issue 2: User Created but No Roles Assigned

Cause: Group attribute not in SAML response or mapping mismatch.

Solution:

  1. In your custom security manager, log the SAML attributes:
logger.info(f"SAML attributes: {saml_attributes}")
  1. Check Superset logs to see what groups were extracted
  2. Verify group names in GROUP_ROLE_MAPPING exactly match SAML group values (case-sensitive)
  3. In your IdP, verify the group attribute is included in the SAML response

Issue 3: Redirect Loop or “Not Authorized”

Cause: ACS URL mismatch or CORS issue.

Solution:

  1. Verify ACS URL in IdP config exactly matches sp.assertionConsumerService.url in saml_settings.json (including trailing slash)
  2. Check that Superset’s public URL matches the domain in certificates
  3. Disable any WAF or proxy rules blocking SAML POST requests

Issue 4: SAML Metadata Endpoint Returns 404

Cause: SAML_METADATA_EXPOSED not enabled or Superset not restarted.

Solution:

  1. Ensure SAML_METADATA_EXPOSED = True in superset_config.py
  2. Restart Superset: docker-compose restart superset (or equivalent)
  3. Check that the URL is https://superset.yourcompany.com/metadata/ (not /saml/metadata/)

Issue 5: Users Can’t Log Out

Cause: Single Logout (SLO) not configured.

Solution:

SAML SLO is optional. If you want logout to also log out of the IdP:

  1. Ensure sp.singleLogoutService.url is configured in saml_settings.json
  2. Configure the same URL in your IdP
  3. Test by logging out and verifying you’re logged out of the IdP too

If SLO causes issues, disable it and rely on session timeout instead.


Monitoring and Maintenance

Once SAML is live, keep it healthy.

Weekly Checks

  • Test login with a test user from each major group
  • Check for authentication errors in Superset logs
  • Verify no users are stuck with wrong roles

Monthly Checks

  • Review authentication logs for anomalies (unusual login times, failed attempts)
  • Verify all active users have appropriate roles
  • Check that offboarded users are actually removed from Superset

Quarterly Checks

  • Verify IdP certificate expiry dates
  • Review SAML configuration against IdP’s latest best practices
  • Test disaster recovery (can you restore Superset and re-authenticate?)

Alerting

Set up alerts for:

  • Multiple failed SAML authentication attempts (potential attack)
  • SAML certificate expiring within 30 days
  • Superset unable to reach IdP metadata endpoint

Example Prometheus alert (if you’re using Prometheus):

groups:
  - name: saml_alerts
    rules:
      - alert: SamlAuthenticationFailures
        expr: rate(saml_auth_failures_total[5m]) > 0.1
        for: 5m
        annotations:
          summary: "High SAML authentication failure rate"

Next Steps and Recommendations

You’ve now got SAML-based SSO running. Here’s what’s next:

Immediate (This Week)

  1. Test with real users: Have 5-10 team members log in and verify they get the right roles
  2. Document the setup: Write a runbook for your team (how to add new users, troubleshoot, etc.)
  3. Configure backups: Ensure your saml_settings.json and certificates are backed up securely

Short-term (This Month)

  1. Enable audit logging: Centralise Superset logs to a SIEM or log aggregation service
  2. Set up monitoring: Alert on authentication failures and certificate expiry
  3. Offboard test: Remove a test user from your IdP and verify they can’t access Superset

Medium-term (This Quarter)

  1. Compliance audit: If pursuing SOC 2 or ISO 27001, use SAML as evidence of strong access control. Consult PADISO’s Security Audit service via Vanta for a gap analysis and remediation roadmap.
  2. Extend to other tools: Once SAML is solid in Superset, roll it out to other analytics or BI tools (Looker, Tableau, etc.)
  3. Advanced features: Implement conditional access (e.g., require MFA for admin logins) or risk-based authentication

Long-term (This Year)

  1. Consolidate identity: Ensure all company tools (Superset, Jira, Slack, GitHub, etc.) use the same IdP
  2. Automate onboarding/offboarding: Use IdP webhooks to automatically create/delete Superset users
  3. Zero-trust architecture: Pair SAML with network segmentation, IP whitelisting, and device posture checks

Resources for Further Learning

For deeper dives, check out:

If you’re running Superset at scale and need fractional CTO leadership, custom SAML implementations, or help hardening your analytics stack for compliance, PADISO provides CTO as a Service and custom software development. We’ve configured SAML for 50+ clients and can accelerate your security posture.

Why SAML Matters Beyond Auth

SSO isn’t just about convenience. It’s the foundation for:

  • Compliance: SOC 2 and ISO 27001 auditors expect federated identity
  • Security: No passwords to steal, breach, or reset
  • Velocity: Onboarding and offboarding become one-click operations
  • Auditability: Every login is logged and traceable to an individual

Pair SAML with encryption, network isolation, and regular backups, and you’ve got the bones of a secure analytics platform.


Conclusion

Configuring SSO and SAML in Apache Superset is a three-to-four-day project for a competent engineer. It requires careful attention to certificate management, group mapping, and testing, but the payoff—secure, auditable, frictionless authentication—is massive.

Start with Okta if you have it; Azure AD if you’re Microsoft-heavy; Google Workspace if you’re lightweight and trust Google. Implement role mapping so org changes flow automatically. Test thoroughly. Document everything. Then move on to the next security control.

If you need hands-on support, PADISO’s team can co-build this with you, handle the configuration, and integrate it with your broader security and compliance programme. We also help with AI automation, platform engineering, and venture studio co-building for ambitious teams.