apiVersion: apps/v1 kind: Deployment metadata: name: superset namespace: stonks-oracle labels: app: superset app.kubernetes.io/part-of: stonks-oracle stonks-oracle/tier: dashboard spec: replicas: 1 selector: matchLabels: app: superset template: metadata: labels: app: superset stonks-oracle/tier: dashboard spec: automountServiceAccountToken: false securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 seccompProfile: type: RuntimeDefault containers: - name: superset image: apache/superset:latest ports: - containerPort: 8088 securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] env: - name: SUPERSET_SECRET_KEY valueFrom: secretKeyRef: name: stonks-dashboard-secrets key: SUPERSET_SECRET_KEY - name: ADMIN_USERNAME value: admin - name: ADMIN_PASSWORD valueFrom: secretKeyRef: name: stonks-dashboard-secrets key: SUPERSET_ADMIN_PASSWORD - name: ADMIN_EMAIL value: admin@stonks.local volumeMounts: - name: superset-home mountPath: /app/superset_home - name: superset-config mountPath: /app/pythonpath/superset_config.py subPath: superset_config.py resources: requests: cpu: 200m memory: 512Mi limits: cpu: "1" memory: 2Gi readinessProbe: httpGet: path: /health port: 8088 initialDelaySeconds: 30 periodSeconds: 15 volumes: - name: superset-home persistentVolumeClaim: claimName: superset-data - name: superset-config configMap: name: superset-config --- apiVersion: v1 kind: Service metadata: name: superset namespace: stonks-oracle spec: selector: app: superset ports: - port: 8088 targetPort: 8088 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: superset-data namespace: stonks-oracle spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi --- apiVersion: v1 kind: ConfigMap metadata: name: superset-config namespace: stonks-oracle data: superset_config.py: | import os SECRET_KEY = os.getenv("SUPERSET_SECRET_KEY", "stonks-dev-secret-key-change-me") SQLALCHEMY_DATABASE_URI = "trino://trino@trino.stonks-oracle.svc.cluster.local:8080/lakehouse/stonks" # Additional database connections available in Superset UI: # Hive catalog: trino://trino@trino.stonks-oracle.svc.cluster.local:8080/lakehouse/stonks # Iceberg catalog: trino://trino@trino.stonks-oracle.svc.cluster.local:8080/iceberg/stonks FEATURE_FLAGS = {"ENABLE_TEMPLATE_PROCESSING": True} CACHE_CONFIG = { "CACHE_TYPE": "RedisCache", "CACHE_DEFAULT_TIMEOUT": 300, "CACHE_KEY_PREFIX": "superset_", "CACHE_REDIS_HOST": os.getenv("REDIS_HOST", "redis-master.redis-service.svc.cluster.local"), "CACHE_REDIS_PORT": int(os.getenv("REDIS_PORT", "6379")), "CACHE_REDIS_DB": 1, } # --- Security hardening --- # Disable public user role (require login) PUBLIC_ROLE_LIKE = None # Session cookie security SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SECURE = True SESSION_COOKIE_SAMESITE = "Lax" # Talisman CSP headers TALISMAN_ENABLED = True TALISMAN_CONFIG = { "content_security_policy": { "default-src": ["'self'"], "img-src": ["'self'", "data:"], "style-src": ["'self'", "'unsafe-inline'"], "script-src": ["'self'", "'unsafe-inline'", "'unsafe-eval'"], }, "force_https": False, # TLS terminated at ingress } # Prevent Superset from allowing arbitrary SQL database connections PREVENT_UNSAFE_DB_CONNECTIONS = True # Row limit for queries ROW_LIMIT = 50000 SQL_MAX_ROW = 100000