Skip to content

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

  • 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 groups claim in the ID token and request it via oidc.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 the existingSecret workflow 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.

  1. 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>"
  1. Encrypt the file with SOPS and commit it to the GitOps repo.
  2. 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.

  1. If the existingSecret is missing at deploy time the init Job pod stays in ContainerCreating with a FailedMount event (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.port at 8083 so bb-common emits the VirtualService targeting Console’s HTTPS port.
  • Emits a DestinationRule (chart/templates/bigbang/destinationrule.yaml) with tls.mode: SIMPLE and insecureSkipVerify: true on 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.