1

I’m automating a Keycloak 26.1.2 installation and need to create a permanent admin user entirely via shell script and the Admin CLI (kcadm.sh/kc.sh), not via the web UI. My installation script does the following steps:

1. Bootstrap temporary admin

kc.sh bootstrap-admin user --username:env KC_BOOTSTRAP_ADMIN_USERNAME --password:env KC_BOOTSTRAP_ADMIN_PASSWORD --no‑prompt

(per https://www.keycloak.org/server/bootstrap-admin-recovery)

2. Start Keycloak with:

kc.sh start ...

3. Import custom realm.json:

kc.sh import --file realm.json --override=false ...

4. Create permanent “super‑admin” user—fully automated, not via the web UI—that:

  • Has full realm‑admin rights in the imported custom realm
  • Ideally also has full realm‑admin rights in the master realm

5. Cleanup: Delete the temporary bootstrap user once the permanent admin exists

I’m stuck on Step 4: how exactly do I grant this user the built‑in realm‑admin role (or equivalent full‑access roles) in both realms programmatically with kcadm.sh? All I’ve found online so far explains how to do it via the Admin Console UI, or only covers the temporary bootstrap user. I need the exact kcadm.sh add-roles (or other) invocation(s).

Question

How do I, in Keycloak 26.1.2, grant a non‑UI, script‑driven permanent admin user full administrative access to:

  1. The master realm
  2. A custom imported realm

using only kcadm.sh (and no interactive login)?

Edit

The question How do I create a permanent admin account in Keycloak 26.0.0? unfortunately doesn't answer my question, as it partly involves the UI, and I also want to give the permanent admin full permissions to both the master and custom realms. This isn't described there.

Dawid
  • 121

2 Answers2

1

This related Server Fault question (and their cross-posted thread on GitHub) has comments showing creation of an admin user once you have created the temporary admin credential. Plus I found a kcadm reference with an example of insecure password on the command line.

kc.sh bootstrap-admin user --username:env KC_BOOTSTRAP_ADMIN_USERNAME --password:env KC_BOOTSTRAP_ADMIN_PASSWORD --no‑prompt
kcadm.sh config credentials    --realm master     --user ${KC_BOOTSTRAP_ADMIN_USERNAME} --password ${KC_BOOTSTRAP_ADMIN_PASSWORD}
kcadm.sh create users -r master -s username=myPermAdmin -s enabled=true  
kcadm.sh set-password -r master --username myPermAdmin --new-password strongAndComplicatedPassword
kcadm.sh add-roles --uusername myPermAdmin  --rolename admin

Replace users and credentials with your own, and look them up from a secret management system. Consider creating additional global super users if that makes sense for your organization, for example personal accounts for you the system administrator, and the chief security officer.

Delete the temporary bootstrap user. However the cli method I found to do so, kcadm.sh delete users requires being provided the id. Fully automating that is an exercise for the reader.

Creating permanent admin user in the script can be skipped if it already exists. Such as if a super admin user was synced from a user directory, or if creating the user was done manually when they enrolled multiple auth factors (passkey, OTP).

Regarding built-in roles, global role admin in realm master has full control over any realm. That "custom" realm of yours, and all others. Should include managing users and all other objects, but the documentation strongly encourages users in master to only be used for updates to realms.

Useful role based access control implies creating additional users that do not have admin in master. The fix auth role for help desk staff should be realm specific, and have less access than full control over everything auth.

I do not have cli examples of building realm specific roles and apps from scratch. All the rest of the build that is less than admin role. Perhaps build them in the web UI, and export them, for import once this admin credentials bootstrap is complete.

John Mahowald
  • 36,071
1

To grant an user full administrative privileges on both the master and a custom realm in Keycloak 26.1.2, you can leverage the fact that every realm in the master realm appears as a “client” with the name <realm-name>-realm. By assigning realm-management roles on that client to your permanent admin user, you effectively give them full control over the target realm.

Grant full “realm-admin” rights in the master realm:

kcadm.sh add-roles \
  --uusername "${MASTER_REALM_PERMANENT_ADMIN_USERNAME}" \
  --rolename admin \
  ${ADMIN_CLI_OPTIONS}

Grant full admin rights on your custom realm by targeting the <realm-name>-realm client in the master realm. From Red Hat’s documentation:

Admin users within the master realm can be granted management privileges to one or more other realms in the system. Each realm in Red Hat build of Keycloak is represented by a client in the master realm. The name of the client is <realm name>-realm.

https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html/server_administration_guide/admin_permissions#realm_specific_roles

kcadm.sh add-roles \
  --uusername "${MASTER_REALM_PERMANENT_ADMIN_USERNAME}" \
  --cclientid "${CUSTOM_REALM_NAME}-realm" \
  --rolename create-client \
  --rolename impersonation \
  --rolename manage-authorization \
  --rolename manage-clients \
  --rolename manage-events \
  --rolename manage-identity-providers \
  --rolename manage-realm \
  --rolename manage-users \
  --rolename query-clients \
  --rolename query-groups \
  ${ADMIN_CLI_OPTIONS}
# server, bootstrap admin user credentials, realm master, truststore etc.
${ADMIN_CLI_OPTIONS}

What This Does

  • --cclientid <realm>-realm: Targets the client in the master realm that represents your custom realm.

  • --rolename: Any of the realm-management roles defined. Together they give full administrative capabilities.

Edit

Here is step 5 because it was asked for in the comments.

delete_bootstrap_admin_if_exists() {
    local bootstrap_user_id
    bootstrap_user_id=$({ kcadm.sh get users -r master -q exact=true -q username="$KC_BOOTSTRAP_USERNAME" $ADMIN_CLI_OPTIONS 2> >(tee -a "$LOGFILE" >&2); } | jq -r '.[0].id')
    # Defensive programming
    if [ -n "$bootstrap_user_id" ]; then
      { kcadm.sh delete users/"$bootstrap_user_id" -r master $ADMIN_CLI_OPTIONS; } 2>&1 | tee -a "$LOGFILE"
    fi
}
Dawid
  • 121