@@ -18,12 +18,28 @@ keycloak:
1818 name : qtodo
1919 protocol : openid-connect
2020 publicClient : false
21+ clientAuthenticatorType : federated-jwt
22+ serviceAccountsEnabled : true
2123 redirectUris :
2224 - " *"
23- secret : ${QTODO_CLIENT_SECRET}
2425 standardFlowEnabled : true
26+ directAccessGrantsEnabled : false
2527 webOrigins :
2628 - +
29+ fullScopeAllowed : true
30+ attributes :
31+ jwt.credential.issuer : spiffe
32+ # Auto-generated by template: spiffe://<localClusterDomain>/ns/qtodo/sa/qtodo
33+ jwt.credential.sub : " "
34+ post.logout.redirect.uris : " +"
35+ defaultClientScopes :
36+ - web-origins
37+ - roles
38+ - profile
39+ - basic
40+ - email
41+ optionalClientScopes :
42+ - offline_access
2743 - clientId : trusted-artifact-signer
2844 enabled : true
2945 name : Red Hat Trusted Artifact Signer Client
@@ -59,6 +75,54 @@ keycloak:
5975 access.token.claim : " true"
6076 id.token.claim : " true"
6177 userinfo.token.claim : " false"
78+ # ACS Central OIDC Client
79+ - clientId : acs-central
80+ enabled : true
81+ name : Red Hat Advanced Cluster Security Central
82+ protocol : openid-connect
83+ publicClient : false
84+ secret : ${ACS_CLIENT_SECRET}
85+ redirectUris :
86+ - " *"
87+ directAccessGrantsEnabled : true
88+ standardFlowEnabled : true
89+ implicitFlowEnabled : false
90+ webOrigins :
91+ - " *"
92+ fullScopeAllowed : true
93+ defaultClientScopes :
94+ - openid
95+ - basic
96+ - email
97+ - profile
98+ - roles
99+ - web-origins
100+ optionalClientScopes :
101+ - address
102+ - phone
103+ - offline_access
104+ protocolMappers :
105+ - name : groups
106+ protocol : openid-connect
107+ protocolMapper : oidc-group-membership-mapper
108+ consentRequired : false
109+ config :
110+ full.path : " false"
111+ id.token.claim : " true"
112+ access.token.claim : " true"
113+ claim.name : groups
114+ userinfo.token.claim : " true"
115+ - name : roles
116+ protocol : openid-connect
117+ protocolMapper : oidc-usermodel-realm-role-mapper
118+ consentRequired : false
119+ config :
120+ multivalued : " true"
121+ userinfo.token.claim : " true"
122+ id.token.claim : " true"
123+ access.token.claim : " true"
124+ claim.name : roles
125+ jsonType.label : String
62126 # RHTPA CLI Client - matches Trustify 'cli' client configuration
63127 # Reference: https://github.com/guacsec/trustify-helm-charts/blob/main/charts/trustify-infrastructure/templates/keycloak/010-ConfigMap.yaml
64128 - clientId : rhtpa-cli
@@ -132,6 +196,22 @@ keycloak:
132196 # Note: We must define 'basic' scope with 'sub' mapper for OIDC compliance
133197 # The 'sub' claim is required by RHTPA for user identification
134198 clientScopes :
199+ # OpenID scope - mandatory OIDC scope (required by ACS and other OIDC clients)
200+ - name : openid
201+ description : OpenID Connect built-in scope
202+ protocol : openid-connect
203+ attributes :
204+ include.in.token.scope : " true"
205+ display.on.consent.screen : " false"
206+ protocolMappers :
207+ - name : sub
208+ protocol : openid-connect
209+ protocolMapper : oidc-sub-mapper
210+ consentRequired : false
211+ config :
212+ introspection.token.claim : " true"
213+ access.token.claim : " true"
214+ id.token.claim : " true"
135215 # Basic scope - required for 'sub' claim in tokens
136216 # Standard OIDC scopes required by Trustify/RHTPA
137217 # Reference: https://github.com/mrrajan/trustify/blob/doc_rhbk_operator/docs/book/modules/admin/pages/infrastructure.adoc
@@ -268,6 +348,7 @@ keycloak:
268348 display.on.consent.screen : " false"
269349 # Set default client scopes for the realm (applied to all new clients)
270350 defaultDefaultClientScopes :
351+ - openid
271352 - basic
272353 - email
273354 - profile
@@ -283,6 +364,8 @@ keycloak:
283364 name : create:sbom
284365 - description : RHTPA Document Creator
285366 name : create:document
367+ - description : ACS Administrator
368+ name : acs-admin
286369 users :
287370 - createdTimestamp : 1
288371 credentials :
@@ -342,6 +425,20 @@ keycloak:
342425 - create:sbom
343426 - create:document
344427 username : rhtpa-user
428+ - createdTimestamp : 1
429+ credentials :
430+ - temporary : false
431+ type : password
432+ value : ${ACS_ADMIN_PASSWORD}
433+ email : admin@example.com
434+ emailVerified : true
435+ enabled : true
436+ firstName : ACS
437+ lastName : Administrator
438+ realmRoles :
439+ - acs-admin
440+ - offline_access
441+ username : admin
345442 ingress :
346443 enabled : true
347444 service : keycloak-service-trusted
@@ -364,9 +461,48 @@ keycloak:
364461 secretName : keycloak-users
365462 # OIDC client secrets for realm configuration
366463 oidcSecrets :
367- # QTodo OIDC client secret (app-level )
464+ # QTodo OIDC client secret — disabled when using federated-jwt (client assertion )
368465 qtodo :
466+ enabled : false
369467 vaultPath : secret/data/apps/qtodo/qtodo-oidc-client
370468 # RHTPA CLI OIDC client secret (infra)
371469 rhtpaCli :
372470 vaultPath : secret/data/hub/infra/rhtpa/rhtpa-oidc-cli
471+ # ACS Central OIDC client secret (infra)
472+ acsClient :
473+ vaultPath : secret/data/hub/infra/acs/acs-central
474+ # SPIFFE Identity Provider for Federated Client Authentication
475+ # Requires RHBK 26.4+ with Technology Preview features: spiffe + client-auth-federated
476+ # (automatically enabled in keycloak.yaml when this is enabled)
477+ #
478+ # Uses an OIDC provider type (not Keycloak's native SPIFFE provider) because the
479+ # ZTWIM operator forces SpireServer.jwtIssuer to be an HTTPS URL, so JWT SVIDs
480+ # contain iss: "https://spire-spiffe-oidc-discovery-provider.<domain>".
481+ # Keycloak's native SPIFFE IdP rejects this (expects spiffe:// URI).
482+ # The OIDC provider matches the HTTPS issuer, enabling Keycloak's federated-jwt
483+ # client authenticator to resolve clients by iss+sub without requiring client_id.
484+ #
485+ # Reference: https://www.keycloak.org/2026/01/federated-client-authentication
486+ spiffeIdentityProvider :
487+ enabled : true
488+ config :
489+ alias : spiffe
490+ displayName : SPIFFE Workload Identity
491+ providerId : oidc
492+ enabled : true
493+ hideOnLogin : true
494+ config :
495+ # SPIRE OIDC Discovery Provider issuer URL (auto-generated if empty)
496+ issuer : " "
497+ # Required by Keycloak OIDC IdP but unused for federated client auth
498+ authorizationUrl : " "
499+ tokenUrl : " "
500+ # SPIRE OIDC Discovery Provider JWKS URL (auto-generated if empty)
501+ jwksUrl : " "
502+ clientId : keycloak
503+ clientSecret : unused
504+ useJwksUrl : " true"
505+ validateSignature : " true"
506+ supportsClientAssertions : " true"
507+ supportsClientAssertionReuse : " true"
508+ syncMode : LEGACY
0 commit comments