Skip to content

Instantly share code, notes, and snippets.

@nelaaro
Last active July 15, 2024 05:28
Show Gist options
  • Save nelaaro/a2ef6f2a268d5a8a7caf6676e2ef2bb5 to your computer and use it in GitHub Desktop.
Save nelaaro/a2ef6f2a268d5a8a7caf6676e2ef2bb5 to your computer and use it in GitHub Desktop.
superset and dex configuration superset helm
# I am only showing the relavant sections that worked for me
# Install additional packages and do any other bootstrap configuration in this script
# For production clusters it's recommended to build own image with this step done in CI
bootstrapScript: |
#!/bin/bash
rm -rf /var/lib/apt/lists/* && \
pip install \
psycopg2==2.8.5 \
redis==3.2.1 \
thrift \
sasl \
thrift_sasl \
pyhive \
elasticsearch-dbapi \
Authlib \
JMESPath \
sqlalchemy-trino && \
if [ ! -f ~/bootstrap ]; then echo "Running Superset with uid {{ .Values.runAsUser }}" > ~/bootstrap; fi
extraSecrets:
custom_sso_security_manager.py: |-
import logging
from superset.security import SupersetSecurityManager
class CustomSsoSecurityManager(SupersetSecurityManager):
def oauth_user_info(self, provider, response=None):
userinfo = {}
logging.debug("Oauth2 provider: {0}.".format(provider))
if provider == 'dex':
# 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('userinfo').json()
# logging.debug("user_data me: {0}".format(me))
# logging.debug("user_data me[name]: {0}".format(me['name']))
# logging.debug("user_data me[groups]: {0}".format(me['groups']))
role_map = {'datascience': 'Gamma',
'data-engineering': 'Alpha',
'data-platform-admin': 'Admin'}
roles = [role_map[key] for key in me['groups'] if key in role_map]
logging.debug("user_data roles: {0}".format(roles))
userinfo = {
'name' : me['name'],
'email' : me['email'],
'id' : me['preferred_username'],
'username' : me['preferred_username'],
'first_name': me['name'].split()[0],
'last_name': me['name'].split()[-1],
'groups': me['groups'],
'role_keys': roles
}
logging.debug("user_info: {0}".format(userinfo))
return userinfo
else:
return userinfo
# A dictionary of overrides to append at the end of superset_config.py - the name does not matter
# WARNING: the order is not guaranteed
configOverrides:
a_override_proxy: |
# https://superset.apache.org/docs/installation/running-on-kubernetes#superset_configpy
# This will make sure the redirect_uri is properly computed, even with SSL offloading
ENABLE_PROXY_FIX = True
FEATURE_FLAGS = {
"DYNAMIC_PLUGINS": True
}
# https://stackoverflow.com/questions/47678321/using-openid-keycloak-with-superset
# https://stackoverflow.com/questions/54010314/using-keycloakopenid-connect-with-apache-superset
# https://superset.apache.org/docs/installation/configuring-superset
# https://flask-appbuilder.readthedocs.io/en/latest/security.html#authentication-oauth
# https://flask-appbuilder.readthedocs.io/en/latest/config.html full config reference
# https://docs.authlib.org/en/latest/client/flask.html
# https://github.com/apache/superset/issues/13806
enable_oauth: |
from flask_appbuilder.security.manager import (AUTH_DB, AUTH_OAUTH, AUTH_OID)
from custom_sso_security_manager import CustomSsoSecurityManager
CUSTOM_SECURITY_MANAGER = CustomSsoSecurityManager
AUTH_TYPE = AUTH_OAUTH
OAUTH_PROVIDERS = [
{ "name":"dex",
"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":"superset-auth", # Client Id (Identify Superset application)
"client_secret":"some lone secure secret", # Secret for this Client Id (Identify Superset application)
"server_metadata_url": "https://dex.somedomain.net/.well-known/openid-configuration",
"api_base_url": "https://dex.somedomain.net/", # required for the custom security manager to work CUSTOM_SECURITY_MANAGER
# "access_token_url": "https://dex.somedomain.net/token",
# "authorize_url": "https://dex.somedomain.net/auth",
# "redirect_uri":"https://superset.somedomain.net/oauth-authorized/dex",
"client_kwargs":{
"scope": "openid profile email groups" # Scope for the Authorization
}
}
}
]
# Will allow user self registration, allowing to create Flask users from Authorized User
AUTH_USER_REGISTRATION = True
PUBLIC_ROLE_LIKE = "Gamma" # allow access to dashboard for users not logged in.
# Map Authlib roles to superset roles
# AUTH_ROLE_ADMIN = "Admin"
AUTH_ROLE_PUBLIC = "Public"
# The default user self registration role or use AUTH_USER_REGISTRATION_ROLE_JMESPATH below
# AUTH_USER_REGISTRATION_ROLE = "Admin"
# AUTH_USER_REGISTRATION_ROLE = "Public"
# if we should replace ALL the user's roles each login, or only on registration
AUTH_ROLES_SYNC_AT_LOGIN = True
# https://flask-appbuilder.readthedocs.io/en/latest/config.html#jmespath-examples
# https://flask-appbuilder.readthedocs.io/en/latest/security.html#role-based
# https://apache.github.io/superset/security.html
# https://api.gopipeline.io/jmespath-tester
AUTH_USER_REGISTRATION_ROLE_JMESPATH = "sort(role_keys)[0] || 'Gamma'"
@nelaaro
Copy link
Author

nelaaro commented Sep 30, 2021

This might also be a useful example of flask app security group mappings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment