Configuring Liteset
superset_config.py
Liteset exposes hundreds of configurable parameters through its config.py module. The variables and objects exposed act as a public interface of the bulk of what you may want to configure, alter and interface with. In this python module, you'll find all these parameters, sensible defaults, as well as rich documentation in the form of comments
To configure your application, you need to create your own configuration module, which
will allow you to override few or many of these parameters. Instead of altering the core module,
you'll want to define your own module (typically a file named 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 Liteset directly on a Linux-based system where your
superset_config.py is under /app directory, you can run:
export SUPERSET_CONFIG_PATH=/app/superset_config.py
If you are using your own custom Dockerfile with the official Liteset image as base image, then you can add your overrides as shown below:
COPY --chown=superset superset_config.py /app/
ENV SUPERSET_CONFIG_PATH /app/superset_config.py
Docker compose deployments handle application configuration differently using specific conventions. Refer to the docker compose tips & configuration for details.
The following is an example of just a few of the parameters you can set in your superset_config.py file:
# Liteset-specific config
ROW_LIMIT = 5000
# Your app secret key will be used for securely signing the session cookie
# and encrypting sensitive information in the metadata database.
# Make sure you change this key for your deployment to a strong, unique value.
# Alternatively you can set it with the `SUPERSET_SECRET_KEY` environment variable.
# You MUST set this for production environments or the server will refuse
# to start and you will see an error in the logs accordingly.
SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
# The SQLAlchemy connection string to your database backend
# This connection defines the path to the database that stores your
# Liteset metadata (slices, connections, tables, dashboards, ...).
# Note that the connection information to connect to the datasources
# you want to explore are managed directly in the web UI
# The check_same_thread=false property ensures the sqlite client does not attempt
# to enforce single-threaded access, which may be problematic in some edge cases
SQLALCHEMY_DATABASE_URI = 'sqlite:////path/to/superset.db?check_same_thread=false'
# Flask-WTF flag for CSRF
WTF_CSRF_ENABLED = True
# Add endpoints that need to be exempt from CSRF protection
WTF_CSRF_EXEMPT_LIST = []
# A CSRF token that expires in 1 year
WTF_CSRF_TIME_LIMIT = 60 * 60 * 24 * 365
# Set this API key to enable Mapbox visualizations
MAPBOX_API_KEY = ''
Note that it is typical to copy and paste [only] the portions of the
core superset/config.py that
you want to alter, along with the related comments into your own superset_config.py file.
All the parameters and default values defined
in 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.
In Liteset, superset_config.py is loaded by pydantic-settings and remains backward-compatible with the original Flask-style module from Apache Superset 6.0.0. The same UPPERCASE = value constants you used with Flask are read into a typed SupersetSettings model.
Liteset is async (Litestar/ASGI) and does not run Flask, but it ports the configuration surface 1:1:
SECRET_KEY,SQLALCHEMY_DATABASE_URI,CACHE_CONFIG,FEATURE_FLAGS,WTF_CSRF_*,AUTH_*,CELERY_CONFIGetc. — all preserved.flask-wtf/flask-caching/flask-appbuilderconfiguration dictionaries are read by Liteset's own subsystems (CSRF middleware, cache backend factory,AsyncSecurityManager).flask-migrateis not used at runtime — Alembic is invoked directly via the sync psycopg2 driver during migrations.
Apache Superset's superset/config.py and Flask App Builder Documentation remain useful references — every Superset configuration key listed there is honoured by Liteset.
At the very least, you'll want to change SECRET_KEY and SQLALCHEMY_DATABASE_URI. Continue reading for more about each of these.
Specifying a SECRET_KEY
Adding an initial SECRET_KEY
Liteset requires a user-specified SECRET_KEY to start up. This requirement was added in Apache Superset 2.1.0 to force secure configurations and is enforced here too. Add a strong SECRET_KEY to your superset_config.py file like:
SECRET_KEY = 'YOUR_OWN_RANDOM_GENERATED_SECRET_KEY'
You can generate a strong secure key with openssl rand -base64 42.
This key will be used for securely signing session cookies and encrypting sensitive information stored in Liteset's metadata database. Your deployment must use a complex, unique key.
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 read the currently-loaded
SECRET_KEY by importing Liteset's settings object — Liteset does not ship an interactive superset shell REPL (Flask's current_app is not available either), so run a one-shot Python invocation
from inside the application container:
python -c "from superset.config import SupersetSettings; print(SupersetSettings().secret_key)"
Save your superset_config.py with these values and then run superset re-encrypt-secrets.
Setting up a production metadata database
Liteset needs a database to store the information it manages, like the definitions of charts, dashboards, and many other things.
By default, Liteset is configured to use SQLite,
a self-contained, single-file database that offers 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 —
and Liteset's async runtime is designed around PostgreSQL with asyncpg.
It's important to use only the supported database engines and consider using a different
database engine on a separate host or container.
Liteset supports the following database engines/versions:
| Database Engine | Supported Versions |
|---|---|
| PostgreSQL | 10.X, 11.X, 12.X, 13.X, 14.X, 15.X, 16.X |
| MySQL | 5.7, 8.X |
Use the following database drivers and connection strings:
| Database | PyPI package | Connection String |
|---|---|---|
| PostgreSQL | asyncpg (runtime) + psycopg2 (Alembic migrations) — both ship in requirements/base.txt | postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name> |
| MySQL | pip install mysqlclient | mysql://<UserName>:<DBPassword>@<Database Host>/<Database Name> |
Liteset talks to its metadata database with asyncpg at runtime (the entire request path is
async) and falls back to psycopg2 for Alembic schema migrations, which run in a synchronous
context. Both drivers are pre-installed in the standard Liteset images; the
SQLALCHEMY_DATABASE_URI value stays in the canonical postgresql:// form — Liteset rewrites the
scheme internally per use-case.
Properly setting up metadata store is beyond the scope of this documentation. We recommend using a hosted managed service such as Amazon RDS or Google Cloud Databases to handle service and supporting infrastructure and backup strategy.
To configure Liteset's metastore, set the SQLALCHEMY_DATABASE_URI config key in superset_config.py
to the appropriate connection string.
Running on an ASGI HTTP server
Liteset ships an ASGI app and is designed to run under Uvicorn with uvloop. The pre-forked Gunicorn + gevent model used by Apache Superset 6.0.0 is not the recommended way to run Liteset — a single Uvicorn process replaces N forked Flask workers and uses one event loop.
A production-ready single-host setup looks like:
uvicorn superset.app:create_app \
--factory \
--host 0.0.0.0 \
--port 6666 \
--workers 1 \
--loop uvloop \
--http httptools \
--proxy-headers \
--forwarded-allow-ips '*' \
--log-config logging.json
Notes:
--workers 1is intentional. Concurrency in Liteset comes from the event loop, not from forks. If you need to use more than one CPU, run several Uvicorn instances behind a reverse proxy (or usegunicorn -k uvicorn.workers.UvicornWorkerwith multiple workers — Liteset is safe under that worker class).--proxy-headerstogether with--forwarded-allow-ipsis required when Liteset is behind nginx / an L7 load balancer; without it, scheme/host detection breaks for redirects and CSRF.- The development server (
uvicorn ... --reloadorsuperset run) is not intended for production. flask-compressis no longer used — response compression is offloaded to the reverse proxy or to Litestar's built-inCompressionMiddleware.
The Google BigQuery gevent-incompatibility caveat that affected Apache Superset under Gunicorn does not apply to Liteset — there is no monkey-patching of the Python core library on the hot path.
HTTPS configuration
Configure HTTPS upstream via a reverse proxy (nginx, Traefik, Caddy) and do TLS termination before traffic reaches Liteset — this is the recommended setup. Local traffic from a Celery worker taking a snapshot of a chart for Alerts & Reports can then access Liteset at an internal http:// URL.
If you really need to terminate TLS in-process, Uvicorn supports it directly:
uvicorn superset.app:create_app --factory \
--ssl-certfile /etc/ssl/liteset.crt \
--ssl-keyfile /etc/ssl/liteset.key
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:
RequestHeader set X-Forwarded-Proto "https"
Configuring the application root
Please be advised that this feature is in BETA.
Liteset supports running the application under a non-root path. The root path prefix can be specified in one of two ways:
- Setting the
SUPERSET_APP_ROOTenvironment variable to the desired prefix. - Customizing the Litestar app factory entrypoint
by passing the
superset_app_rootvariable.
Note, the prefix should start with a /.
Customizing the app factory
To configure a prefix, e.g /analytics, pass the superset_app_root argument to
create_app. With Uvicorn (and the Litestar --factory flag) the call site looks like:
uvicorn "superset.app:create_app" --factory \
--host 0.0.0.0 --port 6666 \
--factory-arg superset_app_root=/analytics
Or set the environment variable read by the factory:
export SUPERSET_APP_ROOT=/analytics
uvicorn superset.app:create_app --factory --host 0.0.0.0 --port 6666
Docker builds
The docker compose developer
configuration includes an additional environmental variable,
SUPERSET_APP_ROOT,
to simplify the process of setting up a non-default root path across the services.
In docker/.env-local set SUPERSET_APP_ROOT to the desired prefix and then bring the
services up with docker compose up --detach.
Custom OAuth2 Configuration
Apache Superset is built on Flask-AppBuilder (FAB), which supports many providers out of the box (GitHub, Twitter, LinkedIn, Google, Azure, etc). Liteset ports the FAB security surface to an AsyncSecurityManager and reads the same configuration keys (AUTH_TYPE, OAUTH_PROVIDERS, AUTH_USER_REGISTRATION, etc.). The superset_config.py snippets below work as-is.
- Liteset uses Authlib under the hood for OAuth, same as Apache Superset.
- If you subclass
SupersetSecurityManagerto overrideoauth_user_info, your subclass should derive fromsuperset.security.AsyncSecurityManagerand the override must beasync def. See theCustomSsoSecurityManagerexample further down on this page.
Make sure the pip package Authlib is installed.
First, configure authorization in Liteset superset_config.py.
from flask_appbuilder.security.manager import AUTH_OAUTH
# Set the authentication type to OAuth
AUTH_TYPE = AUTH_OAUTH
OAUTH_PROVIDERS = [
{ 'name':'egaSSO',
'token_key':'access_token', # Name of the token in the response of access_token_url
'icon':'fa-address-card', # Icon for the provider
'remote_app': {
'client_id':'myClientId', # Client Id (Identify Superset application)
'client_secret':'MySecret', # Secret for this Client Id (Identify Superset application)
'client_kwargs':{
'scope': 'read' # Scope for the Authorization
},
'access_token_method':'POST', # HTTP Method to call access_token_url
'access_token_params':{ # Additional parameters for calls to access_token_url
'client_id':'myClientId'
},
'jwks_uri':'https://myAuthorizationServe/adfs/discovery/keys', # may be required to generate token
'access_token_headers':{ # Additional headers for calls to access_token_url
'Authorization': 'Basic Base64EncodedClientIdAndSecret'
},
'api_base_url':'https://myAuthorizationServer/oauth2AuthorizationServer/',
'access_token_url':'https://myAuthorizationServer/oauth2AuthorizationServer/token',
'authorize_url':'https://myAuthorizationServer/oauth2AuthorizationServer/authorize'
}
}
]
# Will allow user self registration, allowing to create Flask users from Authorized User
AUTH_USER_REGISTRATION = True
# The default user self registration role
AUTH_USER_REGISTRATION_ROLE = "Public"
In case you want to assign the Admin role on new user registration, it can be assigned as follows:
AUTH_USER_REGISTRATION_ROLE = "Admin"
If you encounter the issue of not being able to list users from the Superset main page settings, although a newly registered user has an Admin role, please re-run superset init to sync the required permissions. Below is the command to re-run superset init using docker compose.
docker-compose exec superset superset init
Then, create a CustomSsoSecurityManager that extends SupersetSecurityManager and overrides
oauth_user_info:
import logging
from superset.security import SupersetSecurityManager
class CustomSsoSecurityManager(SupersetSecurityManager):
def oauth_user_info(self, provider, response=None):
logging.debug("Oauth2 provider: {0}.".format(provider))
if provider == 'egaSSO':
# As example, this line request a GET to base_url + '/' + userDetails with Bearer Authentication,
# and expects that authorization server checks the token, and response with user details
me = self.appbuilder.sm.oauth_remotes[provider].get('userDetails').data
logging.debug("user_data: {0}".format(me))
return { 'name' : me['name'], 'email' : me['email'], 'id' : me['user_name'], 'username' : me['user_name'], 'first_name':'', 'last_name':''}
...
This file must be located in the same directory as superset_config.py with the name
custom_sso_security_manager.py. Finally, add the following 2 lines to superset_config.py:
from custom_sso_security_manager import CustomSsoSecurityManager
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 behttps://<superset-webserver>/oauth-authorized/egaSSOfor 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_urland other required options like user info endpoint, jwks uri etc. For instance:OAUTH_PROVIDERS = [{ 'name':'egaSSO','token_key':'access_token', # Name of the token in the response of access_token_url'icon':'fa-address-card', # Icon for the provider'remote_app': {'client_id':'myClientId', # Client Id (Identify Superset application)'client_secret':'MySecret', # Secret for this Client Id (Identify Superset application)'server_metadata_url': 'https://myAuthorizationServer/.well-known/openid-configuration'}}]
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 see the FAB Security documentation.
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.
App Mutator Hook (FLASK_APP_MUTATOR)
FLASK_APP_MUTATOR is preserved in Liteset as a last-mile compat shim — the name and key are
unchanged so old superset_config.py files keep working — but the callable now receives the
Litestar app instance (not a Flask app). It is invoked once during app startup, after middleware,
plugins, and route registration are complete, so it is a convenient place to register additional
middleware, lifecycle hooks, or route handlers.
from datetime import timedelta
from litestar import Litestar
from litestar.middleware.session.client_side import CookieBackendConfig
# Set up max age of session to 24 hours
PERMANENT_SESSION_LIFETIME = timedelta(hours=24)
def FLASK_APP_MUTATOR(app: Litestar) -> None:
# Example: tag the app for an observability backend, register an extra
# middleware, or attach state. Avoid touching internal Litestar plumbing
# that may move between releases — prefer the standard Litestar plugin
# surface for non-trivial integrations.
app.state.deployment_id = "prod-eu-1"
For anything more than a quick tweak, prefer Litestar's first-class extension points (middleware, plugins, lifecycle handlers, dependency providers) over this hook. The hook stays for backward compatibility with existing Apache Superset configurations.
Feature Flags
To support a diverse set of users, Liteset has some features that are not enabled by default. For example, some users have stronger security restrictions, while some others may not. So Liteset allows users to enable or disable some features by config. For feature owners, you can add optional functionalities in Liteset, but will be only affected by a subset of users.
You can enable or disable features with flag from superset_config.py:
FEATURE_FLAGS = {
'PRESTO_EXPAND_DATA': False,
}
A current list of feature flags can be found in RESOURCES/FEATURE_FLAGS.md.