Documentssuperset
Flask-Talisman and Reverse Proxy Configuration
Flask-Talisman and Reverse Proxy Configuration
Type
Topic
Status
Published
Created
Jul 16, 2026
Updated
Jul 16, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Flask-Talisman and Reverse Proxy Configuration#

Superset uses Flask-Talisman to enforce HTTP security headers and Content Security Policy (CSP). The Talisman instance is declared as a module-level extension and initialized conditionally during app startup.

Talisman is disabled by default. It must be explicitly enabled for production deployments .

Key Configuration Variables#

All settings live in superset/config.py and can be overridden via superset_config.py .

VariableDefaultPurpose
TALISMAN_ENABLEDFalseEnable/disable Talisman. Also settable via TALISMAN_ENABLED env var.
TALISMAN_CONFIG(see below)Kwargs passed to talisman.init_app() in production/non-debug mode.
TALISMAN_DEV_CONFIG(see below)Used when app.debug=True; relaxes CSP to allow React's unsafe-eval.
CONTENT_SECURITY_POLICY_WARNINGTrueLogs a warning at startup if no CSP is configured in non-debug mode.
ENABLE_PROXY_FIXFalseEnables Werkzeug's ProxyFix middleware for X-Forwarded-* headers.
PROXY_FIX_CONFIG{x_for:1, x_proto:1, x_host:1, x_port:1, x_prefix:1}Trusted proxy hop counts for each forwarded header.

Initialization Flow#

Talisman and ProxyFix are both configured inside configure_middlewares() in superset/initialization/__init__.py.

The sequence within that method:

  1. ProxyFix is applied first (if ENABLE_PROXY_FIX=True), wrapping the WSGI app .
  2. Talisman config is selected: TALISMAN_DEV_CONFIG is used when app.debug or config["DEBUG"] is True; otherwise TALISMAN_CONFIG .
  3. Talisman is initialized via talisman.init_app(self.superset_app, **talisman_config) if enabled .
  4. CSP warning is emitted at startup if Talisman is disabled or has no content_security_policy defined in non-debug mode .

Default TALISMAN_CONFIG#

The default TALISMAN_CONFIG ships with a production-ready CSP and with HTTPS enforcement deliberately turned off:

  • content_security_policy: restricts script-src to 'self' + 'strict-dynamic', object-src to 'none', and allows img-src for blob/data URIs plus a few CDN domains (Scarf, Document360, OpenStreetMap tile servers).
  • content_security_policy_nonce_in: ["script-src"]: Talisman automatically injects a per-request nonce into <script> tags and the script-src header.
  • force_https: False: HTTPS is not enforced at the app level (see Reverse Proxy Setup below).
  • session_cookie_secure: False: cookies are not restricted to HTTPS-only connections at the Talisman level.

The dev config (TALISMAN_DEV_CONFIG) is identical except script-src also allows 'unsafe-inline' and 'unsafe-eval' for React's hot-reload mode.

Slack avatars: if SLACK_ENABLE_AVATARS is enabled, add https://avatars.slack-edge.com to img-src in your custom TALISMAN_CONFIG .

Reverse Proxy Setup (TLS Termination)#

When Superset runs behind a reverse proxy (nginx, Traefik, etc.) that terminates TLS, the app receives plain HTTP internally. This requires coordinating several settings.

1. Enable ProxyFix#

Set ENABLE_PROXY_FIX = True so Flask reconstructs the correct scheme, host, and client IP from X-Forwarded-* headers . The default PROXY_FIX_CONFIG trusts one hop for each header; adjust counts to match your proxy chain depth .

2. Keep force_https: False#

Do not set force_https: True when a proxy terminates TLS. Superset receives HTTP from the proxy; Talisman would redirect those HTTP requests back to HTTPS, creating redirect loops or breaking internal service-to-service calls. This directly affects Celery workers for Alerts/Reports — they call WEBDRIVER_BASEURL over HTTP internally, and a forced redirect causes those tasks to fail . The proxy itself should enforce HTTPS for external traffic.

The SESSION_COOKIE_SECURE flag (default False) controls whether session cookies are sent only over HTTPS. When True, cookies are silently dropped on HTTP connections — including internal Celery worker calls that use WEBDRIVER_BASEURL = "http://...". The practical result is that CSV report generation returns HTTP 500 because the internal request arrives unauthenticated .

Choose one approach:

  • Set SESSION_COOKIE_SECURE = False if workers and the app server communicate over a trusted internal network (Docker network, etc.). External users still see HTTPS through the proxy.
  • Or change WEBDRIVER_BASEURL to an internal HTTPS endpoint and terminate TLS for internal traffic too.

4. Separate internal vs. user-facing URLs#

Superset has two relevant URL settings :

SettingPurpose
WEBDRIVER_BASEURLInternal URL used by Celery workers/webdrivers. Should use HTTP if TLS is terminated at the proxy.
WEBDRIVER_BASEURL_USER_FRIENDLYExternal HTTPS URL used in email/notification links shown to users.

CSP Customization#

Override TALISMAN_CONFIG in superset_config.py to extend or modify the CSP. The config comment points to the official networking settings docs for further guidance.

Common additions:

  • iframe embedding: add a frame-ancestors directive to allow Superset to be embedded in other origins:

    "frame-ancestors": ["'self'", "https://your-app.example.com"]
    
  • Slack avatars: add https://avatars.slack-edge.com to img-src when SLACK_ENABLE_AVATARS is enabled .

  • Mapbox: connect-src already includes https://api.mapbox.com and https://events.mapbox.com by default .

  • Custom fonts/styles: add domains to style-src and font-src as needed.

When TALISMAN_ENABLED = False (the default), Superset logs a startup warning urging you to configure CSP via an alternative mechanism .

Flask-Talisman and Reverse Proxy Configuration | Dosu