From f982b86ba9b6c89d2ea4ec0279762ae556e92464 Mon Sep 17 00:00:00 2001 From: Zoran Sinnema Date: Fri, 5 Dec 2025 17:23:47 +0100 Subject: [PATCH 1/4] feat: refactor accounts realm.json to use templates --- .../accounts/deploy/resources/realm.json | 186 +++--------------- .../accounts/deploy/templates/_components.tpl | 75 +++++++ .../accounts/deploy/templates/_events.tpl | 100 ++++++++++ .../accounts/deploy/templates/_helpers.tpl | 0 .../deploy/templates/_identity_providers.tpl | 54 +++++ .../deploy/templates/_users_roles.tpl | 95 +++++++++ applications/accounts/deploy/values.yaml | 10 + .../accounts/scripts/create_api_user.sh | 18 +- .../accounts/scripts/kc-entrypoint.sh | 2 +- 9 files changed, 363 insertions(+), 177 deletions(-) create mode 100644 applications/accounts/deploy/templates/_components.tpl create mode 100644 applications/accounts/deploy/templates/_events.tpl create mode 100644 applications/accounts/deploy/templates/_helpers.tpl create mode 100644 applications/accounts/deploy/templates/_identity_providers.tpl create mode 100644 applications/accounts/deploy/templates/_users_roles.tpl diff --git a/applications/accounts/deploy/resources/realm.json b/applications/accounts/deploy/resources/realm.json index def7e2971..af17f73da 100644 --- a/applications/accounts/deploy/resources/realm.json +++ b/applications/accounts/deploy/resources/realm.json @@ -1,177 +1,24 @@ -{{- define "deploy_accounts_utils.role" }} - { - "id": {{ uuidv4 | quote }}, - "name": {{ .role| quote }}, - "composite": false, - "clientRole": true, - "containerId": {{ .app.harness.name | quote }}, - "attributes": {} - } -{{- end}} -{{- define "deploy_accounts_utils.user" }} - { - "username": {{ .user.username | default .user.email | quote }}, - "email": {{ .user.email | default .user.username | quote }}, - "enabled": true, - "firstName": {{ .user.firstName | default "Test" | quote }}, - "lastName": {{ .user.lastName | default "User" | quote }}, - "credentials": [ - { - "type": "password", - "value": {{ .user.password | default "test" | quote }} - } - ], - "realmRoles": {{ .user.realmRoles | toJson }}, - "clientRoles": { - {{ .app.harness.name | quote }}: {{ .user.clientRoles | toJson }} - } - } - -{{- end}} { "id": {{ .Values.namespace | quote }}, "realm": {{ .Values.namespace | quote }}, "enabled": true, "sslRequired": {{ ternary "none" "external" (not .Values.tls) | quote }}, - "loginTheme": "keycloak", - "accountTheme": "keycloak", - "adminTheme": "keycloak", - "emailTheme": "keycloak", - "registrationAllowed": true, - "registrationEmailAsUsername": false, + "loginTheme": {{ .Values.apps.accounts.theme.login | default "keycloak" | quote }}, + "accountTheme": {{ .Values.apps.accounts.theme.account | default "keycloak" | quote }}, + "adminTheme": {{ .Values.apps.accounts.theme.admiin | default "keycloak" | quote }}, + "emailTheme": {{ .Values.apps.accounts.theme.email | default "keycloak" | quote }}, + "registrationAllowed": {{ .Values.apps.accounts.registrationAllowed | default true }}, + "registrationEmailAsUsername": {{ .Values.apps.accounts.registrationEmailAsUsername | default false }}, "rememberMe": true, "verifyEmail": false, "loginWithEmailAllowed": true, "duplicateEmailsAllowed": false, "resetPasswordAllowed": true, - "editUsernameAllowed": true, - "components": { - "org.keycloak.userprofile.UserProfileProvider": [ - { - "id": "002b69df-9702-40dd-b73e-3a66d161bf11", - "providerId": "declarative-user-profile", - "subComponents": {}, - "config": { - "kc.user.profile.config": [ - "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}]}" - ] - } - } - ], - "org.keycloak.keys.KeyProvider": [ - { - "id": "e632ce46-36ad-421a-b1a5-776383cc1565", - "name": "rsa-generated", - "providerId": "rsa-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "b68bee45-a8f0-46ca-b7d9-0df90189736a", - "name": "hmac-generated-hs512", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS512" - ] - } - }, - { - "id": "55960a57-af77-4f4c-8b6e-925c74bb44db", - "name": "aes-generated", - "providerId": "aes-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "ce068675-5cae-434e-851f-09f653ccc604", - "name": "rsa-enc-generated", - "providerId": "rsa-enc-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "RSA-OAEP" - ] - } - } - ] - }, - "users": [ - {{- $j := 0}} - {{- range $app := .Values.apps }} - {{- if (hasKey $app.harness "accounts") }} - {{- if $j}},{{end}} - {{- if $app.harness.accounts.users}} - {{- $j = add1 $j }} - {{- end }} - {{- range $i, $user := $app.harness.accounts.users }}{{if $i}},{{end}} - {{ include "deploy_accounts_utils.user" (dict "root" $ "app" $app "user" $user) }} - {{- end }} - {{- end }} - - {{- end }} - ], - "roles": { - "realm": [ - { - "id": "70835ad6-1454-4bc5-86a4-f1597e776b75", - "name": {{ .Values.apps.accounts.admin.role | quote }}, - "composite": false, - "clientRole": false, - "containerId": {{ .Values.namespace | quote }}, - "attributes": {} - }, - { - "id": "498353dd-88eb-4a5e-99b8-d912e0f20f23", - "name": "uma_authorization", - "description": "${role_uma_authorization}", - "composite": false, - "clientRole": false, - "containerId": {{ .Values.namespace | quote }}, - "attributes": {} - }, - { - "id": "f99970f1-958b-4bb8-8b39-0d7498b0ecc4", - "name": "offline_access", - "description": "${role_offline-access}", - "composite": false, - "clientRole": false, - "containerId": {{ .Values.namespace | quote }}, - "attributes": {} - } - ], - "client": { - {{- $k := 0}} - {{- range $app := .Values.apps }} - - {{- if (hasKey $app.harness "accounts") }} - {{- if $k}},{{end}} - {{ $app.harness.name | quote }}: [ - {{- range $i, $role := $app.harness.accounts.roles }} - {{if $i}},{{end}} - {{- include "deploy_accounts_utils.role" (dict "root" $ "app" $app "role" $role) }} - {{- end }} - ] - {{- $k = add1 $k }} - {{- end }} - {{- end }} - } - }, + "editUsernameAllowed": {{ .Values.apps.accounts.editUsernameAllowed }}, + {{- include "deploy_accounts_utils.events" (dict "app" .Values.apps.accounts) | indent 8 -}} + {{- include "deploy_accounts_utils.identity_providers" (dict "app" .Values.apps.accounts) | indent 8 -}} + {{- include "deploy_accounts_utils.components" . | indent 8 -}} + {{- include "deploy_accounts_utils.users_roles" (dict "Values" .Values) | indent 8 -}} "clientScopeMappings": { "account": [ { @@ -775,6 +622,17 @@ "jsonType.label": "String" } }, + { + "id": "0b8d0cf7-eebc-4c51-892e-2b65212856b4", + "name": "sub", + "protocol": "openid-connect", + "protocolMapper": "oidc-sub-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "access.token.claim": "true" + } + }, { "id": "3d763f84-d417-4b4e-99e4-2b0e05bf861a", "name": "family name", diff --git a/applications/accounts/deploy/templates/_components.tpl b/applications/accounts/deploy/templates/_components.tpl new file mode 100644 index 000000000..4f8180d52 --- /dev/null +++ b/applications/accounts/deploy/templates/_components.tpl @@ -0,0 +1,75 @@ +{{- define "deploy_accounts_utils.user_profile_provider_component" -}} + "org.keycloak.userprofile.UserProfileProvider": [ + { + "id": "002b69df-9702-40dd-b73e-3a66d161bf11", + "providerId": "declarative-user-profile", + "subComponents": {}, + "config": { + "kc.user.profile.config": [ + "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}],\"unmanagedAttributePolicy\":\"ENABLED\"}" + ] + } + } + ] +{{- end -}} +{{- define "deploy_accounts_utils.key_provider_component" -}} + "org.keycloak.keys.KeyProvider": [ + { + "id": "e632ce46-36ad-421a-b1a5-776383cc1565", + "name": "rsa-generated", + "providerId": "rsa-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "b68bee45-a8f0-46ca-b7d9-0df90189736a", + "name": "hmac-generated-hs512", + "providerId": "hmac-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "HS512" + ] + } + }, + { + "id": "55960a57-af77-4f4c-8b6e-925c74bb44db", + "name": "aes-generated", + "providerId": "aes-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "ce068675-5cae-434e-851f-09f653ccc604", + "name": "rsa-enc-generated", + "providerId": "rsa-enc-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "RSA-OAEP" + ] + } + } + ] +{{- end -}} +# +{{- define "deploy_accounts_utils.components" -}} + "components": { + {{template "deploy_accounts_utils.user_profile_provider_component" }}, + {{template "deploy_accounts_utils.key_provider_component" }} + }, +{{- end -}} \ No newline at end of file diff --git a/applications/accounts/deploy/templates/_events.tpl b/applications/accounts/deploy/templates/_events.tpl new file mode 100644 index 000000000..efd2d701a --- /dev/null +++ b/applications/accounts/deploy/templates/_events.tpl @@ -0,0 +1,100 @@ +# Accounts _helper.tpl +{{- define "deploy_accounts_utils.event_listeners" -}} + "eventsListeners": [ + "metacell-admin-event-listener", + "jboss-logging" + ], +{{- end -}} +# +{{- define "deploy_accounts_utils.event_types" -}} + "enabledEventTypes": [ + "SEND_RESET_PASSWORD", + "UPDATE_CONSENT_ERROR", + "GRANT_CONSENT", + "VERIFY_PROFILE_ERROR", + "REMOVE_TOTP", + "REVOKE_GRANT", + "UPDATE_TOTP", + "LOGIN_ERROR", + "CLIENT_LOGIN", + "RESET_PASSWORD_ERROR", + "IMPERSONATE_ERROR", + "CODE_TO_TOKEN_ERROR", + "CUSTOM_REQUIRED_ACTION", + "OAUTH2_DEVICE_CODE_TO_TOKEN_ERROR", + "RESTART_AUTHENTICATION", + "IMPERSONATE", + "UPDATE_PROFILE_ERROR", + "LOGIN", + "OAUTH2_DEVICE_VERIFY_USER_CODE", + "UPDATE_PASSWORD_ERROR", + "CLIENT_INITIATED_ACCOUNT_LINKING", + "TOKEN_EXCHANGE", + "AUTHREQID_TO_TOKEN", + "LOGOUT", + "REGISTER", + "DELETE_ACCOUNT_ERROR", + "CLIENT_REGISTER", + "IDENTITY_PROVIDER_LINK_ACCOUNT", + "DELETE_ACCOUNT", + "UPDATE_PASSWORD", + "CLIENT_DELETE", + "FEDERATED_IDENTITY_LINK_ERROR", + "IDENTITY_PROVIDER_FIRST_LOGIN", + "CLIENT_DELETE_ERROR", + "VERIFY_EMAIL", + "CLIENT_LOGIN_ERROR", + "RESTART_AUTHENTICATION_ERROR", + "EXECUTE_ACTIONS", + "REMOVE_FEDERATED_IDENTITY_ERROR", + "TOKEN_EXCHANGE_ERROR", + "PERMISSION_TOKEN", + "SEND_IDENTITY_PROVIDER_LINK_ERROR", + "EXECUTE_ACTION_TOKEN_ERROR", + "SEND_VERIFY_EMAIL", + "OAUTH2_DEVICE_AUTH", + "EXECUTE_ACTIONS_ERROR", + "REMOVE_FEDERATED_IDENTITY", + "OAUTH2_DEVICE_CODE_TO_TOKEN", + "IDENTITY_PROVIDER_POST_LOGIN", + "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", + "OAUTH2_DEVICE_VERIFY_USER_CODE_ERROR", + "UPDATE_EMAIL", + "REGISTER_ERROR", + "REVOKE_GRANT_ERROR", + "EXECUTE_ACTION_TOKEN", + "LOGOUT_ERROR", + "UPDATE_EMAIL_ERROR", + "CLIENT_UPDATE_ERROR", + "AUTHREQID_TO_TOKEN_ERROR", + "UPDATE_PROFILE", + "CLIENT_REGISTER_ERROR", + "FEDERATED_IDENTITY_LINK", + "SEND_IDENTITY_PROVIDER_LINK", + "SEND_VERIFY_EMAIL_ERROR", + "RESET_PASSWORD", + "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", + "OAUTH2_DEVICE_AUTH_ERROR", + "UPDATE_CONSENT", + "REMOVE_TOTP_ERROR", + "VERIFY_EMAIL_ERROR", + "SEND_RESET_PASSWORD_ERROR", + "CLIENT_UPDATE", + "CUSTOM_REQUIRED_ACTION_ERROR", + "IDENTITY_PROVIDER_POST_LOGIN_ERROR", + "UPDATE_TOTP_ERROR", + "CODE_TO_TOKEN", + "VERIFY_PROFILE", + "GRANT_CONSENT_ERROR", + "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" + ], +{{- end -}} +# +{{- define "deploy_accounts_utils.events" -}} + {{- if eq .app.useEvents true }} + {{template "deploy_accounts_utils.event_listeners" }} + {{template "deploy_accounts_utils.event_types" }} + "adminEventsEnabled": true, + "adminEventsDetailsEnabled": true, + {{- end }} +{{- end -}} \ No newline at end of file diff --git a/applications/accounts/deploy/templates/_helpers.tpl b/applications/accounts/deploy/templates/_helpers.tpl new file mode 100644 index 000000000..e69de29bb diff --git a/applications/accounts/deploy/templates/_identity_providers.tpl b/applications/accounts/deploy/templates/_identity_providers.tpl new file mode 100644 index 000000000..4664120b4 --- /dev/null +++ b/applications/accounts/deploy/templates/_identity_providers.tpl @@ -0,0 +1,54 @@ +# +{{- define "deploy_accounts_utils.github_identity_provider" -}} + { + "alias": "github", + "internalId": "a3b32961-038c-41df-8e7c-815cda420aac", + "providerId": "github", + "enabled": true, + "updateProfileFirstLoginMode": "on", + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "syncMode": "IMPORT", + "clientSecret": {{ .app.harness.secrets.github_clientSecret | default "" | quote }}, + "clientId": {{ .app.harness.secrets.github_clientId | default "" | quote }}, + "useJwksUrl": "true" + } + } +{{- end -}} +# +{{- define "deploy_accounts_utils.google_identity_provider" -}} + { + "alias": "google", + "internalId": "7f65669a-e52f-426b-a9f6-f37253b00dae", + "providerId": "google", + "enabled": true, + "updateProfileFirstLoginMode": "on", + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "syncMode": "IMPORT", + "clientSecret": {{ .app.harness.secrets.google_clientSecret | default "" | quote }}, + "clientId": {{ .app.harness.secrets.google_clientId | default "" | quote }}, + "useJwksUrl": "true" + } + } +{{- end -}} +# +{{- define "deploy_accounts_utils.identity_providers" -}} + {{- if hasKey .app "identityProviders" -}} + "identityProviders": [ + {{- range $provider := .app.identityProviders }} + {{ include (printf "deploy_accounts_utils.%s_identity_provider" $provider) (dict "app" $.app) | indent 12 }} + {{- end -}} + ], + {{- end }} +{{- end -}} \ No newline at end of file diff --git a/applications/accounts/deploy/templates/_users_roles.tpl b/applications/accounts/deploy/templates/_users_roles.tpl new file mode 100644 index 000000000..e83fbf5cc --- /dev/null +++ b/applications/accounts/deploy/templates/_users_roles.tpl @@ -0,0 +1,95 @@ +# Accounts _helper.tpl +{{- define "deploy_accounts_utils.role" }} + { + "id": {{ uuidv4 | quote }}, + "name": {{ .role| quote }}, + "composite": false, + "clientRole": true, + "containerId": {{ .app.harness.name | quote }}, + "attributes": {} + } +{{- end}} +# +{{- define "deploy_accounts_utils.user" }} + { + "username": {{ .user.username | default .user.email | quote }}, + "email": {{ .user.email | default .user.username | quote }}, + "enabled": true, + "firstName": {{ .user.firstName | default "Test" | quote }}, + "lastName": {{ .user.lastName | default "User" | quote }}, + "credentials": [ + { + "type": "password", + "value": {{ .user.password | default "test" | quote }} + } + ], + "realmRoles": {{ .user.realmRoles | toJson }}, + "clientRoles": { + {{ .app.harness.name | quote }}: {{ .user.clientRoles | toJson }} + } + } +{{- end}} +# +{{- define "deploy_accounts_utils.users_roles" }} + "users": [ + {{- $j := 0}} + {{- range $app := .Values.apps }} + {{- if (hasKey $app.harness "accounts") }} + {{- if $j}},{{end}} + {{- if $app.harness.accounts.users}} + {{- $j = add1 $j }} + {{- end }} + {{- range $i, $user := $app.harness.accounts.users }}{{if $i}},{{end}} + {{ include "deploy_accounts_utils.user" (dict "root" $ "app" $app "user" $user) }} + {{- end }} + {{- end }} + + {{- end }} + ], + "roles": { + "realm": [ + { + "id": "70835ad6-1454-4bc5-86a4-f1597e776b75", + "name": {{ .Values.apps.accounts.admin.role | quote }}, + "composite": false, + "clientRole": false, + "containerId": {{ .Values.namespace | quote }}, + "attributes": {} + }, + { + "id": "498353dd-88eb-4a5e-99b8-d912e0f20f23", + "name": "uma_authorization", + "description": "${role_uma_authorization}", + "composite": false, + "clientRole": false, + "containerId": {{ .Values.namespace | quote }}, + "attributes": {} + }, + { + "id": "f99970f1-958b-4bb8-8b39-0d7498b0ecc4", + "name": "offline_access", + "description": "${role_offline-access}", + "composite": false, + "clientRole": false, + "containerId": {{ .Values.namespace | quote }}, + "attributes": {} + } + ], + "client": { + {{- $k := 0}} + {{- range $app := .Values.apps }} + + {{- if (hasKey $app.harness "accounts") }} + {{- if $k}},{{end}} + {{ $app.harness.name | quote }}: [ + {{- range $i, $role := $app.harness.accounts.roles }} + {{if $i}},{{end}} + {{- include "deploy_accounts_utils.role" (dict "root" $ "app" $app "role" $role) }} + {{- end }} + ] + {{- $k = add1 $k }} + {{- end }} + {{- end }} + } + }, +{{- end -}} diff --git a/applications/accounts/deploy/values.yaml b/applications/accounts/deploy/values.yaml index 01401824a..5c3f0a26b 100644 --- a/applications/accounts/deploy/values.yaml +++ b/applications/accounts/deploy/values.yaml @@ -85,3 +85,13 @@ admin: pass: metacell user: admin role: administrator +editUsernameAllowed: true +useEvents: false +identityProviders: +- github +- google +theme: + login: "keycloak" + account: "keycloak" + admin: "keycloak" + email: "keycloak" \ No newline at end of file diff --git a/applications/accounts/scripts/create_api_user.sh b/applications/accounts/scripts/create_api_user.sh index caf92fff5..8f988aee9 100755 --- a/applications/accounts/scripts/create_api_user.sh +++ b/applications/accounts/scripts/create_api_user.sh @@ -7,19 +7,13 @@ PASSWORD=$(cat /opt/cloudharness/resources/auth/api_user_password) echo "Checking if API user exists..." # Check if user already exists -if /opt/keycloak/bin/kcadm.sh get users -q "username=$USERNAME" | grep -q "$USERNAME"; then - echo "ERROR: API user $USERNAME already exists, but password is out of sync. You may need to reset it manually." - # /opt/keycloak/bin/kcadm.sh set-password --username "$USERNAME" --new-password "$PASSWORD" - # Removed automatic password reset as that would only work if the main admin password is unchanged from the default password - # That would create the false impression that the password is reset successfully when in fact it has not on production systems - exit 0 +if /opt/keycloak/bin/kcadm.sh get users -q "username=$USERNAME" | grep -v "$USERNAME"; then + # create the user and reload keycloak + echo "Creating API user $USERNAME" + /opt/keycloak/bin/kcadm.sh create users -s "username=$USERNAME" -s enabled=True + echo "API user created successfully" fi -echo "Creating API user $USERNAME" -set -e -# create the user and reload keycloak -/opt/keycloak/bin/kcadm.sh create users -s "username=$USERNAME" -s enabled=True +echo Setting API user password /opt/keycloak/bin/kcadm.sh set-password --username "$USERNAME" --new-password "$PASSWORD" /opt/keycloak/bin/kcadm.sh add-roles --uusername "$USERNAME" --rolename admin - -echo "API user created successfully" \ No newline at end of file diff --git a/applications/accounts/scripts/kc-entrypoint.sh b/applications/accounts/scripts/kc-entrypoint.sh index 2657b53ce..e21814cbf 100644 --- a/applications/accounts/scripts/kc-entrypoint.sh +++ b/applications/accounts/scripts/kc-entrypoint.sh @@ -21,7 +21,7 @@ if [ -n "$API_PASSWORD" ] && /opt/keycloak/bin/kcadm.sh config credentials \ echo "Successfully authenticated as $API_USERNAME" echo "Startup scripts not needed (admin_api user already exists)" else - echo "admin_api user does not exist or authentication failed. Authenticating as bootstrap admin to create the user..." + echo "admin_api user does not exist or authentication failed. Authenticating as bootstrap admin to create/update the user..." # Authenticate as bootstrap admin to create admin_api user if ! /opt/keycloak/bin/kcadm.sh config credentials \ From 9f6296c16d5fb423e0548455da2110b639d6c3a7 Mon Sep 17 00:00:00 2001 From: Zoran Sinnema Date: Mon, 8 Dec 2025 15:50:46 +0100 Subject: [PATCH 2/4] fix: typo admiin --> admin --- applications/accounts/deploy/resources/realm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/accounts/deploy/resources/realm.json b/applications/accounts/deploy/resources/realm.json index af17f73da..cd280f027 100644 --- a/applications/accounts/deploy/resources/realm.json +++ b/applications/accounts/deploy/resources/realm.json @@ -5,7 +5,7 @@ "sslRequired": {{ ternary "none" "external" (not .Values.tls) | quote }}, "loginTheme": {{ .Values.apps.accounts.theme.login | default "keycloak" | quote }}, "accountTheme": {{ .Values.apps.accounts.theme.account | default "keycloak" | quote }}, - "adminTheme": {{ .Values.apps.accounts.theme.admiin | default "keycloak" | quote }}, + "adminTheme": {{ .Values.apps.accounts.theme.admin | default "keycloak" | quote }}, "emailTheme": {{ .Values.apps.accounts.theme.email | default "keycloak" | quote }}, "registrationAllowed": {{ .Values.apps.accounts.registrationAllowed | default true }}, "registrationEmailAsUsername": {{ .Values.apps.accounts.registrationEmailAsUsername | default false }}, From cf173687ca2fc754ff6401eebd91b5c55c579f73 Mon Sep 17 00:00:00 2001 From: Filippo Ledda Date: Thu, 4 Dec 2025 18:37:45 +0100 Subject: [PATCH 3/4] revert: changes to create_api_user --- applications/accounts/scripts/create_api_user.sh | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/applications/accounts/scripts/create_api_user.sh b/applications/accounts/scripts/create_api_user.sh index 8f988aee9..2061d5f8d 100755 --- a/applications/accounts/scripts/create_api_user.sh +++ b/applications/accounts/scripts/create_api_user.sh @@ -7,13 +7,17 @@ PASSWORD=$(cat /opt/cloudharness/resources/auth/api_user_password) echo "Checking if API user exists..." # Check if user already exists -if /opt/keycloak/bin/kcadm.sh get users -q "username=$USERNAME" | grep -v "$USERNAME"; then - # create the user and reload keycloak - echo "Creating API user $USERNAME" - /opt/keycloak/bin/kcadm.sh create users -s "username=$USERNAME" -s enabled=True - echo "API user created successfully" +if /opt/keycloak/bin/kcadm.sh get users -q "username=$USERNAME" | grep -q "$USERNAME"; then + echo "ERROR: API user $USERNAME already exists, but password is out of sync. You may need to reset it manually." + # /opt/keycloak/bin/kcadm.sh set-password --username "$USERNAME" --new-password "$PASSWORD" + # Removed automatic password reset as that would only work if the main admin password is unchanged from the default password + # That would create the false impression that the password is reset successfully when in fact it has not on production systems + exit 0 fi -echo Setting API user password +echo "Creating API user $USERNAME" +set -e +# create the user and reload keycloak +/opt/keycloak/bin/kcadm.sh create users -s "username=$USERNAME" -s enabled=True /opt/keycloak/bin/kcadm.sh set-password --username "$USERNAME" --new-password "$PASSWORD" /opt/keycloak/bin/kcadm.sh add-roles --uusername "$USERNAME" --rolename admin From e098ae383ac3d8ae60a552638d51690262d76639 Mon Sep 17 00:00:00 2001 From: Zoran Sinnema Date: Tue, 9 Dec 2025 16:01:05 +0100 Subject: [PATCH 4/4] revert: changes to create_api_user --- applications/accounts/scripts/create_api_user.sh | 2 ++ applications/accounts/scripts/kc-entrypoint.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/applications/accounts/scripts/create_api_user.sh b/applications/accounts/scripts/create_api_user.sh index 2061d5f8d..caf92fff5 100755 --- a/applications/accounts/scripts/create_api_user.sh +++ b/applications/accounts/scripts/create_api_user.sh @@ -21,3 +21,5 @@ set -e /opt/keycloak/bin/kcadm.sh create users -s "username=$USERNAME" -s enabled=True /opt/keycloak/bin/kcadm.sh set-password --username "$USERNAME" --new-password "$PASSWORD" /opt/keycloak/bin/kcadm.sh add-roles --uusername "$USERNAME" --rolename admin + +echo "API user created successfully" \ No newline at end of file diff --git a/applications/accounts/scripts/kc-entrypoint.sh b/applications/accounts/scripts/kc-entrypoint.sh index e21814cbf..2657b53ce 100644 --- a/applications/accounts/scripts/kc-entrypoint.sh +++ b/applications/accounts/scripts/kc-entrypoint.sh @@ -21,7 +21,7 @@ if [ -n "$API_PASSWORD" ] && /opt/keycloak/bin/kcadm.sh config credentials \ echo "Successfully authenticated as $API_USERNAME" echo "Startup scripts not needed (admin_api user already exists)" else - echo "admin_api user does not exist or authentication failed. Authenticating as bootstrap admin to create/update the user..." + echo "admin_api user does not exist or authentication failed. Authenticating as bootstrap admin to create the user..." # Authenticate as bootstrap admin to create admin_api user if ! /opt/keycloak/bin/kcadm.sh config credentials \