OIDC SSO integration¶
Prisma Cloud Compute Console supports OpenID Connect (OIDC) federated login. This chart wires the POST /api/v1/settings/oidc endpoint so the Console is configured as part of the init Job, alongside SAML. Both providers can be enabled simultaneously.
- Prerequisites
- IdP configuration (Keycloak example)
- Chart values
- Using a pre-created Secret for sensitive material
- Group-to-role mapping
- Verification
Prerequisites¶
init.enabled=true(the chart-managed Job performs the API configuration).- A valid Prisma Cloud Compute license.
- An OIDC IdP reachable from the Console pod. The Console calls the issuer’s discovery endpoint (
<issuer>/.well-known/openid-configuration) during federation.
IdP configuration (Keycloak example)¶
Create the OIDC client in your IdP per KEYCLOAK.md. Three settings are load-bearing for this chart:
- Valid redirect URI must match the Console callback exactly:
https://<twistlock-console-url>/api/v1/authenticate/callback/oidc
- Groups claim. If you use group-to-role mapping, add a Group Membership mapper emitting a
groupsclaim in the ID token and request it viaoidc.groups_scope. Without it the token carries no group data and role mapping is inert. - Client secret. Copy it for
oidc.client_secret, or use theexistingSecretworkflow below.
Chart values¶
Minimum viable values.yaml:
init:
enabled: true
oidc:
enabled: true
client_id: "twistlock"
client_secret: "<keycloak-client-secret>" # see below for existingSecret alternative
provider_name: "keycloak"
issuer_uri: "https://keycloak.bigbang.dev/auth/realms/baby-yoda"
groups_claim: "groups"
groups_scope: "groups"
Field mapping to the Console API (identity.ProviderSettings):
| Chart value | API field | Notes |
|---|---|---|
oidc.client_id |
clientID |
|
oidc.client_secret |
clientSecret |
Sent as {plain: "<secret>"}; Console encrypts on save |
oidc.issuer_uri |
openIDIssuesURL |
Upstream typo preserved |
oidc.provider_name |
providerAlias |
Display name on the login page |
oidc.groups_claim |
groupClaim |
Required for group-to-role mapping |
oidc.groups_scope |
groupScope |
OAuth scope that triggers the claim |
oidc.user_claim |
userClaim |
Optional; defaults server-side to sub |
oidc.auth_url |
authURL |
Optional override when discovery is unavailable |
oidc.token_url |
tokenURL |
Optional override when discovery is unavailable |
oidc.cert |
cert |
Optional IdP CA (PEM) for private chains |
Using a pre-created Secret for sensitive material¶
For GitOps deployments where the client secret must not live in chart values, set oidc.existingSecret and supply a SOPS-encrypted Secret separately. The chart will layer the user-supplied Secret on top of the chart-managed Secret using a projected volume, so the init script reads one directory regardless of where each key came from.
- Create the Secret with exactly the key
TWISTLOCK_OIDC_CLIENT_SECRET:
apiVersion: v1
kind: Secret
metadata:
name: twistlock-oidc-creds
namespace: twistlock
stringData:
TWISTLOCK_OIDC_CLIENT_SECRET: "<keycloak-client-secret>"
- Encrypt the file with SOPS and commit it to the GitOps repo.
- Reference it from chart values:
oidc:
enabled: true
client_id: "twistlock"
existingSecret: "twistlock-oidc-creds"
issuer_uri: "https://keycloak.bigbang.dev/auth/realms/baby-yoda"
groups_claim: "groups"
groups_scope: "groups"
When existingSecret is set the inline client secret is ignored and is omitted from the chart-managed Secret.
- If the existingSecret is missing at deploy time the init Job pod stays in
ContainerCreatingwith aFailedMountevent (secret "<name>" not found). This is fail-loud by design.
The same pattern works for SAML via sso.existingSecret with key TWISTLOCK_SSO_CERT.
Group-to-role mapping¶
Prisma Cloud maps the value of the configured groups claim to groups defined in /api/v1/groups. Groups are created through console.groups in chart/values.yaml or the Console UI. A token carrying "groups": ["twistlock-admins"] matches a Console group named twistlock-admins, and the Console applies that group’s role.
Verification¶
After init.enabled=true deploy, verify the Console accepted the configuration:
TL_TOKEN=$(kubectl exec -n twistlock deploy/twistlock-console -- \
curl -sk -X POST https://localhost:8083/api/v1/authenticate \
-H 'Content-Type: application/json' \
-d '{"username":"<admin>","password":"<pw>"}' | jq -r .token)
kubectl exec -n twistlock deploy/twistlock-console -- \
curl -sk https://localhost:8083/api/v1/settings/oidc \
-H "Authorization: Bearer $TL_TOKEN" | jq '{enabled, clientID, openIDIssuesURL, providerAlias, groupClaim}'
A non-empty clientSecret.encrypted in the full response confirms the Console encrypted the plain value we sent.
Full end-to-end validation requires a browser: log in via the OIDC provider button on the Twistlock login page, complete the Keycloak flow, and confirm landing in the Console UI with the role mapped to the group claim.
OIDC redirect URI scheme (console.backendTLS)¶
Prisma Console builds the OIDC redirect URI from the request’s TLS state and
ignores X-Forwarded-Proto. Nothing in the Console API’s types.Settings or
identity.ProviderSettings overrides this. When an Istio gateway
terminates client TLS and forwards plain HTTP to Console’s 8081 management port,
Console emits an http redirect URI, which most IdP client registrations reject.
Enable console.backendTLS: true (with istio.enabled: true, which every
resource below requires) to route the gateway-to-Console leg over HTTPS
on port 8083. The chart then:
- Points
routes.inbound.console.portat 8083 so bb-common emits the VirtualService targeting Console’s HTTPS port. - Emits a DestinationRule (
chart/templates/bigbang/destinationrule.yaml) withtls.mode: SIMPLEandinsecureSkipVerify: trueon port 8083 so Envoy originates its own TLS to Console and trusts Console’s self-signed cert. - Adds
traffic.sidecar.istio.io/excludeInboundPorts: "8083"to the Console pod template so the sidecar does not intercept that port; the gateway’s originated TLS lands directly on Console’s HTTPS listener instead of the sidecar’s STRICT-mTLS inbound filter. Same pattern BigBang uses for vault:8080, minio-operator:9443, eck-operator:9443, and elasticsearch-kibana:9300.
Client-side the browser keeps seeing the ingress gateway’s public cert; Console’s self-signed cert stays internal to the gateway-to-pod hop. Mesh mTLS on ports 8081 and 8084 is untouched; only 8083 is carved out. No Gateway CR changes are needed.