# Keycloak

> Administer a Keycloak realm. Create and update users, reset passwords, enable and disable accounts, manage groups and their members, create realm roles and assign them, check who is signed in, and list the applications registered in the realm.

App · Compliance & Security · 20 actions. Web page: https://docs.lodol.com/docs/integrations/keycloak

## Actions

### Add user to group

Put a user in a group, so they pick up whatever roles and attributes it carries. Adding someone who is already a member changes nothing and is not an error.

**Inputs**

- User ID (`user_id`, text, required): The user's Keycloak ID - the UUID in the admin console's address bar when the user is open, and the 'id' field of any List users result. Not the username, which can change.
- Group (`group_id`, text, required): The group to act on. Pick one, or paste a group ID from an earlier step - a group created by this workflow will not be in the list until it is refreshed.

**Outputs**

- `added` (true/false)
- `group_id` (text)
- `removed` (true/false)
- `resource` (text)
- `user_id` (text)

**Example output**

```json
{
  "added": true,
  "group_id": "1f3c0e2a-9b1d-4a5e-8c77-2b6d5f0a1c34",
  "resource": "group_membership",
  "user_id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"
}
```

### Assign realm role to user

Give a user a realm role. The role takes effect on their next token, so an already signed-in user picks it up when their session refreshes rather than instantly. Assigning a role the user already has changes nothing and is not an error.

**Inputs**

- User ID (`user_id`, text, required): The user's Keycloak ID - the UUID in the admin console's address bar when the user is open, and the 'id' field of any List users result. Not the username, which can change.
- Realm role (`role_name`, text, required): The realm role, by name. Pick one, or type a name - a role created by this workflow will not be in the list until it is refreshed.

**Outputs**

- `assigned` (true/false)
- `resource` (text)
- `role` (object)
- `user_id` (text)

**Example output**

```json
{
  "assigned": true,
  "resource": "realm_role_mapping",
  "role": {
    "clientRole": false,
    "composite": false,
    "containerId": "my-company",
    "description": "Can read the reporting dashboards",
    "id": "8a2c5f10-4d3b-4e91-9f0a-77c1b2e3d4f5",
    "name": "reporting-viewer"
  },
  "user_id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"
}
```

### Create group

Create a top-level group and return it, including the new group ID for later steps. Group names are unique among their siblings.

**Inputs**

- Name (`name`, text, required): The group's name.
- Description (`description`, text): What the group is for.

**Outputs**

- `access` (object)
- `attributes` (object)
- `clientRoles` (object)
- `description` (text)
- `id` (text)
- `name` (text)
- `parentId` (text)
- `path` (text)
- `realmRoles` (list)
- `subGroupCount` (number)
- `subGroups` (list)

**Example output**

```json
{
  "id": "1f3c0e2a-9b1d-4a5e-8c77-2b6d5f0a1c34",
  "name": "Engineering",
  "path": "/Engineering",
  "subGroupCount": 2
}
```

### Create realm role

Create a realm role and return it. Role names are unique in the realm and are how every other role step refers to them, so pick a name you can keep.

**Inputs**

- Name (`name`, text, required): The role's name, unique in the realm. This is the identifier applications check for.
- Description (`description`, text): What the role grants.

**Outputs**

- `attributes` (object)
- `clientRole` (true/false)
- `composite` (true/false)
- `containerId` (text)
- `description` (text)
- `id` (text)
- `name` (text)
- `scopeParamRequired` (true/false)

**Example output**

```json
{
  "clientRole": false,
  "composite": false,
  "containerId": "my-company",
  "description": "Can read the reporting dashboards",
  "id": "8a2c5f10-4d3b-4e91-9f0a-77c1b2e3d4f5",
  "name": "reporting-viewer"
}
```

### Create user

Create a user in the realm and return the created record, including the new user ID for later steps. The username must be unique in the realm, and so is the email address when the realm requires one. Set a password here to create the account ready to use; leave it empty to create one that cannot sign in until a password is set.

**Inputs**

- Username (`username`, text, required): The username, unique within the realm. Keycloak lowercases it unless the realm is set to be case sensitive.
- Email (`email`, text): The user's email address.
- First name (`first_name`, text): The user's first name.
- Last name (`last_name`, text): The user's last name.
- Enabled (`enabled`, true/false): Whether the account can sign in. Defaults to enabled. Default: `true`.
- Email verified (`email_verified`, true/false): Mark the email as already verified, so the user is not asked to confirm it. Defaults to unverified.
- Required actions (`required_actions`, list): What the user must do at their next sign-in. Each one has to be switched on for the realm under Authentication > Required actions; Keycloak accepts one that is off and then simply never asks for it. One or more of: `UPDATE_PASSWORD` (Update password), `VERIFY_EMAIL` (Verify email), `UPDATE_PROFILE` (Update profile), `CONFIGURE_TOTP` (Configure OTP), `UPDATE_EMAIL` (Update email), `TERMS_AND_CONDITIONS` (Accept terms and conditions), `CONFIGURE_RECOVERY_CODES` (Configure recovery codes), `webauthn-register` (Register a passkey (WebAuthn)), `webauthn-register-passwordless` (Register a passwordless passkey), `delete_account` (Delete account).
- Password (`password`, text): An initial password. Leave empty to create the account without one.
- Password is temporary (`temporary_password`, true/false): Make the user choose a new password at their first sign-in. Defaults to a permanent password.

**Outputs**

- `access` (object)
- `attributes` (object)
- `clientRoles` (object)
- `createdTimestamp` (number)
- `disableableCredentialTypes` (list)
- `email` (text)
- `emailVerified` (true/false)
- `enabled` (true/false)
- `federationLink` (text)
- `firstName` (text)
- `groups` (list)
- `id` (text)
- `lastName` (text)
- `notBefore` (number)
- `realmRoles` (list)
- `requiredActions` (list)
- `self` (text)
- `serviceAccountClientId` (text)
- `totp` (true/false)
- `username` (text)

**Example output**

```json
{
  "createdTimestamp": 1735689600000,
  "email": "ada@example.com",
  "emailVerified": true,
  "enabled": true,
  "firstName": "Ada",
  "id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
  "lastName": "Lovelace",
  "requiredActions": [],
  "username": "ada.lovelace"
}
```

### Delete group

Delete a group and its subgroups. The members keep their accounts and lose whatever the group granted them. This cannot be undone.

**Inputs**

- Group (`group_id`, text, required): The group to act on. Pick one, or paste a group ID from an earlier step - a group created by this workflow will not be in the list until it is refreshed.

**Outputs**

- `deleted` (true/false)
- `id` (text)
- `resource` (text)

**Example output**

```json
{
  "deleted": true,
  "id": "1f3c0e2a-9b1d-4a5e-8c77-2b6d5f0a1c34",
  "resource": "group"
}
```

### Delete realm role

Delete a realm role by name. Everyone who held it loses it immediately, and any composite role built on it loses that part. This cannot be undone.

**Inputs**

- Realm role (`role_name`, text, required): The realm role, by name. Pick one, or type a name - a role created by this workflow will not be in the list until it is refreshed.

**Outputs**

- `deleted` (true/false)
- `id` (text)
- `resource` (text)

**Example output**

```json
{
  "deleted": true,
  "id": "reporting-viewer",
  "resource": "realm_role"
}
```

### Delete user

Permanently delete a user, with their sessions, group memberships and role assignments. This cannot be undone - to block someone's access reversibly, use Update user to disable the account instead.

**Inputs**

- User ID (`user_id`, text, required): The user's Keycloak ID - the UUID in the admin console's address bar when the user is open, and the 'id' field of any List users result. Not the username, which can change.

**Outputs**

- `deleted` (true/false)
- `id` (text)
- `resource` (text)

**Example output**

```json
{
  "deleted": true,
  "id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
  "resource": "user"
}
```

### Get group

Read one group: its name, description, full path, parent and attributes.

**Inputs**

- Group (`group_id`, text, required): The group to act on. Pick one, or paste a group ID from an earlier step - a group created by this workflow will not be in the list until it is refreshed.

**Outputs**

- `access` (object)
- `attributes` (object)
- `clientRoles` (object)
- `description` (text)
- `id` (text)
- `name` (text)
- `parentId` (text)
- `path` (text)
- `realmRoles` (list)
- `subGroupCount` (number)
- `subGroups` (list)

**Example output**

```json
{
  "id": "1f3c0e2a-9b1d-4a5e-8c77-2b6d5f0a1c34",
  "name": "Engineering",
  "path": "/Engineering",
  "subGroupCount": 2
}
```

### Get user

Read one user in full by their Keycloak user ID: username, name, email and whether it is verified, whether the account is enabled, when it was created, and any required actions outstanding.

**Inputs**

- User ID (`user_id`, text, required): The user's Keycloak ID - the UUID in the admin console's address bar when the user is open, and the 'id' field of any List users result. Not the username, which can change.

**Outputs**

- `access` (object)
- `attributes` (object)
- `clientRoles` (object)
- `createdTimestamp` (number)
- `disableableCredentialTypes` (list)
- `email` (text)
- `emailVerified` (true/false)
- `enabled` (true/false)
- `federationLink` (text)
- `firstName` (text)
- `groups` (list)
- `id` (text)
- `lastName` (text)
- `notBefore` (number)
- `realmRoles` (list)
- `requiredActions` (list)
- `self` (text)
- `serviceAccountClientId` (text)
- `totp` (true/false)
- `username` (text)

**Example output**

```json
{
  "createdTimestamp": 1735689600000,
  "email": "ada@example.com",
  "emailVerified": true,
  "enabled": true,
  "firstName": "Ada",
  "id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
  "lastName": "Lovelace",
  "requiredActions": [],
  "username": "ada.lovelace"
}
```

### List clients

The applications registered in the realm, with each one's UUID, client ID, protocol, redirect URIs and which flows it allows. Search by part of a client ID, or turn off partial matching to look one up exactly.

**Inputs**

- Client ID (`client_id`, text): Only clients whose client ID matches. Leave empty for all of them.
- Match part of the client ID (`partial_match`, true/false): Treat the client ID above as text to search for rather than an exact name. Defaults to on, and does nothing unless a client ID is given. Default: `true`.
- Only clients I can view (`viewable_only`, true/false): Hide clients the service account has no view permission for, instead of listing them by ID alone.
- Skip (`offset`, number): How many results to skip before this page. Leave empty to start at the beginning. From 0 to 1000000. Default: `0`.
- Maximum results (`limit`, number): How many to return, 1-500. Defaults to 50. From 1 to 500. Default: `50`.

**Outputs**

- `count` (number): How many came back
- `has_more` (true/false): Whether another page probably follows
- `items` (list): The matching clients
- `limit` (number): The page size asked for
- `next_offset` (number): The offset to send for the next page, if any
- `offset` (number): How many were skipped

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "items": [
    {
      "clientId": "reporting-web",
      "enabled": true,
      "id": "c4d5e6f7-8a9b-4c0d-9e1f-2a3b4c5d6e7f",
      "name": "Reporting",
      "protocol": "openid-connect",
      "publicClient": true,
      "redirectUris": [
        "https://reporting.example.com/*"
      ],
      "standardFlowEnabled": true
    }
  ],
  "limit": 50,
  "next_offset": null,
  "offset": 0
}
```

### List group members

The users in a group. Members of its subgroups are not included - Keycloak treats each group's membership as its own.

**Inputs**

- Group (`group_id`, text, required): The group to act on. Pick one, or paste a group ID from an earlier step - a group created by this workflow will not be in the list until it is refreshed.
- Skip (`offset`, number): How many results to skip before this page. Leave empty to start at the beginning. From 0 to 1000000. Default: `0`.
- Maximum results (`limit`, number): How many to return, 1-500. Defaults to 50. From 1 to 500. Default: `50`.

**Outputs**

- `count` (number): How many came back
- `has_more` (true/false): Whether another page probably follows
- `items` (list): The users in the group
- `limit` (number): The page size asked for
- `next_offset` (number): The offset to send for the next page, if any
- `offset` (number): How many were skipped

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "items": [
    {
      "createdTimestamp": 1735689600000,
      "email": "ada@example.com",
      "emailVerified": true,
      "enabled": true,
      "firstName": "Ada",
      "id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
      "lastName": "Lovelace",
      "requiredActions": [],
      "username": "ada.lovelace"
    }
  ],
  "limit": 50,
  "next_offset": null,
  "offset": 0
}
```

### List groups

The realm's top-level groups, each with its path and how many subgroups it has. Search by name to find one anywhere in the tree.

**Inputs**

- Search (`search`, text): Only groups whose name matches this text. Leave empty for all of them.
- Exact match (`exact`, true/false): Match the search text exactly instead of as part of a name.
- Skip (`offset`, number): How many results to skip before this page. Leave empty to start at the beginning. From 0 to 1000000. Default: `0`.
- Maximum results (`limit`, number): How many to return, 1-500. Defaults to 50. From 1 to 500. Default: `50`.

**Outputs**

- `count` (number): How many came back
- `has_more` (true/false): Whether another page probably follows
- `items` (list): The matching groups
- `limit` (number): The page size asked for
- `next_offset` (number): The offset to send for the next page, if any
- `offset` (number): How many were skipped

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "items": [
    {
      "id": "1f3c0e2a-9b1d-4a5e-8c77-2b6d5f0a1c34",
      "name": "Engineering",
      "path": "/Engineering",
      "subGroupCount": 2
    }
  ],
  "limit": 50,
  "next_offset": null,
  "offset": 0
}
```

### List realm roles

The realm's own roles, with their descriptions and whether each is composite. Roles that belong to a client are listed under that client, not here.

**Inputs**

- Search (`search`, text): Only roles whose name or description matches this text. Leave empty for all of them.
- Skip (`offset`, number): How many results to skip before this page. Leave empty to start at the beginning. From 0 to 1000000. Default: `0`.
- Maximum results (`limit`, number): How many to return, 1-500. Defaults to 50. From 1 to 500. Default: `50`.

**Outputs**

- `count` (number): How many came back
- `has_more` (true/false): Whether another page probably follows
- `items` (list): The matching realm roles
- `limit` (number): The page size asked for
- `next_offset` (number): The offset to send for the next page, if any
- `offset` (number): How many were skipped

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "items": [
    {
      "clientRole": false,
      "composite": false,
      "containerId": "my-company",
      "description": "Can read the reporting dashboards",
      "id": "8a2c5f10-4d3b-4e91-9f0a-77c1b2e3d4f5",
      "name": "reporting-viewer"
    }
  ],
  "limit": 50,
  "next_offset": null,
  "offset": 0
}
```

### List user sessions

The user's active sessions: when each started, when it was last used, the IP address it came from and which applications it has reached. An empty list means the user is not signed in anywhere.

**Inputs**

- User ID (`user_id`, text, required): The user's Keycloak ID - the UUID in the admin console's address bar when the user is open, and the 'id' field of any List users result. Not the username, which can change.

**Outputs**

- `count` (number): How many came back
- `items` (list): The user's active sessions

**Example output**

```json
{
  "count": 1,
  "items": [
    {
      "clients": {
        "c4d5e6f7-8a9b-4c0d-9e1f-2a3b4c5d6e7f": "reporting-web"
      },
      "id": "3b9f1c7e-5d2a-4e8b-9c0f-1a2b3c4d5e6f",
      "ipAddress": "203.0.113.42",
      "lastAccess": 1735693200000,
      "rememberMe": false,
      "start": 1735689600000,
      "userId": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
      "username": "ada.lovelace"
    }
  ]
}
```

### List user's realm roles

The realm roles assigned directly to a user. Roles they hold only through a group, or through a composite role, are not listed here - Keycloak counts those as effective roles rather than as this user's own.

**Inputs**

- User ID (`user_id`, text, required): The user's Keycloak ID - the UUID in the admin console's address bar when the user is open, and the 'id' field of any List users result. Not the username, which can change.

**Outputs**

- `count` (number): How many came back
- `items` (list): The realm roles assigned directly to the user

**Example output**

```json
{
  "count": 1,
  "items": [
    {
      "clientRole": false,
      "composite": false,
      "containerId": "my-company",
      "description": "Can read the reporting dashboards",
      "id": "8a2c5f10-4d3b-4e91-9f0a-77c1b2e3d4f5",
      "name": "reporting-viewer"
    }
  ]
}
```

### List users

Find users in the realm. Search across username, first name, last name and email at once, or filter on any of them individually, and narrow to enabled or verified accounts. Returns each user's ID, username, name, email and status.

**Inputs**

- Search (`search`, text): Match this text against username, first name, last name and email at once. Leave empty for all users.
- Username (`username`, text): Only users with this username.
- Email (`email`, text): Only users with this email address.
- First name (`first_name`, text): Only users with this first name.
- Last name (`last_name`, text): Only users with this last name.
- Enabled (`enabled`, true/false): Only enabled users, or only disabled ones. Leave unset for both.
- Email verified (`email_verified`, true/false): Only users whose email is verified, or only those whose is not. Leave unset for both.
- Exact match (`exact`, true/false): Match the username, email and name filters exactly instead of as a prefix.
- Skip (`offset`, number): How many results to skip before this page. Leave empty to start at the beginning. From 0 to 1000000. Default: `0`.
- Maximum results (`limit`, number): How many to return, 1-500. Defaults to 50. From 1 to 500. Default: `50`.

**Outputs**

- `count` (number): How many came back
- `has_more` (true/false): Whether another page probably follows
- `items` (list): The matching users
- `limit` (number): The page size asked for
- `next_offset` (number): The offset to send for the next page, if any
- `offset` (number): How many were skipped

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "items": [
    {
      "createdTimestamp": 1735689600000,
      "email": "ada@example.com",
      "emailVerified": true,
      "enabled": true,
      "firstName": "Ada",
      "id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
      "lastName": "Lovelace",
      "requiredActions": [],
      "username": "ada.lovelace"
    }
  ],
  "limit": 50,
  "next_offset": null,
  "offset": 0
}
```

### Remove user from group

Take a user out of a group. Their account and everything else about it are untouched; they simply lose what the group granted.

**Inputs**

- User ID (`user_id`, text, required): The user's Keycloak ID - the UUID in the admin console's address bar when the user is open, and the 'id' field of any List users result. Not the username, which can change.
- Group (`group_id`, text, required): The group to act on. Pick one, or paste a group ID from an earlier step - a group created by this workflow will not be in the list until it is refreshed.

**Outputs**

- `added` (true/false)
- `group_id` (text)
- `removed` (true/false)
- `resource` (text)
- `user_id` (text)

**Example output**

```json
{
  "group_id": "1f3c0e2a-9b1d-4a5e-8c77-2b6d5f0a1c34",
  "removed": true,
  "resource": "group_membership",
  "user_id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"
}
```

### Reset user password

Set a user's password. By default the password is temporary, so Keycloak makes the user choose their own at the next sign-in - which is what an administrator setting a password usually wants. The password is never echoed back in the result.

**Inputs**

- User ID (`user_id`, text, required): The user's Keycloak ID - the UUID in the admin console's address bar when the user is open, and the 'id' field of any List users result. Not the username, which can change.
- Password (`password`, text, required): The new password.
- Temporary (`temporary`, true/false): Make the user choose a new password at their next sign-in. Defaults to on. Default: `true`.

**Outputs**

- `id` (text)
- `resource` (text)
- `temporary` (true/false)
- `updated` (true/false)

**Example output**

```json
{
  "id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
  "resource": "user_password",
  "temporary": true,
  "updated": true
}
```

### Update user

Change a user's details. Only the fields you fill in change - everything else is left exactly as it was. Use this to enable or disable an account, correct a name or email, or set what the user must do at their next sign-in.

**Inputs**

- User ID (`user_id`, text, required): The user's Keycloak ID - the UUID in the admin console's address bar when the user is open, and the 'id' field of any List users result. Not the username, which can change.
- Email (`email`, text): A new email address. Leave empty to keep it.
- First name (`first_name`, text): A new first name. Leave empty to keep it.
- Last name (`last_name`, text): A new last name. Leave empty to keep it.
- Enabled (`enabled`, true/false): Enable or disable the account. Disabling it signs the user out and refuses new sign-ins without deleting anything. Leave unset to keep it as it is.
- Email verified (`email_verified`, true/false): Mark the email verified or unverified. Leave unset to keep it as it is.
- Required actions (`required_actions`, list): What the user must do at their next sign-in. Each one has to be switched on for the realm under Authentication > Required actions; Keycloak accepts one that is off and then simply never asks for it. One or more of: `UPDATE_PASSWORD` (Update password), `VERIFY_EMAIL` (Verify email), `UPDATE_PROFILE` (Update profile), `CONFIGURE_TOTP` (Configure OTP), `UPDATE_EMAIL` (Update email), `TERMS_AND_CONDITIONS` (Accept terms and conditions), `CONFIGURE_RECOVERY_CODES` (Configure recovery codes), `webauthn-register` (Register a passkey (WebAuthn)), `webauthn-register-passwordless` (Register a passwordless passkey), `delete_account` (Delete account).

**Outputs**

- `access` (object)
- `attributes` (object)
- `clientRoles` (object)
- `createdTimestamp` (number)
- `disableableCredentialTypes` (list)
- `email` (text)
- `emailVerified` (true/false)
- `enabled` (true/false)
- `federationLink` (text)
- `firstName` (text)
- `groups` (list)
- `id` (text)
- `lastName` (text)
- `notBefore` (number)
- `realmRoles` (list)
- `requiredActions` (list)
- `self` (text)
- `serviceAccountClientId` (text)
- `totp` (true/false)
- `username` (text)

**Example output**

```json
{
  "createdTimestamp": 1735689600000,
  "email": "ada@example.com",
  "emailVerified": true,
  "enabled": true,
  "firstName": "Ada",
  "id": "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
  "lastName": "Lovelace",
  "requiredActions": [],
  "username": "ada.lovelace"
}
```
