# petrolyst-insights The Petrolyst customization of Apache Superset 6.1.0: sign-in, roles, look and feel, patches and dashboards. Consumed by the deployment folders of this repository at image-build time. **Not runnable standalone**: this folder has no Dockerfile, no Compose file, no CI and no secrets. `deploy/deploy.sh` refuses to deploy if one appears here. The split follows media-insights (customization) and media-intelligence-docker (deployment): anything that changes how Superset looks or behaves for Petrolyst lives here; anything about how and where it runs lives in `stacks/`, `traefik/`, `deploy/` and `host/`. ## Layout | Path | What it is | In the image at | |---|---|---| | `superset_config.py` | Keycloak sign-in, role mapping, proxy and cookie settings, Redis caches, theme and chart palettes | `/app/pythonpath/` | | `petrolyst_security.py` | `PetrolystSecurityManager`: user info and roles from the Keycloak ID token, `/login/` straight to Keycloak, `/logout/` through Keycloak; takes the reader rules | `/app/pythonpath/` | | `petrolyst_reader.py` | readers ("ATOMA Reader"): reach only dashboards granted to the role, own nothing, get no SQL; land on the ATOMA dashboard; `register` is `FLASK_APP_MUTATOR` | `/app/pythonpath/` | | `templates/` | `head_custom_extra.html`: loads `reader.css` for readers on every page | `/app/pythonpath/templates/` | | `roles/` | `atoma_reader.py`: the role "ATOMA Reader" with exactly its permissions, run by `superset-init`; `atoma_guest.py`: the role "ATOMA Guest" for the Petrolyst app's embedded dashboards, run by hand (see "Embedding") | `/app/petrolyst-roles/` | | `assets/branding/` | logos (full colour and white): the wordmark alone for the navbar, and the stacked logo; favicons, app icons; `reader.css`; ATOMA's logo for the fleet map | `/app/superset/static/assets/branding/`, served at `/static/assets/branding/…` | | `patches/` | runtime patches, `fix_*.py` with `--verify` (see its README): `fix_redact_query_for_readers.py` | `/app/patches/petrolyst/`, applied during the build | | `dashboards/` | exported dashboards and import scripts (see its README) | not in the image | How the image consumes this folder: `stacks/fuel-monitoring/compose.yaml` passes it to the build as the named context `insights`, and the Dockerfile copies from it with `COPY --from=insights`. The image tag is a hash of exactly the inputs above that end up in the image, so a change here rebuilds and recreates only the `superset` container. ## Secrets read `superset_config.py` uses `_read_secret(name)` (copied from media-insights): it prefers `/run/secrets/` and falls back to an env var for local runs, and fails at boot on an empty value. | Secret | Purpose | |---|---| | `superset_secret_key` | Flask `SECRET_KEY` | | `superset_db_password` | password of user `superset` on the metadata database | | `keycloak_petrolyst_client_secret` | client secret of Keycloak client `petrolyst` | On the server they come from `/opt/petrolyst/secrets/` (see the deployment README). ## Sign-in and roles - Provider: Keycloak realm `thedigitalbridge` at `iam.thedigitalbridge.io`, client `petrolyst`, authorization code flow with PKCE S256. The realm URL can be overridden with `KEYCLOAK_REALM_URL`. - Roles come from the client roles of `petrolyst`, which a protocol mapper puts into the claim `petrolyst_roles`, and are re-read at every login: | Keycloak client role | Superset role | |---|---| | `superset-admin` | Admin | | `superset-editor` | Alpha | | `superset-viewer` | Gamma | | `atoma-reader` | ATOMA Reader: the ATOMA dashboard only, read-only (SPEC.md §6) | | none | Public (no permissions) | - `DASHBOARD_RBAC` is on: a viewer sees a dashboard once an admin adds the Gamma role (or a custom one) to it. - `FILTERBAR_CLOSED_BY_DEFAULT` is on: a dashboard's filter column opens collapsed, a narrow strip with an expand button; `?expand_filters=true` opens it from a link. ## Embedding (local trial only) The Petrolyst app (PD-12, petrolyst-platform `app/` and `services/app/`) shows dashboards inside its Insights lens with Superset guest passes. This is switched on **only in the local scratch stack** (`.local/fmdb-scratch`); `superset_config.py` here leaves it off, and loads without the guest secret. - The scratch stack's `superset_config_local.py` turns on `EMBEDDED_SUPERSET`, names the guest role `GUEST_ROLE_NAME = "ATOMA Guest"`, reads the signing secret with `_read_secret("superset_guest_token_secret")` and expects the audience `petrolyst-app`. The app service signs the guest passes itself with the same secret. - `roles/atoma_guest.py` gives "ATOMA Guest" the same permissions as "ATOMA Reader". Which dashboard a guest sees comes from the pass, not the role. It is not in `init.sh`; run it once, and again whenever the permissions in `atoma_reader.py` change: docker exec /app/.venv/bin/python /app/petrolyst-roles/atoma_guest.py - The app's dashboards and their embedding ids: `dashboards/README.md`. Production embedding is an open point of PD-12 (`.context/design-decisions.md`). ## Look and feel Source: `petrolyst-ui/design/brand/` (tokens `07_UI_Tokens/petrolyst_tokens.css`, logos `public/brand/`, favicons `03_Favicon_App_Icons/`), copied on 2026-10-23 from petrolyst-ui commit `2b2e694`. Copy again when the brand changes. - Light theme: action teal `#00695C` for primary and links, navy `#0B1D33` text, `#F8FAFC` layout, full-colour stacked logo. - Dark theme: `#35C5B6` primary, `#071425` / `#12263D` surfaces, white logo. - Font: Inter, Superset's default. Satoshi is licence-restricted and is not used. - Chart palettes: "Petrolyst" categorical (the default, brand teal first) and "Petrolyst Teal" / "Petrolyst Navy" sequential. The categorical palette was validated with the dataviz skill's validator on both chart surfaces; the numbers are in the comment above it in `superset_config.py`. Charts with more than three series in scatter or map form should fold the rest into "Other".