diff --git a/Chart.yaml b/Chart.yaml index f80ab9a..bc8b559 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -4,7 +4,7 @@ keywords: - pattern name: rhbk type: application -version: 0.0.12 +version: 0.1.0 home: https://github.com/validatedpatterns/rhbk-chart maintainers: - name: Validated Patterns Team diff --git a/README.md b/README.md index 20407f4..4e9c41c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -![Version: 0.0.12](https://img.shields.io/badge/Version-0.0.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) +![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) @@ -28,402 +28,27 @@ This chart is used to serve as the template for Validated Patterns Charts ## Values -| Key | Type | Default | Description | -| ------------------------------------------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| defaultDenyNetworkPolicy | object | false | Default-deny NetworkPolicy for the keycloak namespace. When enabled, deploys a namespace-wide NetworkPolicy that blocks all ingress and egress for pods without an explicit allow policy. Patterns that need zero-trust network isolation should enable this and provide per-pod allow rules via networkPolicy. | -| externalSecrets | object | `{"acs":{"metadata":{},"targetMetadata":{}},"adminUser":{"metadata":{},"targetMetadata":{}},"keycloakUsers":{"labels":{},"metadata":{},"targetMetadata":{}},"oidcClientSecret":{"metadata":{},"targetMetadata":{}},"postgresqlDb":{"metadata":{},"targetMetadata":{}},"rhtpa":{"metadata":{},"targetMetadata":{}}}` | Properties associated with ExternalSecret resources. | -| global.creationPolicy | string | `"Owner"` | | -| global.deletionPolicy | string | `"Retain"` | | -| global.localClusterDomain | string | `"apps.example.com"` | | -| global.refreshInterval | string | `"1h"` | | -| global.refreshPolicy | string | `"Periodic"` | | -| global.secretStore.kind | string | `"ClusterSecretStore"` | | -| global.secretStore.name | string | `"vault-backend"` | | -| keycloak.adminUser.enabled | bool | `true` | | -| keycloak.adminUser.passwordVaultKey | string | `"secret/data/hub/infra/keycloak/keycloak"` | | -| keycloak.adminUser.secretName | string | `"keycloak-admin-user"` | | -| keycloak.adminUser.username | string | `"admin"` | | -| keycloak.defaultConfig | bool | `true` | | -| keycloak.defaultRealm.clientScopes[0].attributes."display.on.consent.screen" | string | `"false"` | | -| keycloak.defaultRealm.clientScopes[0].attributes."include.in.token.scope" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[0].description | string | `"OpenID Connect built-in scope"` | | -| keycloak.defaultRealm.clientScopes[0].name | string | `"openid"` | | -| keycloak.defaultRealm.clientScopes[0].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[0].protocolMappers[0].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[0].protocolMappers[0].config."id.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[0].protocolMappers[0].config."introspection.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[0].protocolMappers[0].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clientScopes[0].protocolMappers[0].name | string | `"sub"` | | -| keycloak.defaultRealm.clientScopes[0].protocolMappers[0].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[0].protocolMappers[0].protocolMapper | string | `"oidc-sub-mapper"` | | -| keycloak.defaultRealm.clientScopes[1].attributes."display.on.consent.screen" | string | `"false"` | | -| keycloak.defaultRealm.clientScopes[1].attributes."include.in.token.scope" | string | `"false"` | | -| keycloak.defaultRealm.clientScopes[1].description | string | `"OpenID Connect basic scope"` | | -| keycloak.defaultRealm.clientScopes[1].name | string | `"basic"` | | -| keycloak.defaultRealm.clientScopes[1].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[1].protocolMappers[0].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[1].protocolMappers[0].config."introspection.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[1].protocolMappers[0].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clientScopes[1].protocolMappers[0].name | string | `"sub"` | | -| keycloak.defaultRealm.clientScopes[1].protocolMappers[0].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[1].protocolMappers[0].protocolMapper | string | `"oidc-sub-mapper"` | | -| keycloak.defaultRealm.clientScopes[2].attributes."consent.screen.text" | string | `"${emailScopeConsentText}"` | | -| keycloak.defaultRealm.clientScopes[2].attributes."display.on.consent.screen" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[2].attributes."include.in.token.scope" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[2].description | string | `"OpenID Connect email scope"` | | -| keycloak.defaultRealm.clientScopes[2].name | string | `"email"` | | -| keycloak.defaultRealm.clientScopes[2].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[0].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[0].config."claim.name" | string | `"email"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[0].config."id.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[0].config."jsonType.label" | string | `"String"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[0].config."user.attribute" | string | `"email"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[0].config."userinfo.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[0].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[0].name | string | `"email"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[0].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[0].protocolMapper | string | `"oidc-usermodel-attribute-mapper"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[1].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[1].config."claim.name" | string | `"email_verified"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[1].config."id.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[1].config."jsonType.label" | string | `"boolean"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[1].config."user.attribute" | string | `"emailVerified"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[1].config."userinfo.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[1].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[1].name | string | `"email verified"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[1].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[2].protocolMappers[1].protocolMapper | string | `"oidc-usermodel-attribute-mapper"` | | -| keycloak.defaultRealm.clientScopes[3].attributes."consent.screen.text" | string | `"${profileScopeConsentText}"` | | -| keycloak.defaultRealm.clientScopes[3].attributes."display.on.consent.screen" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[3].attributes."include.in.token.scope" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[3].description | string | `"OpenID Connect profile scope"` | | -| keycloak.defaultRealm.clientScopes[3].name | string | `"profile"` | | -| keycloak.defaultRealm.clientScopes[3].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[0].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[0].config."claim.name" | string | `"preferred_username"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[0].config."id.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[0].config."jsonType.label" | string | `"String"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[0].config."user.attribute" | string | `"username"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[0].config."userinfo.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[0].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[0].name | string | `"username"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[0].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[0].protocolMapper | string | `"oidc-usermodel-attribute-mapper"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[1].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[1].config."id.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[1].config."userinfo.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[1].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[1].name | string | `"full name"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[1].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[3].protocolMappers[1].protocolMapper | string | `"oidc-full-name-mapper"` | | -| keycloak.defaultRealm.clientScopes[4].attributes."consent.screen.text" | string | `"${rolesScopeConsentText}"` | | -| keycloak.defaultRealm.clientScopes[4].attributes."display.on.consent.screen" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[4].attributes."include.in.token.scope" | string | `"false"` | | -| keycloak.defaultRealm.clientScopes[4].description | string | `"OpenID Connect roles scope"` | | -| keycloak.defaultRealm.clientScopes[4].name | string | `"roles"` | | -| keycloak.defaultRealm.clientScopes[4].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[0].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[0].config."claim.name" | string | `"realm_access.roles"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[0].config."jsonType.label" | string | `"String"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[0].config."user.attribute" | string | `"foo"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[0].config.multivalued | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[0].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[0].name | string | `"realm roles"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[0].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[0].protocolMapper | string | `"oidc-usermodel-realm-role-mapper"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[1].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[1].name | string | `"audience resolve"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[1].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[4].protocolMappers[1].protocolMapper | string | `"oidc-audience-resolve-mapper"` | | -| keycloak.defaultRealm.clientScopes[5].attributes."display.on.consent.screen" | string | `"false"` | | -| keycloak.defaultRealm.clientScopes[5].attributes."include.in.token.scope" | string | `"false"` | | -| keycloak.defaultRealm.clientScopes[5].description | string | `"OpenID Connect web origins scope"` | | -| keycloak.defaultRealm.clientScopes[5].name | string | `"web-origins"` | | -| keycloak.defaultRealm.clientScopes[5].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[5].protocolMappers[0].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[5].protocolMappers[0].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clientScopes[5].protocolMappers[0].name | string | `"allowed web origins"` | | -| keycloak.defaultRealm.clientScopes[5].protocolMappers[0].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[5].protocolMappers[0].protocolMapper | string | `"oidc-allowed-origins-mapper"` | | -| keycloak.defaultRealm.clientScopes[6].attributes."display.on.consent.screen" | string | `"false"` | | -| keycloak.defaultRealm.clientScopes[6].attributes."include.in.token.scope" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[6].description | string | `"Permission to create documents"` | | -| keycloak.defaultRealm.clientScopes[6].name | string | `"create:document"` | | -| keycloak.defaultRealm.clientScopes[6].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[7].attributes."display.on.consent.screen" | string | `"false"` | | -| keycloak.defaultRealm.clientScopes[7].attributes."include.in.token.scope" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[7].description | string | `"Permission to read documents"` | | -| keycloak.defaultRealm.clientScopes[7].name | string | `"read:document"` | | -| keycloak.defaultRealm.clientScopes[7].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[8].attributes."display.on.consent.screen" | string | `"false"` | | -| keycloak.defaultRealm.clientScopes[8].attributes."include.in.token.scope" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[8].description | string | `"Permission to update documents"` | | -| keycloak.defaultRealm.clientScopes[8].name | string | `"update:document"` | | -| keycloak.defaultRealm.clientScopes[8].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clientScopes[9].attributes."display.on.consent.screen" | string | `"false"` | | -| keycloak.defaultRealm.clientScopes[9].attributes."include.in.token.scope" | string | `"true"` | | -| keycloak.defaultRealm.clientScopes[9].description | string | `"Permission to delete documents"` | | -| keycloak.defaultRealm.clientScopes[9].name | string | `"delete:document"` | | -| keycloak.defaultRealm.clientScopes[9].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clients[0].attributes."jwt.credential.issuer" | string | `"spiffe"` | | -| keycloak.defaultRealm.clients[0].attributes."jwt.credential.sub" | string | `""` | | -| keycloak.defaultRealm.clients[0].attributes."post.logout.redirect.uris" | string | `"+"` | | -| keycloak.defaultRealm.clients[0].clientAuthenticatorType | string | `"federated-jwt"` | | -| keycloak.defaultRealm.clients[0].clientId | string | `"qtodo-app"` | | -| keycloak.defaultRealm.clients[0].defaultClientScopes[0] | string | `"web-origins"` | | -| keycloak.defaultRealm.clients[0].defaultClientScopes[1] | string | `"roles"` | | -| keycloak.defaultRealm.clients[0].defaultClientScopes[2] | string | `"profile"` | | -| keycloak.defaultRealm.clients[0].defaultClientScopes[3] | string | `"basic"` | | -| keycloak.defaultRealm.clients[0].defaultClientScopes[4] | string | `"email"` | | -| keycloak.defaultRealm.clients[0].directAccessGrantsEnabled | bool | `false` | | -| keycloak.defaultRealm.clients[0].enabled | bool | `true` | | -| keycloak.defaultRealm.clients[0].fullScopeAllowed | bool | `true` | | -| keycloak.defaultRealm.clients[0].name | string | `"qtodo"` | | -| keycloak.defaultRealm.clients[0].optionalClientScopes[0] | string | `"offline_access"` | | -| keycloak.defaultRealm.clients[0].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clients[0].publicClient | bool | `false` | | -| keycloak.defaultRealm.clients[0].redirectUris[0] | string | `"*"` | | -| keycloak.defaultRealm.clients[0].serviceAccountsEnabled | bool | `true` | | -| keycloak.defaultRealm.clients[0].standardFlowEnabled | bool | `true` | | -| keycloak.defaultRealm.clients[0].webOrigins[0] | string | `"+"` | | -| keycloak.defaultRealm.clients[1].attributes."oauth2.device.authorization.grant.enabled" | string | `"true"` | | -| keycloak.defaultRealm.clients[1].clientId | string | `"trusted-artifact-signer"` | | -| keycloak.defaultRealm.clients[1].directAccessGrantsEnabled | bool | `true` | | -| keycloak.defaultRealm.clients[1].enabled | bool | `true` | | -| keycloak.defaultRealm.clients[1].implicitFlowEnabled | bool | `false` | | -| keycloak.defaultRealm.clients[1].name | string | `"Red Hat Trusted Artifact Signer Client"` | | -| keycloak.defaultRealm.clients[1].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[0].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[0].config."id.token.claim" | string | `"false"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[0].config."included.client.audience" | string | `"trusted-artifact-signer"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[0].name | string | `"audience-mapper"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[0].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[0].protocolMapper | string | `"oidc-audience-mapper"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[1].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[1].config."claim.name" | string | `"email_verified"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[1].config."claim.value" | string | `"true"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[1].config."id.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[1].config."jsonType.label" | string | `"boolean"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[1].config."userinfo.token.claim" | string | `"false"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[1].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clients[1].protocolMappers[1].name | string | `"email-mapper"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[1].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clients[1].protocolMappers[1].protocolMapper | string | `"oidc-hardcoded-claim-mapper"` | | -| keycloak.defaultRealm.clients[1].publicClient | bool | `true` | | -| keycloak.defaultRealm.clients[1].redirectUris[0] | string | `"*"` | | -| keycloak.defaultRealm.clients[1].redirectUris[1] | string | `"urn:ietf:wg:oauth:2.0:oob"` | | -| keycloak.defaultRealm.clients[1].redirectUris[2] | string | `"http://localhost:*/auth/callback"` | | -| keycloak.defaultRealm.clients[1].standardFlowEnabled | bool | `true` | | -| keycloak.defaultRealm.clients[1].webOrigins[0] | string | `"+"` | | -| keycloak.defaultRealm.clients[2].clientId | string | `"acs-central"` | | -| keycloak.defaultRealm.clients[2].defaultClientScopes[0] | string | `"openid"` | | -| keycloak.defaultRealm.clients[2].defaultClientScopes[1] | string | `"basic"` | | -| keycloak.defaultRealm.clients[2].defaultClientScopes[2] | string | `"email"` | | -| keycloak.defaultRealm.clients[2].defaultClientScopes[3] | string | `"profile"` | | -| keycloak.defaultRealm.clients[2].defaultClientScopes[4] | string | `"roles"` | | -| keycloak.defaultRealm.clients[2].defaultClientScopes[5] | string | `"web-origins"` | | -| keycloak.defaultRealm.clients[2].directAccessGrantsEnabled | bool | `true` | | -| keycloak.defaultRealm.clients[2].enabled | bool | `true` | | -| keycloak.defaultRealm.clients[2].fullScopeAllowed | bool | `true` | | -| keycloak.defaultRealm.clients[2].implicitFlowEnabled | bool | `false` | | -| keycloak.defaultRealm.clients[2].name | string | `"Red Hat Advanced Cluster Security Central"` | | -| keycloak.defaultRealm.clients[2].optionalClientScopes[0] | string | `"address"` | | -| keycloak.defaultRealm.clients[2].optionalClientScopes[1] | string | `"phone"` | | -| keycloak.defaultRealm.clients[2].optionalClientScopes[2] | string | `"offline_access"` | | -| keycloak.defaultRealm.clients[2].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[0].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[0].config."claim.name" | string | `"groups"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[0].config."full.path" | string | `"false"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[0].config."id.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[0].config."userinfo.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[0].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clients[2].protocolMappers[0].name | string | `"groups"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[0].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[0].protocolMapper | string | `"oidc-group-membership-mapper"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[1].config."access.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[1].config."claim.name" | string | `"roles"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[1].config."id.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[1].config."jsonType.label" | string | `"String"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[1].config."userinfo.token.claim" | string | `"true"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[1].config.multivalued | string | `"true"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[1].consentRequired | bool | `false` | | -| keycloak.defaultRealm.clients[2].protocolMappers[1].name | string | `"roles"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[1].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clients[2].protocolMappers[1].protocolMapper | string | `"oidc-usermodel-realm-role-mapper"` | | -| keycloak.defaultRealm.clients[2].publicClient | bool | `false` | | -| keycloak.defaultRealm.clients[2].redirectUris[0] | string | `"*"` | | -| keycloak.defaultRealm.clients[2].secret | string | `"${ACS_CLIENT_SECRET}"` | | -| keycloak.defaultRealm.clients[2].standardFlowEnabled | bool | `true` | | -| keycloak.defaultRealm.clients[2].webOrigins[0] | string | `"*"` | | -| keycloak.defaultRealm.clients[3].attributes."access.token.lifespan" | string | `"300"` | | -| keycloak.defaultRealm.clients[3].attributes."post.logout.redirect.uris" | string | `"+"` | | -| keycloak.defaultRealm.clients[3].clientId | string | `"rhtpa-cli"` | | -| keycloak.defaultRealm.clients[3].defaultClientScopes[0] | string | `"basic"` | | -| keycloak.defaultRealm.clients[3].defaultClientScopes[1] | string | `"email"` | | -| keycloak.defaultRealm.clients[3].defaultClientScopes[2] | string | `"profile"` | | -| keycloak.defaultRealm.clients[3].defaultClientScopes[3] | string | `"roles"` | | -| keycloak.defaultRealm.clients[3].defaultClientScopes[4] | string | `"web-origins"` | | -| keycloak.defaultRealm.clients[3].defaultClientScopes[5] | string | `"create:document"` | | -| keycloak.defaultRealm.clients[3].defaultClientScopes[6] | string | `"read:document"` | | -| keycloak.defaultRealm.clients[3].defaultClientScopes[7] | string | `"update:document"` | | -| keycloak.defaultRealm.clients[3].defaultClientScopes[8] | string | `"delete:document"` | | -| keycloak.defaultRealm.clients[3].directAccessGrantsEnabled | bool | `false` | | -| keycloak.defaultRealm.clients[3].enabled | bool | `true` | | -| keycloak.defaultRealm.clients[3].fullScopeAllowed | bool | `true` | | -| keycloak.defaultRealm.clients[3].implicitFlowEnabled | bool | `false` | | -| keycloak.defaultRealm.clients[3].name | string | `"RHTPA CLI Client"` | | -| keycloak.defaultRealm.clients[3].optionalClientScopes[0] | string | `"address"` | | -| keycloak.defaultRealm.clients[3].optionalClientScopes[1] | string | `"microprofile-jwt"` | | -| keycloak.defaultRealm.clients[3].optionalClientScopes[2] | string | `"offline_access"` | | -| keycloak.defaultRealm.clients[3].optionalClientScopes[3] | string | `"phone"` | | -| keycloak.defaultRealm.clients[3].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clients[3].publicClient | bool | `false` | | -| keycloak.defaultRealm.clients[3].secret | string | `"${RHTPA_CLI_SECRET}"` | | -| keycloak.defaultRealm.clients[3].serviceAccountsEnabled | bool | `true` | | -| keycloak.defaultRealm.clients[3].standardFlowEnabled | bool | `false` | | -| keycloak.defaultRealm.clients[4].attributes."access.token.lifespan" | string | `"300"` | | -| keycloak.defaultRealm.clients[4].attributes."post.logout.redirect.uris" | string | `"+"` | | -| keycloak.defaultRealm.clients[4].clientId | string | `"rhtpa-frontend"` | | -| keycloak.defaultRealm.clients[4].defaultClientScopes[0] | string | `"basic"` | | -| keycloak.defaultRealm.clients[4].defaultClientScopes[1] | string | `"email"` | | -| keycloak.defaultRealm.clients[4].defaultClientScopes[2] | string | `"profile"` | | -| keycloak.defaultRealm.clients[4].defaultClientScopes[3] | string | `"roles"` | | -| keycloak.defaultRealm.clients[4].defaultClientScopes[4] | string | `"web-origins"` | | -| keycloak.defaultRealm.clients[4].defaultClientScopes[5] | string | `"create:document"` | | -| keycloak.defaultRealm.clients[4].defaultClientScopes[6] | string | `"read:document"` | | -| keycloak.defaultRealm.clients[4].defaultClientScopes[7] | string | `"update:document"` | | -| keycloak.defaultRealm.clients[4].defaultClientScopes[8] | string | `"delete:document"` | | -| keycloak.defaultRealm.clients[4].directAccessGrantsEnabled | bool | `false` | | -| keycloak.defaultRealm.clients[4].enabled | bool | `true` | | -| keycloak.defaultRealm.clients[4].fullScopeAllowed | bool | `true` | | -| keycloak.defaultRealm.clients[4].implicitFlowEnabled | bool | `true` | | -| keycloak.defaultRealm.clients[4].name | string | `"RHTPA Frontend Client"` | | -| keycloak.defaultRealm.clients[4].optionalClientScopes[0] | string | `"address"` | | -| keycloak.defaultRealm.clients[4].optionalClientScopes[1] | string | `"microprofile-jwt"` | | -| keycloak.defaultRealm.clients[4].optionalClientScopes[2] | string | `"offline_access"` | | -| keycloak.defaultRealm.clients[4].optionalClientScopes[3] | string | `"phone"` | | -| keycloak.defaultRealm.clients[4].protocol | string | `"openid-connect"` | | -| keycloak.defaultRealm.clients[4].publicClient | bool | `true` | | -| keycloak.defaultRealm.clients[4].redirectUris[0] | string | `"*"` | | -| keycloak.defaultRealm.clients[4].serviceAccountsEnabled | bool | `false` | | -| keycloak.defaultRealm.clients[4].standardFlowEnabled | bool | `true` | | -| keycloak.defaultRealm.clients[4].webOrigins[0] | string | `"*"` | | -| keycloak.defaultRealm.defaultDefaultClientScopes[0] | string | `"openid"` | | -| keycloak.defaultRealm.defaultDefaultClientScopes[1] | string | `"basic"` | | -| keycloak.defaultRealm.defaultDefaultClientScopes[2] | string | `"email"` | | -| keycloak.defaultRealm.defaultDefaultClientScopes[3] | string | `"profile"` | | -| keycloak.defaultRealm.defaultDefaultClientScopes[4] | string | `"roles"` | | -| keycloak.defaultRealm.defaultDefaultClientScopes[5] | string | `"web-origins"` | | -| keycloak.defaultRealm.displayName | string | `"ZTVP Realm"` | | -| keycloak.defaultRealm.enabled | bool | `true` | | -| keycloak.defaultRealm.realm | string | `"ztvp"` | | -| keycloak.defaultRealm.registrationAllowed | bool | `false` | | -| keycloak.defaultRealm.roles.realm[0].description | string | `"QTodo App Administrator"` | | -| keycloak.defaultRealm.roles.realm[0].name | string | `"qtodo-admin"` | | -| keycloak.defaultRealm.roles.realm[1].description | string | `"Read-only access"` | | -| keycloak.defaultRealm.roles.realm[1].name | string | `"viewer"` | | -| keycloak.defaultRealm.roles.realm[2].description | string | `"RHTPA SBOM Creator"` | | -| keycloak.defaultRealm.roles.realm[2].name | string | `"create:sbom"` | | -| keycloak.defaultRealm.roles.realm[3].description | string | `"RHTPA Document Creator"` | | -| keycloak.defaultRealm.roles.realm[3].name | string | `"create:document"` | | -| keycloak.defaultRealm.roles.realm[4].description | string | `"ACS Administrator"` | | -| keycloak.defaultRealm.roles.realm[4].name | string | `"acs-admin"` | | -| keycloak.defaultRealm.users[0].createdTimestamp | int | `1` | | -| keycloak.defaultRealm.users[0].credentials[0].temporary | bool | `true` | | -| keycloak.defaultRealm.users[0].credentials[0].type | string | `"password"` | | -| keycloak.defaultRealm.users[0].credentials[0].value | string | `"${QTODO_ADMIN_PASSWORD}"` | | -| keycloak.defaultRealm.users[0].email | string | `"qtodo-admin@example.com"` | | -| keycloak.defaultRealm.users[0].emailVerified | bool | `true` | | -| keycloak.defaultRealm.users[0].enabled | bool | `true` | | -| keycloak.defaultRealm.users[0].firstName | string | `"QTodo"` | | -| keycloak.defaultRealm.users[0].lastName | string | `"Admin"` | | -| keycloak.defaultRealm.users[0].realmRoles[0] | string | `"qtodo-admin"` | | -| keycloak.defaultRealm.users[0].requiredActions[0] | string | `"UPDATE_PASSWORD"` | | -| keycloak.defaultRealm.users[0].username | string | `"qtodo-admin"` | | -| keycloak.defaultRealm.users[1].createdTimestamp | int | `1` | | -| keycloak.defaultRealm.users[1].credentials[0].temporary | bool | `true` | | -| keycloak.defaultRealm.users[1].credentials[0].type | string | `"password"` | | -| keycloak.defaultRealm.users[1].credentials[0].value | string | `"${QTODO_USER1_PASSWORD}"` | | -| keycloak.defaultRealm.users[1].email | string | `"qtodo-user1@example.com"` | | -| keycloak.defaultRealm.users[1].emailVerified | bool | `true` | | -| keycloak.defaultRealm.users[1].enabled | bool | `true` | | -| keycloak.defaultRealm.users[1].firstName | string | `"QTodo"` | | -| keycloak.defaultRealm.users[1].lastName | string | `"User-1"` | | -| keycloak.defaultRealm.users[1].realmRoles[0] | string | `"viewer"` | | -| keycloak.defaultRealm.users[1].requiredActions[0] | string | `"UPDATE_PASSWORD"` | | -| keycloak.defaultRealm.users[1].username | string | `"qtodo-user1"` | | -| keycloak.defaultRealm.users[2].createdTimestamp | int | `1` | | -| keycloak.defaultRealm.users[2].credentials[0].temporary | bool | `false` | | -| keycloak.defaultRealm.users[2].credentials[0].type | string | `"password"` | | -| keycloak.defaultRealm.users[2].credentials[0].value | string | `"${RHTAS_USER_PASSWORD}"` | | -| keycloak.defaultRealm.users[2].email | string | `"rhtas-user@example.com"` | | -| keycloak.defaultRealm.users[2].emailVerified | bool | `true` | | -| keycloak.defaultRealm.users[2].enabled | bool | `true` | | -| keycloak.defaultRealm.users[2].firstName | string | `"RHTAS"` | | -| keycloak.defaultRealm.users[2].lastName | string | `"Signer"` | | -| keycloak.defaultRealm.users[2].realmRoles[0] | string | `"viewer"` | | -| keycloak.defaultRealm.users[2].username | string | `"rhtas-user"` | | -| keycloak.defaultRealm.users[3].createdTimestamp | int | `1` | | -| keycloak.defaultRealm.users[3].credentials[0].temporary | bool | `false` | | -| keycloak.defaultRealm.users[3].credentials[0].type | string | `"password"` | | -| keycloak.defaultRealm.users[3].credentials[0].value | string | `"${RHTPA_USER_PASSWORD}"` | | -| keycloak.defaultRealm.users[3].email | string | `"rhtpa-user@example.com"` | | -| keycloak.defaultRealm.users[3].emailVerified | bool | `true` | | -| keycloak.defaultRealm.users[3].enabled | bool | `true` | | -| keycloak.defaultRealm.users[3].firstName | string | `"RHTPA"` | | -| keycloak.defaultRealm.users[3].lastName | string | `"User"` | | -| keycloak.defaultRealm.users[3].realmRoles[0] | string | `"viewer"` | | -| keycloak.defaultRealm.users[3].realmRoles[1] | string | `"create:sbom"` | | -| keycloak.defaultRealm.users[3].realmRoles[2] | string | `"create:document"` | | -| keycloak.defaultRealm.users[3].username | string | `"rhtpa-user"` | | -| keycloak.defaultRealm.users[4].createdTimestamp | int | `1` | | -| keycloak.defaultRealm.users[4].credentials[0].temporary | bool | `false` | | -| keycloak.defaultRealm.users[4].credentials[0].type | string | `"password"` | | -| keycloak.defaultRealm.users[4].credentials[0].value | string | `"${ACS_ADMIN_PASSWORD}"` | | -| keycloak.defaultRealm.users[4].email | string | `"acs-admin@example.com"` | | -| keycloak.defaultRealm.users[4].emailVerified | bool | `true` | | -| keycloak.defaultRealm.users[4].enabled | bool | `true` | | -| keycloak.defaultRealm.users[4].firstName | string | `"ACS"` | | -| keycloak.defaultRealm.users[4].lastName | string | `"Administrator"` | | -| keycloak.defaultRealm.users[4].realmRoles[0] | string | `"acs-admin"` | | -| keycloak.defaultRealm.users[4].realmRoles[1] | string | `"offline_access"` | | -| keycloak.defaultRealm.users[4].username | string | `"acs-admin"` | | -| keycloak.ingress.enabled | bool | `true` | | -| keycloak.ingress.hostname | string | `""` | | -| keycloak.ingress.service | string | `"keycloak-service-trusted"` | | -| keycloak.ingress.termination | string | `"reencrypt"` | | -| keycloak.name | string | `"keycloak"` | | -| keycloak.oidcSecrets.acsClient.vaultPath | string | `"secret/data/hub/infra/acs/acs-central"` | | -| keycloak.oidcSecrets.qtodo.enabled | bool | `false` | | -| keycloak.oidcSecrets.qtodo.vaultPath | string | `"secret/data/apps/qtodo/qtodo-oidc-client"` | | -| keycloak.oidcSecrets.rhtpaCli.vaultPath | string | `"secret/data/hub/infra/rhtpa/rhtpa-oidc-cli"` | | -| keycloak.postgresqlDb.database | string | `"keycloak"` | | -| keycloak.postgresqlDb.passwordVaultKey | string | `"secret/data/hub/infra/keycloak/keycloak"` | | -| keycloak.postgresqlDb.secretName | string | `"postgresql-db"` | | -| keycloak.postgresqlDb.username | string | `"keycloak"` | | -| keycloak.realms | list | `[]` | | -| keycloak.spiffeIdentityProvider.config.alias | string | `"spiffe"` | | -| keycloak.spiffeIdentityProvider.config.config.authorizationUrl | string | `""` | | -| keycloak.spiffeIdentityProvider.config.config.clientId | string | `"keycloak"` | | -| keycloak.spiffeIdentityProvider.config.config.clientSecret | string | `"unused"` | | -| keycloak.spiffeIdentityProvider.config.config.issuer | string | `""` | | -| keycloak.spiffeIdentityProvider.config.config.jwksUrl | string | `""` | | -| keycloak.spiffeIdentityProvider.config.config.supportsClientAssertionReuse | string | `"true"` | | -| keycloak.spiffeIdentityProvider.config.config.supportsClientAssertions | string | `"true"` | | -| keycloak.spiffeIdentityProvider.config.config.syncMode | string | `"LEGACY"` | | -| keycloak.spiffeIdentityProvider.config.config.tokenUrl | string | `""` | | -| keycloak.spiffeIdentityProvider.config.config.useJwksUrl | string | `"true"` | | -| keycloak.spiffeIdentityProvider.config.config.validateSignature | string | `"true"` | | -| keycloak.spiffeIdentityProvider.config.displayName | string | `"SPIFFE Workload Identity"` | | -| keycloak.spiffeIdentityProvider.config.enabled | bool | `true` | | -| keycloak.spiffeIdentityProvider.config.hideOnLogin | bool | `true` | | -| keycloak.spiffeIdentityProvider.config.providerId | string | `"oidc"` | | -| keycloak.spiffeIdentityProvider.enabled | bool | `true` | | -| keycloak.tls.secret | string | `"keycloak-tls"` | | -| keycloak.tls.serviceServing | bool | `true` | | -| keycloak.users.passwordVaultKey | string | `"secret/data/hub/infra/users/keycloak-users"` | | -| keycloak.users.secretName | string | `"keycloak-users"` | | -| networkPolicy | object | `{"keycloak":{"egress":[],"enabled":false},"operator":{"egress":[],"enabled":false,"ingress":[]},"postgresql":{"egress":[],"enabled":false,"ingress":[]},"realmImport":{"egress":[],"enabled":false,"podSelector":{"app":"keycloak-realm-import"}}}` | Per-pod NetworkPolicy rules for keycloak, PostgreSQL, and operator pods. Only effective when defaultDenyNetworkPolicy is enabled. The RHBK operator manages its own ingress policy for keycloak pods (keycloak-network-policy) — these templates add egress rules for keycloak and full ingress/egress rules for PostgreSQL and operator pods. | +| Key | Type | Default | Description | +| ------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| defaultDenyNetworkPolicy | object | false | Default-deny NetworkPolicy for the keycloak namespace. When enabled, deploys a namespace-wide NetworkPolicy that blocks all ingress and egress for pods without an explicit allow policy. Patterns that need zero-trust network isolation should enable this and provide per-pod allow rules via networkPolicy. | +| externalSecrets | object | `{"adminUser":{"metadata":{},"targetMetadata":{}},"postgresqlDb":{"metadata":{},"targetMetadata":{}}}` | Per-ExternalSecret lifecycle and metadata overrides. Only adminUser and postgresqlDb are managed directly by this chart. All other secrets should use keycloak.extraSecrets. | +| global.creationPolicy | string | `"Owner"` | | +| global.deletionPolicy | string | `"Retain"` | | +| global.localClusterDomain | string | `"apps.example.com"` | | +| global.refreshInterval | string | `"1h"` | | +| global.refreshPolicy | string | `"Periodic"` | | +| global.secretStore.kind | string | `"ClusterSecretStore"` | | +| global.secretStore.name | string | `"vault-backend"` | | +| keycloak.adminUser | object | `{"enabled":true,"passwordVaultKey":"","secretName":"keycloak-admin-user","username":"admin"}` | Keycloak admin bootstrap user. Creates an ExternalSecret that pulls the admin password from the configured secret store. | +| keycloak.extraSecrets | list | `[]` | Extra ExternalSecrets. Each entry creates an ExternalSecret resource that pulls data from the configured secret store into a Kubernetes Secret. Use this for user passwords, OIDC client secrets, or any other secrets that your realm configuration requires. Example: extraSecrets: - name: my-users targetName: my-users-secret data: - secretKey: user_password remoteRef: key: secret/data/my/path property: user-password templateData: user-password: "{{ .user_password }}" | +| keycloak.ingress | object | `{"enabled":true,"hostname":"","service":"keycloak-service-trusted","termination":"reencrypt"}` | Keycloak Ingress (OpenShift Route). | +| keycloak.name | string | `"keycloak"` | Keycloak instance name. Used for pod labels, service names, and hostname generation. | +| keycloak.postgresqlDb | object | `{"database":"keycloak","passwordVaultKey":"","secretName":"postgresql-db","username":"keycloak"}` | PostgreSQL database credentials. Creates an ExternalSecret that pulls the DB password from the configured secret store. | +| keycloak.realmPlaceholders | object | `{}` | Realm import placeholders. Maps placeholder variables (used as ${VAR} in realm definitions) to Kubernetes Secret references. Applied to all realm imports. Example: realmPlaceholders: MY_USER_PASSWORD: secret: name: my-users-secret key: user-password | +| keycloak.realms | list | `[]` | Keycloak realm definitions. Each entry is a full Keycloak realm representation that will be rendered as a KeycloakRealmImport CR. Consumers define their realm structure (clients, users, roles, scopes, identity providers) here. Example: realms: - realm: my-realm enabled: true displayName: "My Realm" clients: [...] users: [...] | +| keycloak.spiffeIdentityProvider | object | `{"config":{"alias":"spiffe","config":{"authorizationUrl":"","clientId":"keycloak","clientSecret":"unused","issuer":"","jwksUrl":"","supportsClientAssertionReuse":"true","supportsClientAssertions":"true","syncMode":"LEGACY","tokenUrl":"","useJwksUrl":"true","validateSignature":"true"},"displayName":"SPIFFE Workload Identity","enabled":true,"hideOnLogin":true,"providerId":"oidc"},"enabled":false}` | SPIFFE Identity Provider for Federated Client Authentication. Requires RHBK 26.4+ with Technology Preview features: spiffe + client-auth-federated (automatically enabled in keycloak.yaml when this is enabled). Uses an OIDC provider type (not Keycloak's native SPIFFE provider) because the ZTWIM operator forces SpireServer.jwtIssuer to be an HTTPS URL, so JWT SVIDs contain iss: "https://spire-spiffe-oidc-discovery-provider.". Keycloak's native SPIFFE IdP rejects this (expects spiffe:// URI). The OIDC provider matches the HTTPS issuer, enabling Keycloak's federated-jwt client authenticator to resolve clients by iss+sub without requiring client_id. Reference: https://www.keycloak.org/2026/01/federated-client-authentication | +| keycloak.tls | object | `{"secret":"keycloak-tls","serviceServing":true}` | TLS configuration for the Keycloak instance. | +| networkPolicy | object | `{"keycloak":{"egress":[],"enabled":false},"operator":{"egress":[],"enabled":false,"ingress":[]},"postgresql":{"egress":[],"enabled":false,"ingress":[]},"realmImport":{"egress":[],"enabled":false,"podSelector":{"app":"keycloak-realm-import"}}}` | Per-pod NetworkPolicy rules for keycloak, PostgreSQL, and operator pods. Only effective when defaultDenyNetworkPolicy is enabled. The RHBK operator manages its own ingress policy for keycloak pods (keycloak-network-policy) — these templates add egress rules for keycloak and full ingress/egress rules for PostgreSQL and operator pods. | diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 592150d..5b3a584 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -35,4 +35,22 @@ Generate the target lifecycle for the ExternalSecrets resource. {{- define "keycloak.externalSecrets.targetLifecycle" -}} creationPolicy: {{ .local.creationPolicy | default .global.creationPolicy }} deletionPolicy: {{ .local.deletionPolicy | default .global.deletionPolicy }} +{{- end }} + +{{/* +Generate the lifecycle for an extraSecrets entry. +Per-entry fields override global defaults. +*/}} +{{- define "keycloak.extraSecrets.lifecycle" -}} +refreshPolicy: {{ .local.refreshPolicy | default .global.refreshPolicy }} +refreshInterval: {{ .local.refreshInterval | default .global.refreshInterval }} +{{- end }} + +{{/* +Generate the target lifecycle for an extraSecrets entry. +Per-entry fields override global defaults. +*/}} +{{- define "keycloak.extraSecrets.targetLifecycle" -}} +creationPolicy: {{ .local.creationPolicy | default .global.creationPolicy }} +deletionPolicy: {{ .local.deletionPolicy | default .global.deletionPolicy }} {{- end }} \ No newline at end of file diff --git a/templates/acs-oidc-client-secret-external-secret.yaml b/templates/acs-oidc-client-secret-external-secret.yaml deleted file mode 100644 index fc6a6a8..0000000 --- a/templates/acs-oidc-client-secret-external-secret.yaml +++ /dev/null @@ -1,32 +0,0 @@ -{{- if .Values.keycloak.defaultConfig }} ---- -apiVersion: "external-secrets.io/v1" -kind: ExternalSecret -metadata: - name: acs-oidc-client-secret - namespace: {{ .Release.Namespace }} - {{- if .Values.externalSecrets.acs.metadata }} - {{- toYaml .Values.externalSecrets.acs.metadata | nindent 2 }} - {{- end }} -spec: - {{ include "keycloak.externalSecrets.lifecycle" (dict "local" .Values.externalSecrets.acs "global" .Values.global) | nindent 2 }} - secretStoreRef: - name: {{ .Values.global.secretStore.name }} - kind: {{ .Values.global.secretStore.kind }} - target: - name: acs-oidc-client-secret - {{ include "keycloak.externalSecrets.targetLifecycle" (dict "local" .Values.externalSecrets.acs "global" .Values.global) | nindent 4 }} - template: - {{- if .Values.externalSecrets.acs.targetMetadata }} - metadata: - {{- toYaml .Values.externalSecrets.acs.targetMetadata | nindent 8 }} - {{- end }} - type: Opaque - data: - client-secret: "{{ `{{ .client_secret }}` }}" - data: - - secretKey: client_secret - remoteRef: - key: {{ .Values.keycloak.oidcSecrets.acsClient.vaultPath }} - property: admin-password -{{- end }} diff --git a/templates/extra-secrets.yaml b/templates/extra-secrets.yaml new file mode 100644 index 0000000..fb7d1e0 --- /dev/null +++ b/templates/extra-secrets.yaml @@ -0,0 +1,36 @@ +{{- range .Values.keycloak.extraSecrets }} +--- +apiVersion: "external-secrets.io/v1" +kind: ExternalSecret +metadata: + name: {{ .name }} + namespace: {{ $.Release.Namespace }} + {{- with .metadata }} + {{- toYaml . | nindent 2 }} + {{- end }} +spec: + {{ include "keycloak.extraSecrets.lifecycle" (dict "local" . "global" $.Values.global) | nindent 2 }} + secretStoreRef: + name: {{ $.Values.global.secretStore.name }} + kind: {{ $.Values.global.secretStore.kind }} + target: + name: {{ .targetName | default .name }} + {{ include "keycloak.extraSecrets.targetLifecycle" (dict "local" . "global" $.Values.global) | nindent 4 }} + template: + {{- with .targetMetadata }} + metadata: + {{- toYaml . | nindent 8 }} + {{- end }} + type: Opaque + data: + {{- range $key, $val := .templateData }} + {{ $key }}: {{ $val | quote }} + {{- end }} + data: + {{- range .data }} + - secretKey: {{ .secretKey }} + remoteRef: + key: {{ .remoteRef.key }} + property: {{ .remoteRef.property }} + {{- end }} +{{- end }} diff --git a/templates/keycloak-realm-import.yaml b/templates/keycloak-realm-import.yaml index aa0c2b8..09b9a80 100644 --- a/templates/keycloak-realm-import.yaml +++ b/templates/keycloak-realm-import.yaml @@ -1,12 +1,5 @@ -{{- if or .Values.keycloak.defaultConfig .Values.keycloak.realms }} -{{/* -Merge realms -*/}} -{{- $realms := .Values.keycloak.realms | default list }} -{{- if .Values.keycloak.defaultConfig }} -{{- $realms = append $realms .Values.keycloak.defaultRealm }} -{{- end }} -{{- range $realms }} +{{- if .Values.keycloak.realms }} +{{- range .Values.keycloak.realms }} {{- $realm := deepCopy . }} {{- $localDomain := $.Values.global.localClusterDomain }} {{- $oidcProviderBase := printf "https://spire-spiffe-oidc-discovery-provider.%s" $localDomain }} @@ -51,40 +44,9 @@ spec: keycloakCRName: keycloak realm: {{- toYaml $realm | nindent 4 }} +{{- with $.Values.keycloak.realmPlaceholders }} placeholders: - QTODO_ADMIN_PASSWORD: - secret: - name: {{ $.Values.keycloak.users.secretName }} - key: qtodo-admin-password - QTODO_USER1_PASSWORD: - secret: - name: {{ $.Values.keycloak.users.secretName }} - key: qtodo-user1-password - RHTAS_USER_PASSWORD: - secret: - name: {{ $.Values.keycloak.users.secretName }} - key: rhtas-user-password - RHTPA_USER_PASSWORD: - secret: - name: {{ $.Values.keycloak.users.secretName }} - key: rhtpa-user-password -{{- if and $.Values.keycloak.oidcSecrets.qtodo (default false $.Values.keycloak.oidcSecrets.qtodo.enabled) }} - QTODO_CLIENT_SECRET: - secret: - name: oidc-client-secret - key: client-secret + {{- toYaml . | nindent 4 }} {{- end }} - RHTPA_CLI_SECRET: - secret: - name: rhtpa-oidc-cli-secret - key: client-secret - ACS_ADMIN_PASSWORD: - secret: - name: {{ $.Values.keycloak.users.secretName }} - key: acs-admin-password - ACS_CLIENT_SECRET: - secret: - name: acs-oidc-client-secret - key: client-secret {{- end }} {{- end }} diff --git a/templates/keycloak-users-external-secret.yaml b/templates/keycloak-users-external-secret.yaml deleted file mode 100644 index e008215..0000000 --- a/templates/keycloak-users-external-secret.yaml +++ /dev/null @@ -1,51 +0,0 @@ -{{- if .Values.keycloak.defaultConfig }} -apiVersion: "external-secrets.io/v1" -kind: ExternalSecret -metadata: - name: keycloak-users - namespace: {{ .Release.Namespace }} - {{- if .Values.externalSecrets.keycloakUsers.metadata }} - {{- toYaml .Values.externalSecrets.keycloakUsers.metadata | nindent 2 }} - {{- end }} -spec: - {{ include "keycloak.externalSecrets.lifecycle" (dict "local" .Values.externalSecrets.keycloakUsers "global" .Values.global) | nindent 2 }} - secretStoreRef: - name: {{ .Values.global.secretStore.name }} - kind: {{ .Values.global.secretStore.kind }} - target: - name: keycloak-users - {{ include "keycloak.externalSecrets.targetLifecycle" (dict "local" .Values.externalSecrets.keycloakUsers "global" .Values.global) | nindent 4 }} - template: - {{- if .Values.externalSecrets.keycloakUsers.targetMetadata }} - metadata: - {{- toYaml .Values.externalSecrets.keycloakUsers.targetMetadata | nindent 8 }} - {{- end }} - type: Opaque - data: - qtodo-admin-password: "{{ `{{ .qtodo_admin_password }}` }}" - qtodo-user1-password: "{{ `{{ .qtodo_user1_password }}` }}" - rhtas-user-password: "{{ `{{ .rhtas_user_password }}` }}" - rhtpa-user-password: "{{ `{{ .rhtpa_user_password }}` }}" - acs-admin-password: "{{ `{{ .acs_admin_password }}` }}" - data: - - secretKey: qtodo_admin_password - remoteRef: - key: {{ .Values.keycloak.users.passwordVaultKey }} - property: qtodo-admin-password - - secretKey: qtodo_user1_password - remoteRef: - key: {{ .Values.keycloak.users.passwordVaultKey }} - property: qtodo-user1-password - - secretKey: rhtas_user_password - remoteRef: - key: {{ .Values.keycloak.users.passwordVaultKey }} - property: rhtas-user-password - - secretKey: rhtpa_user_password - remoteRef: - key: {{ .Values.keycloak.users.passwordVaultKey }} - property: rhtpa-user-password - - secretKey: acs_admin_password - remoteRef: - key: secret/data/hub/infra/acs/acs-central - property: admin-password -{{- end }} diff --git a/templates/oidc-client-secret-external-secret.yaml b/templates/oidc-client-secret-external-secret.yaml deleted file mode 100644 index 69abb6e..0000000 --- a/templates/oidc-client-secret-external-secret.yaml +++ /dev/null @@ -1,31 +0,0 @@ -{{- if and .Values.keycloak.defaultConfig (default false .Values.keycloak.oidcSecrets.qtodo.enabled) }} -apiVersion: "external-secrets.io/v1" -kind: ExternalSecret -metadata: - name: oidc-client-secret - namespace: {{ .Release.Namespace }} - {{- if .Values.externalSecrets.oidcClientSecret.metadata }} - {{- toYaml .Values.externalSecrets.oidcClientSecret.metadata | nindent 2 }} - {{- end }} -spec: - {{ include "keycloak.externalSecrets.lifecycle" (dict "local" .Values.externalSecrets.oidcClientSecret "global" .Values.global) | nindent 2 }} - secretStoreRef: - name: {{ .Values.global.secretStore.name }} - kind: {{ .Values.global.secretStore.kind }} - target: - name: oidc-client-secret - {{ include "keycloak.externalSecrets.targetLifecycle" (dict "local" .Values.externalSecrets.oidcClientSecret "global" .Values.global) | nindent 4 }} - template: - {{- if .Values.externalSecrets.oidcClientSecret.targetMetadata }} - metadata: - {{- toYaml .Values.externalSecrets.oidcClientSecret.targetMetadata | nindent 8 }} - {{- end }} - type: Opaque - data: - client-secret: "{{ `{{ .client_secret }}` }}" - data: - - secretKey: client_secret - remoteRef: - key: {{ .Values.keycloak.oidcSecrets.qtodo.vaultPath }} - property: client-secret -{{- end }} diff --git a/templates/rhtpa-oidc-cli-secret-external-secret.yaml b/templates/rhtpa-oidc-cli-secret-external-secret.yaml deleted file mode 100644 index 5203256..0000000 --- a/templates/rhtpa-oidc-cli-secret-external-secret.yaml +++ /dev/null @@ -1,33 +0,0 @@ -{{- if .Values.keycloak.defaultConfig }} ---- -apiVersion: "external-secrets.io/v1" -kind: ExternalSecret -metadata: - name: rhtpa-oidc-cli-secret - namespace: {{ .Release.Namespace }} - {{- if .Values.externalSecrets.rhtpa.metadata }} - {{- toYaml .Values.externalSecrets.rhtpa.metadata | nindent 2 }} - {{- end }} -spec: - {{ include "keycloak.externalSecrets.lifecycle" (dict "local" .Values.externalSecrets.rhtpa "global" .Values.global) | nindent 2 }} - secretStoreRef: - name: {{ .Values.global.secretStore.name }} - kind: {{ .Values.global.secretStore.kind }} - target: - name: rhtpa-oidc-cli-secret - {{ include "keycloak.externalSecrets.targetLifecycle" (dict "local" .Values.externalSecrets.rhtpa "global" .Values.global) | nindent 4 }} - template: - {{- if .Values.externalSecrets.rhtpa.targetMetadata }} - metadata: - {{- toYaml .Values.externalSecrets.rhtpa.targetMetadata | nindent 8 }} - {{- end }} - type: Opaque - data: - client-secret: "{{ `{{ .client_secret | trim }}` }}" - data: - - secretKey: client_secret - remoteRef: - key: {{ .Values.keycloak.oidcSecrets.rhtpaCli.vaultPath }} - property: client-secret -{{- end }} - diff --git a/values.yaml b/values.yaml index d1d15ba..22675ae 100644 --- a/values.yaml +++ b/values.yaml @@ -8,15 +8,10 @@ global: kind: ClusterSecretStore name: vault-backend -# -- Properties associated with ExternalSecret resources. +# -- Per-ExternalSecret lifecycle and metadata overrides. +# Only adminUser and postgresqlDb are managed directly by this chart. +# All other secrets should use keycloak.extraSecrets. externalSecrets: - acs: - metadata: {} - targetMetadata: {} - #creationPolicy: Owner - #deletionPolicy: Retain - #refreshPolicy: Periodic - #refreshInterval: 1h adminUser: metadata: {} targetMetadata: {} @@ -24,21 +19,6 @@ externalSecrets: #deletionPolicy: Retain #refreshPolicy: Periodic #refreshInterval: 1h - keycloakUsers: - metadata: {} - targetMetadata: {} - #creationPolicy: Owner - #deletionPolicy: Retain - #refreshPolicy: Periodic - #refreshInterval: 1h - labels: {} - oidcClientSecret: - metadata: {} - targetMetadata: {} - #creationPolicy: Owner - #deletionPolicy: Retain - #refreshPolicy: Periodic - #refreshInterval: 1h postgresqlDb: metadata: {} targetMetadata: {} @@ -46,13 +26,6 @@ externalSecrets: #deletionPolicy: Retain #refreshPolicy: Periodic #refreshInterval: 1h - rhtpa: - metadata: {} - targetMetadata: {} - #creationPolicy: Owner - #deletionPolicy: Retain - #refreshPolicy: Periodic - #refreshInterval: 1h # -- Default-deny NetworkPolicy for the keycloak namespace. # When enabled, deploys a namespace-wide NetworkPolicy that blocks all ingress and egress @@ -85,476 +58,82 @@ networkPolicy: egress: [] keycloak: + # -- Keycloak admin bootstrap user. Creates an ExternalSecret that pulls the + # admin password from the configured secret store. adminUser: enabled: true username: admin - # Keycloak admin password (infra) - passwordVaultKey: secret/data/hub/infra/keycloak/keycloak + passwordVaultKey: "" secretName: keycloak-admin-user - defaultConfig: true - defaultRealm: - clients: - - clientId: qtodo-app - enabled: true - name: qtodo - protocol: openid-connect - publicClient: false - clientAuthenticatorType: federated-jwt - serviceAccountsEnabled: true - redirectUris: - - "*" - standardFlowEnabled: true - directAccessGrantsEnabled: false - webOrigins: - - + - fullScopeAllowed: true - attributes: - jwt.credential.issuer: spiffe - # Auto-generated by template: spiffe:///ns/qtodo/sa/qtodo - jwt.credential.sub: "" - post.logout.redirect.uris: "+" - defaultClientScopes: - - web-origins - - roles - - profile - - basic - - email - optionalClientScopes: - - offline_access - - clientId: trusted-artifact-signer - enabled: true - name: Red Hat Trusted Artifact Signer Client - protocol: openid-connect - publicClient: true - redirectUris: - - "*" - - "urn:ietf:wg:oauth:2.0:oob" - - "http://localhost:*/auth/callback" - directAccessGrantsEnabled: true - standardFlowEnabled: true - implicitFlowEnabled: false - webOrigins: - - + - attributes: - oauth2.device.authorization.grant.enabled: "true" - protocolMappers: - - name: audience-mapper - protocol: openid-connect - protocolMapper: oidc-audience-mapper - config: - included.client.audience: trusted-artifact-signer - access.token.claim: "true" - id.token.claim: "false" - - name: email-mapper - protocol: openid-connect - protocolMapper: oidc-hardcoded-claim-mapper - consentRequired: false - config: - claim.name: email_verified - claim.value: "true" - jsonType.label: boolean - access.token.claim: "true" - id.token.claim: "true" - userinfo.token.claim: "false" - # ACS Central OIDC Client - - clientId: acs-central - enabled: true - name: Red Hat Advanced Cluster Security Central - protocol: openid-connect - publicClient: false - secret: ${ACS_CLIENT_SECRET} - redirectUris: - - "*" - directAccessGrantsEnabled: true - standardFlowEnabled: true - implicitFlowEnabled: false - webOrigins: - - "*" - fullScopeAllowed: true - defaultClientScopes: - - openid - - basic - - email - - profile - - roles - - web-origins - optionalClientScopes: - - address - - phone - - offline_access - protocolMappers: - - name: groups - protocol: openid-connect - protocolMapper: oidc-group-membership-mapper - consentRequired: false - config: - full.path: "false" - id.token.claim: "true" - access.token.claim: "true" - claim.name: groups - userinfo.token.claim: "true" - - name: roles - protocol: openid-connect - protocolMapper: oidc-usermodel-realm-role-mapper - consentRequired: false - config: - multivalued: "true" - userinfo.token.claim: "true" - id.token.claim: "true" - access.token.claim: "true" - claim.name: roles - jsonType.label: String - # RHTPA CLI Client - matches Trustify 'cli' client configuration - # Reference: https://github.com/guacsec/trustify-helm-charts/blob/main/charts/trustify-infrastructure/templates/keycloak/010-ConfigMap.yaml - - clientId: rhtpa-cli - enabled: true - name: RHTPA CLI Client - protocol: openid-connect - publicClient: false - secret: ${RHTPA_CLI_SECRET} - directAccessGrantsEnabled: false - standardFlowEnabled: false - implicitFlowEnabled: false - serviceAccountsEnabled: true - fullScopeAllowed: true - defaultClientScopes: - - basic - - email - - profile - - roles - - web-origins - - create:document - - read:document - - update:document - - delete:document - optionalClientScopes: - - address - - microprofile-jwt - - offline_access - - phone - attributes: - access.token.lifespan: "300" - post.logout.redirect.uris: "+" - # RHTPA Frontend Client - matches Trustify 'frontend' client configuration - # Reference: https://github.com/guacsec/trustify-helm-charts/blob/main/charts/trustify-infrastructure/templates/keycloak/010-ConfigMap.yaml - - clientId: rhtpa-frontend - enabled: true - name: RHTPA Frontend Client - protocol: openid-connect - publicClient: true - redirectUris: - - "*" - directAccessGrantsEnabled: false - standardFlowEnabled: true - implicitFlowEnabled: true - serviceAccountsEnabled: false - webOrigins: - - "*" - fullScopeAllowed: true - defaultClientScopes: - - basic - - email - - profile - - roles - - web-origins - - create:document - - read:document - - update:document - - delete:document - optionalClientScopes: - - address - - microprofile-jwt - - offline_access - - phone - attributes: - access.token.lifespan: "300" - post.logout.redirect.uris: "+" - displayName: ZTVP Realm - enabled: true - realm: ztvp - registrationAllowed: false - # Client scopes - # Note: We must define 'basic' scope with 'sub' mapper for OIDC compliance - # The 'sub' claim is required by RHTPA for user identification - clientScopes: - # OpenID scope - mandatory OIDC scope (required by ACS and other OIDC clients) - - name: openid - description: OpenID Connect built-in scope - protocol: openid-connect - attributes: - include.in.token.scope: "true" - display.on.consent.screen: "false" - protocolMappers: - - name: sub - protocol: openid-connect - protocolMapper: oidc-sub-mapper - consentRequired: false - config: - introspection.token.claim: "true" - access.token.claim: "true" - id.token.claim: "true" - # Basic scope - required for 'sub' claim in tokens - # Standard OIDC scopes required by Trustify/RHTPA - # Reference: https://github.com/mrrajan/trustify/blob/doc_rhbk_operator/docs/book/modules/admin/pages/infrastructure.adoc - - name: basic - description: OpenID Connect basic scope - protocol: openid-connect - attributes: - include.in.token.scope: "false" - display.on.consent.screen: "false" - protocolMappers: - - name: sub - protocol: openid-connect - protocolMapper: oidc-sub-mapper - consentRequired: false - config: - introspection.token.claim: "true" - access.token.claim: "true" - - name: email - description: OpenID Connect email scope - protocol: openid-connect - attributes: - include.in.token.scope: "true" - display.on.consent.screen: "true" - consent.screen.text: "${emailScopeConsentText}" - protocolMappers: - - name: email - protocol: openid-connect - protocolMapper: oidc-usermodel-attribute-mapper - consentRequired: false - config: - userinfo.token.claim: "true" - user.attribute: email - id.token.claim: "true" - access.token.claim: "true" - claim.name: email - jsonType.label: String - - name: email verified - protocol: openid-connect - protocolMapper: oidc-usermodel-attribute-mapper - consentRequired: false - config: - userinfo.token.claim: "true" - user.attribute: emailVerified - id.token.claim: "true" - access.token.claim: "true" - claim.name: email_verified - jsonType.label: boolean - - name: profile - description: OpenID Connect profile scope - protocol: openid-connect - attributes: - include.in.token.scope: "true" - display.on.consent.screen: "true" - consent.screen.text: "${profileScopeConsentText}" - protocolMappers: - - name: username - protocol: openid-connect - protocolMapper: oidc-usermodel-attribute-mapper - consentRequired: false - config: - userinfo.token.claim: "true" - user.attribute: username - id.token.claim: "true" - access.token.claim: "true" - claim.name: preferred_username - jsonType.label: String - - name: full name - protocol: openid-connect - protocolMapper: oidc-full-name-mapper - consentRequired: false - config: - id.token.claim: "true" - access.token.claim: "true" - userinfo.token.claim: "true" - - name: roles - description: OpenID Connect roles scope - protocol: openid-connect - attributes: - include.in.token.scope: "false" - display.on.consent.screen: "true" - consent.screen.text: "${rolesScopeConsentText}" - protocolMappers: - - name: realm roles - protocol: openid-connect - protocolMapper: oidc-usermodel-realm-role-mapper - consentRequired: false - config: - multivalued: "true" - user.attribute: foo - access.token.claim: "true" - claim.name: realm_access.roles - jsonType.label: String - - name: audience resolve - protocol: openid-connect - protocolMapper: oidc-audience-resolve-mapper - consentRequired: false - - name: web-origins - description: OpenID Connect web origins scope - protocol: openid-connect - attributes: - include.in.token.scope: "false" - display.on.consent.screen: "false" - protocolMappers: - - name: allowed web origins - protocol: openid-connect - protocolMapper: oidc-allowed-origins-mapper - consentRequired: false - config: - access.token.claim: "true" - # RHTPA document permission scopes - - name: create:document - description: Permission to create documents - protocol: openid-connect - attributes: - include.in.token.scope: "true" - display.on.consent.screen: "false" - - name: read:document - description: Permission to read documents - protocol: openid-connect - attributes: - include.in.token.scope: "true" - display.on.consent.screen: "false" - - name: update:document - description: Permission to update documents - protocol: openid-connect - attributes: - include.in.token.scope: "true" - display.on.consent.screen: "false" - - name: delete:document - description: Permission to delete documents - protocol: openid-connect - attributes: - include.in.token.scope: "true" - display.on.consent.screen: "false" - # Set default client scopes for the realm (applied to all new clients) - defaultDefaultClientScopes: - - openid - - basic - - email - - profile - - roles - - web-origins - roles: - realm: - - description: QTodo App Administrator - name: qtodo-admin - - description: Read-only access - name: viewer - - description: RHTPA SBOM Creator - name: create:sbom - - description: RHTPA Document Creator - name: create:document - - description: ACS Administrator - name: acs-admin - users: - - createdTimestamp: 1 - credentials: - - temporary: true - type: password - value: ${QTODO_ADMIN_PASSWORD} - email: qtodo-admin@example.com - emailVerified: true - enabled: true - firstName: QTodo - lastName: Admin - realmRoles: - - qtodo-admin - requiredActions: - - UPDATE_PASSWORD - username: qtodo-admin - - createdTimestamp: 1 - credentials: - - temporary: true - type: password - value: ${QTODO_USER1_PASSWORD} - email: qtodo-user1@example.com - emailVerified: true - enabled: true - firstName: QTodo - lastName: User-1 - realmRoles: - - viewer - requiredActions: - - UPDATE_PASSWORD - username: qtodo-user1 - - createdTimestamp: 1 - credentials: - - temporary: false - type: password - value: ${RHTAS_USER_PASSWORD} - email: rhtas-user@example.com - emailVerified: true - enabled: true - firstName: RHTAS - lastName: Signer - realmRoles: - - viewer - username: rhtas-user - - createdTimestamp: 1 - credentials: - - temporary: false - type: password - value: ${RHTPA_USER_PASSWORD} - email: rhtpa-user@example.com - emailVerified: true - enabled: true - firstName: RHTPA - lastName: User - realmRoles: - - viewer - - create:sbom - - create:document - username: rhtpa-user - - createdTimestamp: 1 - credentials: - - temporary: false - type: password - value: ${ACS_ADMIN_PASSWORD} - email: acs-admin@example.com - emailVerified: true - enabled: true - firstName: ACS - lastName: Administrator - realmRoles: - - acs-admin - - offline_access - username: acs-admin + + # -- Keycloak Ingress (OpenShift Route). ingress: enabled: true service: keycloak-service-trusted termination: reencrypt hostname: "" + + # -- Keycloak instance name. Used for pod labels, service names, and hostname generation. name: keycloak + + # -- PostgreSQL database credentials. Creates an ExternalSecret that pulls the + # DB password from the configured secret store. postgresqlDb: database: keycloak - # Keycloak DB password path (infra) - passwordVaultKey: secret/data/hub/infra/keycloak/keycloak + passwordVaultKey: "" secretName: postgresql-db username: keycloak - realms: [] + + # -- TLS configuration for the Keycloak instance. tls: secret: keycloak-tls serviceServing: true - users: - # User credentials path (infra) - passwordVaultKey: secret/data/hub/infra/users/keycloak-users - secretName: keycloak-users - # OIDC client secrets for realm configuration - oidcSecrets: - # QTodo OIDC client secret — disabled when using federated-jwt (client assertion) - qtodo: - enabled: false - vaultPath: secret/data/apps/qtodo/qtodo-oidc-client - # RHTPA CLI OIDC client secret (infra) - rhtpaCli: - vaultPath: secret/data/hub/infra/rhtpa/rhtpa-oidc-cli - # ACS Central OIDC client secret (infra) - acsClient: - vaultPath: secret/data/hub/infra/acs/acs-central - # SPIFFE Identity Provider for Federated Client Authentication + + # -- Keycloak realm definitions. Each entry is a full Keycloak realm representation + # that will be rendered as a KeycloakRealmImport CR. Consumers define their realm + # structure (clients, users, roles, scopes, identity providers) here. + # + # Example: + # realms: + # - realm: my-realm + # enabled: true + # displayName: "My Realm" + # clients: [...] + # users: [...] + realms: [] + + # -- Realm import placeholders. Maps placeholder variables (used as ${VAR} in realm + # definitions) to Kubernetes Secret references. Applied to all realm imports. + # + # Example: + # realmPlaceholders: + # MY_USER_PASSWORD: + # secret: + # name: my-users-secret + # key: user-password + realmPlaceholders: {} + + # -- Extra ExternalSecrets. Each entry creates an ExternalSecret resource that + # pulls data from the configured secret store into a Kubernetes Secret. + # Use this for user passwords, OIDC client secrets, or any other secrets + # that your realm configuration requires. + # + # Example: + # extraSecrets: + # - name: my-users + # targetName: my-users-secret + # data: + # - secretKey: user_password + # remoteRef: + # key: secret/data/my/path + # property: user-password + # templateData: + # user-password: "{{ .user_password }}" + extraSecrets: [] + + # -- SPIFFE Identity Provider for Federated Client Authentication. # Requires RHBK 26.4+ with Technology Preview features: spiffe + client-auth-federated - # (automatically enabled in keycloak.yaml when this is enabled) + # (automatically enabled in keycloak.yaml when this is enabled). # # Uses an OIDC provider type (not Keycloak's native SPIFFE provider) because the # ZTWIM operator forces SpireServer.jwtIssuer to be an HTTPS URL, so JWT SVIDs @@ -565,7 +144,7 @@ keycloak: # # Reference: https://www.keycloak.org/2026/01/federated-client-authentication spiffeIdentityProvider: - enabled: true + enabled: false config: alias: spiffe displayName: SPIFFE Workload Identity @@ -573,12 +152,9 @@ keycloak: enabled: true hideOnLogin: true config: - # SPIRE OIDC Discovery Provider issuer URL (auto-generated if empty) issuer: "" - # Required by Keycloak OIDC IdP but unused for federated client auth authorizationUrl: "" tokenUrl: "" - # SPIRE OIDC Discovery Provider JWKS URL (auto-generated if empty) jwksUrl: "" clientId: keycloak clientSecret: unused