albundy83 commented on code in PR #38092:
URL: https://github.com/apache/superset/pull/38092#discussion_r3671466051


##########
docs/admin_docs/security/oauth.mdx:
##########
@@ -0,0 +1,269 @@
+---
+title: OAuth Configuration
+sidebar_position: 4
+---
+
+# Keycloak
+
+## Complete example: Keycloak with PKCE and group mapping
+
+This example demonstrates a complete Keycloak integration with Superset, 
including:
+
+* **PKCE** (Proof Key for Code Exchange) on top of a confidential client
+* **Group-to-role mapping**: Keycloak groups are mapped to Superset roles at 
every login (`AUTH_ROLES_SYNC_AT_LOGIN`)
+* **Access control**: users who authenticate successfully but do not belong to 
any mapped group are rejected with an explicit message instead of being 
silently logged in
+* **Single logout** (RP-Initiated Logout): logging out of Superset also 
terminates the Keycloak SSO session, using `id_token_hint`
+
+## Prerequisites: Keycloak client configuration
+
+### 1. Client settings
+
+Create a confidential OIDC client (e.g. `my_superset_clientid`) with:
+
+* **Valid redirect URIs**: `https://<superset-host>/oauth-authorized/keycloak`
+* **Valid post logout redirect URIs**: `https://<superset-host>` — required 
for the single-logout redirect to be accepted by Keycloak
+
+### 2. Enable PKCE
+
+Set **Proof Key for Code Exchange Code Challenge Method** to **S256** under:
+
+`Clients -> my_superset_clientid -> Advanced -> Advanced settings`
+
+### 3. Expose group membership in the userinfo response
+
+:::warning
+Keycloak does **not** expose a `groups` claim by default. Without this mapper, 
every user will be rejected with "no valid groups" even if they are correctly 
assigned in Keycloak.
+:::
+
+Add a **Group Membership** mapper to the client:
+
+`Clients -> my_superset_clientid -> Client scopes -> 
my_superset_clientid-dedicated -> Add mapper -> By configuration -> Group 
Membership`
+
+* **Token Claim Name**: `groups`
+* **Full group path**: **OFF** — otherwise groups are returned as 
`/my_superset_clientid_admin` (with a leading slash) and the role mapping will 
silently fail
+* **Add to userinfo**: **ON**
+
+### 4. Create the groups
+
+Make sure the following groups exist in Keycloak and that users are assigned 
to at least one of them:
+
+* `<my_superset_clientid>_admin`
+* `<my_superset_clientid>_alpha`
+* `<my_superset_clientid>_gamma`
+* `<my_superset_clientid>_public`
+
+The mapping between Keycloak groups and Superset roles is defined by 
`AUTH_ROLES_MAPPING` in the configuration below. Users who do not belong to any 
of the mapped groups are shown an explicit access-denied page, without being 
logged in.
+
+:::note
+This example deliberately renders the access-denied page directly from the 
OAuth callback instead of using Flask `flash()` messages. Starting with the 
React-based login page (Superset 6.x lineage), flash messages are no longer 
displayed anywhere in the UI, so a `flash()` + redirect would fail silently and 
the user would bounce between Superset and Keycloak (whose SSO session is still 
active) with no explanation. A directly rendered response works on every 
Superset version. The `AuthOAuthView` subclassing pattern itself still works on 
6.x because the `/oauth-authorized/<provider>` callback route is still served 
by Flask-AppBuilder — but verify against your target version, as login-flow 
extension points are being reworked.
+:::
+
+:::note
+The issuer URL format depends on your Keycloak version. Legacy (Wildfly-based, 
< 17) distributions use `https://<keycloak-host>/auth/realms/<REALM>`, while 
modern (Quarkus-based) distributions use 
`https://<keycloak-host>/realms/<REALM>` — without the `/auth` prefix.
+:::
+
+## Kubernetes Secret
+
+Create a Secret containing the OIDC credentials, so they never appear in your 
Helm values (and therefore never end up in Git):
+
+```bash
+kubectl create secret generic superset-oidc \
+  --namespace superset \
+  --from-literal=CLIENT_ID='my_superset_clientid' \
+  --from-literal=CLIENT_SECRET='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
+  --from-literal=OIDC_ISSUER='https://mykeycloak.youpi.fr/realms/MYREALM'
+```
+
+In a GitOps workflow, prefer provisioning this Secret through your secret 
management tooling (e.g. External Secrets Operator, Sealed Secrets) rather than 
creating it imperatively.
+
+## Helm chart configuration
+
+Reference the Secret with `envFromSecret` instead of putting values in 
`extraSecretEnv`:
+
+```yaml
+envFromSecret: superset-oidc

Review Comment:
   Totally true, fixed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to