Configuring Superset

Configuration

To configure your application, you need to create a file superset_config.py. Add this file to your

PYTHONPATH or create an environment variable SUPERSET_CONFIG_PATH specifying the full path of the superset_config.py.

For example, if deploying on Superset directly on a Linux-based system where your superset_config.py is under /app directory, you can run:

  1. export SUPERSET_CONFIG_PATH=/app/superset_config.py

If you are using your own custom Dockerfile with official Superset image as base image, then you can add your overrides as shown below:

  1. COPY --chown=superset superset_config.py /app/
  2. ENV SUPERSET_CONFIG_PATH /app/superset_config.py

Docker compose deployments handle application configuration differently. See https://github.com/apache/superset/tree/master/docker#readme for details.

The following is an example of just a few of the parameters you can set in your superset_config.py file:

  1. # Superset specific config
  2. ROW_LIMIT = 5000
  3. # Flask App Builder configuration
  4. # Your App secret key will be used for securely signing the session cookie
  5. # and encrypting sensitive information on the database
  6. # Make sure you are changing this key for your deployment with a strong key.
  7. # Alternatively you can set it with `SUPERSET_SECRET_KEY` environment variable.
  8. # You MUST set this for production environments or the server will not refuse
  9. # to start and you will see an error in the logs accordingly.
  10. SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
  11. # The SQLAlchemy connection string to your database backend
  12. # This connection defines the path to the database that stores your
  13. # superset metadata (slices, connections, tables, dashboards, ...).
  14. # Note that the connection information to connect to the datasources
  15. # you want to explore are managed directly in the web UI
  16. # The check_same_thread=false property ensures the sqlite client does not attempt
  17. # to enforce single-threaded access, which may be problematic in some edge cases
  18. SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/superset.db?check_same_thread=false'
  19. # Flask-WTF flag for CSRF
  20. WTF_CSRF_ENABLED = True
  21. # Add endpoints that need to be exempt from CSRF protection
  22. WTF_CSRF_EXEMPT_LIST = []
  23. # A CSRF token that expires in 1 year
  24. WTF_CSRF_TIME_LIMIT = 60 * 60 * 24 * 365
  25. # Set this API key to enable Mapbox visualizations
  26. MAPBOX_API_KEY = ''

All the parameters and default values defined in https://github.com/apache/superset/blob/master/superset/config.py can be altered in your local superset_config.py. Administrators will want to read through the file to understand what can be configured locally as well as the default values in place.

Since superset_config.py acts as a Flask configuration module, it can be used to alter the settings Flask itself, as well as Flask extensions like flask-wtf, flask-caching, flask-migrate, and flask-appbuilder. Flask App Builder, the web framework used by Superset, offers many configuration settings. Please consult the Flask App Builder Documentation for more information on how to configure it.

Make sure to change:

  • SQLALCHEMY_DATABASE_URI: by default it is stored at ~/.superset/superset.db
  • SECRET_KEY: to a long random string

If you need to exempt endpoints from CSRF (e.g. if you are running a custom auth postback endpoint), you can add the endpoints to WTF_CSRF_EXEMPT_LIST:

  1. WTF_CSRF_EXEMPT_LIST = [‘’]

Specifying a SECRET_KEY

Adding an initial SECRET_KEY

Superset requires a user-specified SECRET_KEY to start up. This requirement was added in version 2.1.0 to force secure configurations. Add a strong SECRET_KEY to your superset_config.py file like:

  1. SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'

You can generate a strong secure key with openssl rand -base64 42.

Rotating to a newer SECRET_KEY

If you wish to change your existing SECRET_KEY, add the existing SECRET_KEY to your superset_config.py file as PREVIOUS_SECRET_KEY = and provide your new key as SECRET_KEY =. You can find your current SECRET_KEY with these commands - if running Superset with Docker, execute from within the Superset application container:

  1. superset shell
  2. from flask import current_app; print(current_app.config["SECRET_KEY"])

Save your superset_config.py with these values and then run superset re-encrypt-secrets.

Using a production metastore

By default, Superset is configured to use SQLite, which is a simple and fast way to get started (without requiring any installation). However, for production environments, using SQLite is highly discouraged due to security, scalability, and data integrity reasons. It’s important to use only the supported database engines and consider using a different database engine on a separate host or container.

Superset supports the following database engines/versions:

Database EngineSupported Versions
PostgreSQL10.X, 11.X, 12.X, 13.X, 14.X, 15.X
MySQL5.7, 8.X

Use the following database drivers and connection strings:

DatabasePyPI packageConnection String
PostgreSQLpip install psycopg2postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>
MySQLpip install mysqlclientmysql://<UserName>:<DBPassword>@<Database Host>/<Database Name>

To configure Superset metastore set SQLALCHEMY_DATABASE_URI config key on superset_config to the appropriate connection string.

Running on a WSGI HTTP Server

While you can run Superset on NGINX or Apache, we recommend using Gunicorn in async mode. This enables impressive concurrency even and is fairly easy to install and configure. Please refer to the documentation of your preferred technology to set up this Flask WSGI application in a way that works well in your environment. Here’s an async setup known to work well in production:

  1. -w 10 \
  2. -k gevent \
  3. --worker-connections 1000 \
  4. --timeout 120 \
  5. -b 0.0.0.0:6666 \
  6. --limit-request-line 0 \
  7. --limit-request-field_size 0 \
  8. --statsd-host localhost:8125 \
  9. "superset.app:create_app()"

Refer to the Gunicorn documentation for more information. Note that the development web server (superset run or flask run) is not intended for production use.

If you’re not using Gunicorn, you may want to disable the use of flask-compress by setting COMPRESS_REGISTER = False in your superset_config.py.

Currently, Google BigQuery python sdk is not compatible with gevent, due to some dynamic monkeypatching on python core library by gevent. So, when you use BigQuery datasource on Superset, you have to use gunicorn worker type except gevent.

HTTPS Configuration

You can configure HTTPS upstream via a load balancer or a reverse proxy (such as nginx) and do SSL/TLS Offloading before traffic reaches the Superset application. In this setup, local traffic from a Celery worker taking a snapshot of a chart for Alerts & Reports can access Superset at a http:// URL, from behind the ingress point. You can also configure SSL in Gunicorn (the Python webserver) if you are using an official Superset Docker image.

Configuration Behind a Load Balancer

If you are running superset behind a load balancer or reverse proxy (e.g. NGINX or ELB on AWS), you may need to utilize a healthcheck endpoint so that your load balancer knows if your superset instance is running. This is provided at /health which will return a 200 response containing “OK” if the webserver is running.

If the load balancer is inserting X-Forwarded-For/X-Forwarded-Proto headers, you should set ENABLE_PROXY_FIX = True in the superset config file (superset_config.py) to extract and use the headers.

In case the reverse proxy is used for providing SSL encryption, an explicit definition of the X-Forwarded-Proto may be required. For the Apache webserver this can be set as follows:

  1. RequestHeader set X-Forwarded-Proto "https"

Custom OAuth2 Configuration

Superset is built on Flask-AppBuilder (FAB), which supports many providers out of the box (GitHub, Twitter, LinkedIn, Google, Azure, etc). Beyond those, Superset can be configured to connect with other OAuth2 Authorization Server implementations that support “code” authorization.

Make sure the pip package Authlib is installed on the webserver.

First, configure authorization in Superset superset_config.py.

  1. from flask_appbuilder.security.manager import AUTH_OAUTH
  2. # Set the authentication type to OAuth
  3. AUTH_TYPE = AUTH_OAUTH
  4. OAUTH_PROVIDERS = [
  5. { 'name':'egaSSO',
  6. 'token_key':'access_token', # Name of the token in the response of access_token_url
  7. 'icon':'fa-address-card', # Icon for the provider
  8. 'remote_app': {
  9. 'client_id':'myClientId', # Client Id (Identify Superset application)
  10. 'client_secret':'MySecret', # Secret for this Client Id (Identify Superset application)
  11. 'client_kwargs':{
  12. 'scope': 'read' # Scope for the Authorization
  13. },
  14. 'access_token_method':'POST', # HTTP Method to call access_token_url
  15. 'access_token_params':{ # Additional parameters for calls to access_token_url
  16. 'client_id':'myClientId'
  17. },
  18. 'jwks_uri':'https://myAuthorizationServe/adfs/discovery/keys', # may be required to generate token
  19. 'access_token_headers':{ # Additional headers for calls to access_token_url
  20. 'Authorization': 'Basic Base64EncodedClientIdAndSecret'
  21. },
  22. 'api_base_url':'https://myAuthorizationServer/oauth2AuthorizationServer/',
  23. 'access_token_url':'https://myAuthorizationServer/oauth2AuthorizationServer/token',
  24. 'authorize_url':'https://myAuthorizationServer/oauth2AuthorizationServer/authorize'
  25. }
  26. }
  27. ]
  28. # Will allow user self registration, allowing to create Flask users from Authorized User
  29. AUTH_USER_REGISTRATION = True
  30. # The default user self registration role
  31. AUTH_USER_REGISTRATION_ROLE = "Public"

Then, create a CustomSsoSecurityManager that extends SupersetSecurityManager and overrides oauth_user_info:

  1. import logging
  2. from superset.security import SupersetSecurityManager
  3. class CustomSsoSecurityManager(SupersetSecurityManager):
  4. def oauth_user_info(self, provider, response=None):
  5. logging.debug("Oauth2 provider: {0}.".format(provider))
  6. if provider == 'egaSSO':
  7. # As example, this line request a GET to base_url + '/' + userDetails with Bearer Authentication,
  8. # and expects that authorization server checks the token, and response with user details
  9. me = self.appbuilder.sm.oauth_remotes[provider].get('userDetails').data
  10. logging.debug("user_data: {0}".format(me))
  11. return { 'name' : me['name'], 'email' : me['email'], 'id' : me['user_name'], 'username' : me['user_name'], 'first_name':'', 'last_name':''}
  12. ...

This file must be located at the same directory than superset_config.py with the name custom_sso_security_manager.py. Finally, add the following 2 lines to superset_config.py:

  1. from custom_sso_security_manager import CustomSsoSecurityManager
  2. CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager

Notes

  • The redirect URL will be https://<superset-webserver>/oauth-authorized/<provider-name> When configuring an OAuth2 authorization provider if needed. For instance, the redirect URL will be https://<superset-webserver>/oauth-authorized/egaSSO for the above configuration.

  • If an OAuth2 authorization server supports OpenID Connect 1.0, you could configure its configuration document URL only without providing api_base_url, access_token_url, authorize_url and other required options like user info endpoint, jwks uri etc. For instance:

    1. OAUTH_PROVIDERS = [
    2. { 'name':'egaSSO',
    3. 'token_key':'access_token', # Name of the token in the response of access_token_url
    4. 'icon':'fa-address-card', # Icon for the provider
    5. 'remote_app': {
    6. 'client_id':'myClientId', # Client Id (Identify Superset application)
    7. 'client_secret':'MySecret', # Secret for this Client Id (Identify Superset application)
    8. 'server_metadata_url': 'https://myAuthorizationServer/.well-known/openid-configuration'
    9. }
    10. }
    11. ]

LDAP Authentication

FAB supports authenticating user credentials against an LDAP server. To use LDAP you must install the python-ldap package. See FAB’s LDAP documentation for details.

Mapping LDAP or OAUTH groups to Superset roles

AUTH_ROLES_MAPPING in Flask-AppBuilder is a dictionary that maps from LDAP/OAUTH group names to FAB roles. It is used to assign roles to users who authenticate using LDAP or OAuth.

Mapping OAUTH groups to Superset roles

The following AUTH_ROLES_MAPPING dictionary would map the OAUTH group “superset_users” to the Superset roles “Gamma” as well as “Alpha”, and the OAUTH group “superset_admins” to the Superset role “Admin”.

AUTH_ROLES_MAPPING = { “superset_users”: [“Gamma”,”Alpha”], “superset_admins”: [“Admin”], }

Mapping LDAP groups to Superset roles

The following AUTH_ROLES_MAPPING dictionary would map the LDAP DN “cn=superset_users,ou=groups,dc=example,dc=com” to the Superset roles “Gamma” as well as “Alpha”, and the LDAP DN “cn=superset_admins,ou=groups,dc=example,dc=com” to the Superset role “Admin”.

AUTH_ROLES_MAPPING = { “cn=superset_users,ou=groups,dc=example,dc=com”: [“Gamma”,”Alpha”], “cn=superset_admins,ou=groups,dc=example,dc=com”: [“Admin”], }

Note: This requires AUTH_LDAP_SEARCH to be set. For more details, Please refer (FAB Security documentation)[https://flask-appbuilder.readthedocs.io/en/latest/security.html\].

Syncing roles at login

You can also use the AUTH_ROLES_SYNC_AT_LOGIN configuration variable to control how often Flask-AppBuilder syncs the user’s roles with the LDAP/OAUTH groups. If AUTH_ROLES_SYNC_AT_LOGIN is set to True, Flask-AppBuilder will sync the user’s roles each time they log in. If AUTH_ROLES_SYNC_AT_LOGIN is set to False, Flask-AppBuilder will only sync the user’s roles when they first register.

Flask app Configuration Hook

FLASK_APP_MUTATOR is a configuration function that can be provided in your environment, receives the app object and can alter it in any way. For example, add FLASK_APP_MUTATOR into your superset_config.py to setup session cookie expiration time to 24 hours:

  1. from flask import session
  2. from flask import Flask
  3. def make_session_permanent():
  4. '''
  5. Enable maxAge for the cookie 'session'
  6. '''
  7. session.permanent = True
  8. # Set up max age of session to 24 hours
  9. PERMANENT_SESSION_LIFETIME = timedelta(hours=24)
  10. def FLASK_APP_MUTATOR(app: Flask) -> None:
  11. app.before_request_funcs.setdefault(None, []).append(make_session_permanent)

Feature Flags

To support a diverse set of users, Superset has some features that are not enabled by default. For example, some users have stronger security restrictions, while some others may not. So Superset allow users to enable or disable some features by config. For feature owners, you can add optional functionalities in Superset, but will be only affected by a subset of users.

You can enable or disable features with flag from superset_config.py:

  1. FEATURE_FLAGS = {
  2. 'ENABLE_EXPLORE_JSON_CSRF_PROTECTION': False,
  3. 'PRESTO_EXPAND_DATA': False,
  4. }

A current list of feature flags can be found in RESOURCES/FEATURE_FLAGS.md.