keycloakkeycloak-rest-api

How can I create a service account in the master realm with the same admin capabilities as the admin user in Keycloak 26.2.5


I have created a client (ntrcpt_service) and selected "Service account roles". I have added the "admin" role to the client's service account roles. I am able to authenticate with the ntrcpt_service client. I am able to programmatically create a new realm (acme.com) via the api. When I subsequently get the new acme realm via the keycloak rest api (in the same session) using the ntrcpt_service client, I get a 200 but the response contains very limited realm information and when I try to update the acme realm with a put I get a 403. Using the exact same code, but authenticating with a user account (ntrcpt_admin) that has the same roles assigned as the service account, everything works as expected, i.e., I get the full response from a get and the put succeeds. I would appreciate any help you can provide in getting my service account working.

Here's the service account client:

"clientId": "ntrcpt_service",
  "name": "",
  "description": "",
  "rootUrl": "",
  "adminUrl": "",
  "baseUrl": "",
  "surrogateAuthRequired": false,
  "enabled": true,
  "alwaysDisplayInConsole": false,
  "clientAuthenticatorType": "client-secret",
  "secret": "**********************",
  "redirectUris": [],
  "webOrigins": [],
  "notBefore": 0,
  "bearerOnly": false,
  "consentRequired": false,
  "standardFlowEnabled": false,
  "implicitFlowEnabled": false,
  "directAccessGrantsEnabled": false,
  "serviceAccountsEnabled": true,
  "publicClient": false,
  "frontchannelLogout": false,
  "protocol": "openid-connect",
  "attributes": {
    "realm_client": "false",
    "ntrcpt.created_at": "2025-05-29 15:10:11.151074 UTC",
    "oidc.ciba.grant.enabled": "false",
    "backchannel.logout.session.required": "true",
    "standard.token.exchange.enabled": "false",
    "ntrcpt.schema_version": "0",
    "ntrcpt.updated_at": "2025-05-29 15:10:11.194012 UTC",
    "ntrcpt.tenant_id": "e832ad64-e561-464f-84a2-7b7d68768f11",
    "oauth2.device.authorization.grant.enabled": "false",
    "display.on.consent.screen": "false",
    "ntrcpt.sub": "1527d088-f6cd-48e5-acbd-7ec2df6fa5d9",
    "backchannel.logout.revoke.offline.tokens": "false"
  },
  "authenticationFlowBindingOverrides": {},
  "fullScopeAllowed": true,
  "nodeReRegistrationTimeout": -1,
  "defaultClientScopes": [
    "service_account",
    "web-origins",
    "acr",
    "roles",
    "profile",
    "client_uuid",
    "basic",
    "email"
  ],
  "optionalClientScopes": [
    "address",
    "phone",
    "organization",
    "offline_access",
    "microprofile-jwt"
  ],
  "access": {
    "view": true,
    "configure": true,
    "manage": true
  }
}

...and here's a screenshot of the service account user roles showing the acme.com realm roles: service account roles

Here's the details from the put request as requested:

URL: http://localhost:8080/admin/realms/test_21498
Method: PUT
Status: 403 Forbidden
Request Headers Size: 5899 B
Request Body Size: 244 B
Response Headers Size: 199 B
Response Body Size: 30 B
Timestamp: 2025-05-29T16:50:26.339Z

Content-Type: application/json
Authorization:  
Bearer ***************
Accept: */*
Host: localhost:8080
Content-Length: 244
Body:
{
  "realm": "test_21498",
  "enabled": true
}

Response: 
---------
Content-Length: 30
Connection: close
Content-Type: application/json
Referrer-Policy: no-referrer
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Body: 
{
  "error": "HTTP 403 Forbidden"
}

Solution

  • You need to assign "Assign roles to ntrcpt_service" with test_21498-realm manage-realm

    To update realm, you should be create test_21498 first.

    enter image description here

    if create test_21498 realm, can you test_21498-realm client in master realm enter image description here

    Let start to assign role for ntrcpt_service client

    enter image description here

    And Press a Assign button

    enter image description here

    Now Ready to update realm by REST API

    Get Client Token

    Note: replace client_secret with your client_secret

    CLIENT_TOKEN=$(curl --location --request POST 'http://localhost:8080/realms/master/protocol/openid-connect/token' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'grant_type=client_credentials' \
    --data-urlencode 'scope=openid' \
    --data-urlencode 'client_id=ntrcpt_service' \
    --data-urlencode 'client_secret=g36WP5Iis5usNPju4xEkRyHzVa3TGhSo' | jq -r '.access_token')
    echo $CLIENT_TOKEN
    

    Update realm

    curl --location --request PUT 'http://localhost:8080/admin/realms/test_21498' \
    --header 'Authorization: Bearer '$CLIENT_TOKEN \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "realm": "test_21498",
      "enabled": true
    }'
    

    Result

    No Error (no more 403 Forbidden)

    enter image description here

    Postman

    URL

    http://localhost:8080/realms/master/protocol/openid-connect/token
    

    enter image description here

    In script of Post response

    let jsonData = pm.response.json();
    
    pm.environment.set("token", jsonData.access_token);
    

    enter image description here

    Result

    No error too.

    Raw of Body Input

    {
      "realm": "test_21498",
      "enabled": true
    }
    

    enter image description here

    enter image description here