Download the PHP package sandstorm/keycloak-admin-api without Composer
On this page you can find all versions of the php package sandstorm/keycloak-admin-api. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download sandstorm/keycloak-admin-api
More information about sandstorm/keycloak-admin-api
Files in sandstorm/keycloak-admin-api
Package keycloak-admin-api
Short Description Framework-agnostic PHP client for the Keycloak Admin REST API (users, groups, credentials, sessions, events), returning immutable typed DTOs and collections.
License MIT
Informations about the package keycloak-admin-api
sandstorm/keycloak-admin-api
A framework-agnostic PHP client for the Keycloak Admin REST API (target: Keycloak 26.5 or newer).
The whole package is work in progress, and is extended as needed.
Thanks to BroodfondsMakers for sponsoring the development of this package, and for agreeing to Open Source it!
It exposes the admin API in modern PHP, using immutable typed DTOs and collections. It has no framework coupling.
- sandstorm/keycloak-admin-api
- Requirements
- Usage
- Keycloak REST API coverage
- #21 - Users (paths under
/admin/realms/{realm}) - #11 - Groups (paths under
/admin/realms/{realm}) - #8 - Clients (paths under
/admin/realms/{realm}) - #16 - Realms Admin (paths under
/admin/realms) - Development Ideas
- Package layout (feature-first)
- Unit and Integration Tests
- License
Requirements
- PHP 8.3+
- A PSR-18 HTTP client, like Guzzle
Usage
Also on KeycloakUsersApi:
findByUsername(string): ?KeycloakUser- exact identity lookup (exact=true), full representation; more than one match is refused, never silently picked from.create(CreateKeycloakUserCommand): KeycloakUser-POST /users(attributes, credentials, required actions), returned read back through the API.KeycloakUser::withCredentials()+update()- replace all stored credentials of an existing user.
Keycloak REST API coverage
This is based on the Keycloak Admin REST API: The vast majority is not implemented, because so far this is focused upon user-administration.
Legend: โ implemented ยท ๐ก partial ยท โ not implemented (candidate)
| # | KC resource group | Status | What we cover / our slice |
|---|---|---|---|
| 1 | Attack Detection | โ | brute-force status/clear - none |
| 2 | Authentication Management | โ | realm auth-flow config |
| 3 | Client Attribute Certificate | โ | client keystores |
| 4 | Client Initial Access | โ | dynamic client registration tokens |
| 5 | Client Registration Policy | โ | - |
| 6 | Client Role Mappings | โ | a user's client-role grants - candidate |
| 7 | Client Scopes | โ | - |
| 8 | Clients | ๐ก | GET /clients (KeycloakClientsApi::list); client CRUD - โ |
| 9 | Component | โ | user-federation / key providers |
| 10 | default (realm root) | โ | GET/PUT /admin/realms/{realm} - planned KeycloakRealmApi |
| 11 | Groups | ๐ก | GET /groups (KeycloakGroupsApi::listRealmGroups); group CRUD, /groups/{id}/members, children - โ |
| 12 | Identity Providers | โ | - |
| 13 | Key | โ | realm keys |
| 14 | Organizations | โ | - |
| 15 | Protocol Mappers | โ | - |
| 16 | Realms Admin | ๐ก | GET /events, GET /admin-events (KeycloakEventsApi); realm config + /health - โ (planned KeycloakRealmApi) |
| 17 | Role Mapper | โ | a user's realm-role grants - candidate |
| 18 | Roles | โ | realm/client role definitions |
| 19 | Roles (by ID) | โ | - |
| 20 | Scope Mappings | โ | - |
| 21 | Users | ๐ก | read + update + user-profile schema + credentials + sessions + membership (see detail below); create/delete/reset-password and many sub-resources - โ |
| 22 | Workflows | โ | - |
| - | OIDC token endpoint | โ | POST /realms/{realm}/protocol/openid-connect/token - ServiceAccountTokenProvider |
21 - Users (paths under /admin/realms/{realm})
| Method & path | Status | Notes |
|---|---|---|
GET /users |
โ | KeycloakUsersApi::list (infix search), ::findByUsername (exact=true) |
POST /users |
โ | KeycloakUsersApi::create (read back by exact username) |
GET /users/count |
โ | KeycloakUsersApi::count |
GET /users/profile |
โ | KeycloakRealmApi::getUserProfile (attribute schema + per-role perms) |
PUT /users/profile |
โ | user-profile schema authoring |
GET /users/profile/metadata |
โ | user-profile metadata (drives proactive form rendering) |
GET /users/{user-id} |
โ | KeycloakUsersApi::getById |
PUT /users/{user-id} |
โ | KeycloakUsersApi::update (lossless read-modify-write; also writes replacement credentials) |
DELETE /users/{user-id} |
โ | user deletion |
GET /users/{user-id}/configured-user-storage-credential-types |
โ | - |
GET /users/{user-id}/consents |
โ | - |
DELETE /users/{user-id}/consents/{client} |
โ | - |
GET /users/{user-id}/credentials |
โ | KeycloakCredentialsApi::get |
DELETE /users/{user-id}/credentials/{credentialId} |
โ | KeycloakCredentialsApi::delete |
POST /users/{user-id}/credentials/{credentialId}/moveAfter/{newPreviousCredentialId} |
โ | reorder credential |
POST /users/{user-id}/credentials/{credentialId}/moveToFirst |
โ | reorder credential |
PUT /users/{user-id}/credentials/{credentialId}/userLabel |
โ | rename credential |
PUT /users/{user-id}/disable-credential-types |
โ | - |
PUT /users/{user-id}/execute-actions-email |
โ | KeycloakCredentialsApi::executeActionsEmail (array body) |
GET /users/{user-id}/federated-identity |
โ | - |
POST /users/{user-id}/federated-identity/{provider} |
โ | - |
DELETE /users/{user-id}/federated-identity/{provider} |
โ | - |
GET /users/{user-id}/groups |
โ | KeycloakGroupsApi::getUserGroups |
GET /users/{user-id}/groups/count |
โ | - |
PUT /users/{user-id}/groups/{groupId} |
โ | KeycloakGroupsApi::addUserToGroup (body-less) |
DELETE /users/{user-id}/groups/{groupId} |
โ | KeycloakGroupsApi::removeUserFromGroup |
POST /users/{user-id}/impersonation |
โ | deliberately not supported: it plants an SSO cookie in the browser (so a server-side call is useless), and it backchannel-logs-out the caller's own session when caller and target share a realm. |
POST /users/{user-id}/logout |
โ | KeycloakSessionsApi::logoutAll |
GET /users/{user-id}/offline-sessions/{clientUuid} |
โ | - |
PUT /users/{user-id}/reset-password |
โ | not needed: KeycloakUser::withCredentials() + update covers the admin-set / pre-hashed case; execute-actions-email preferred |
PUT /users/{user-id}/reset-password-email |
โ | deprecated alias of execute-actions-email |
PUT /users/{user-id}/send-verify-email |
โ | |
GET /users/{user-id}/sessions |
โ | KeycloakSessionsApi::getSessions |
GET /users/{user-id}/unmanagedAttributes |
โ | - |
11 - Groups (paths under /admin/realms/{realm})
| Method & path | Status | Notes |
|---|---|---|
GET /groups |
โ | KeycloakGroupsApi::listRealmGroups |
POST /groups |
โ | group CRUD |
GET /groups/count |
โ | - |
GET /groups/{group-id} |
โ | single group |
PUT /groups/{group-id} |
โ | group CRUD |
DELETE /groups/{group-id} |
โ | group CRUD |
GET /groups/{group-id}/children |
โ | sub-group listing |
POST /groups/{group-id}/children |
โ | sub-group create |
GET /groups/{group-id}/members |
โ | list users in a group (group-filter data source) |
GET /groups/{group-id}/management/permissions |
โ | FGAP admin permissions |
PUT /groups/{group-id}/management/permissions |
โ | FGAP admin permissions |
8 - Clients (paths under /admin/realms/{realm})
| Method & path | Status | Notes |
|---|---|---|
GET /clients |
โ | KeycloakClientsApi::list โ the realm's applications; KeycloakClients::browserLoginable() filters to the browser-loginable ones, KeycloakClient::resolvedUrl() yields an openable URL (rootUrl/baseUrl join, ${authBaseUrl}/${authAdminUrl} substitution, redirect-URI origin fallback) |
GET /clients/{id} |
โ | single client |
POST /clients |
โ | client CRUD |
PUT /clients/{id} |
โ | client CRUD |
DELETE /clients/{id} |
โ | client CRUD |
16 - Realms Admin (paths under /admin/realms)
| Method & path | Status | Notes |
|---|---|---|
GET / |
โ | list realms |
POST / |
โ | create realm |
GET /{realm} |
โ | realm config (editUsernameAllowed, events flags) - planned KeycloakRealmApi |
PUT /{realm} |
โ | realm config authoring |
DELETE /{realm} |
โ | delete realm |
GET /{realm}/admin-events |
โ | KeycloakEventsApi::getAdminEventsForUser |
DELETE /{realm}/admin-events |
โ | clear admin events |
POST /{realm}/client-description-converter |
โ | - |
GET /{realm}/client-policies/policies |
โ | - |
PUT /{realm}/client-policies/policies |
โ | - |
GET /{realm}/client-policies/profiles |
โ | - |
PUT /{realm}/client-policies/profiles |
โ | - |
GET /{realm}/client-session-stats |
โ | - |
GET /{realm}/client-types |
โ | - |
PUT /{realm}/client-types |
โ | - |
GET /{realm}/credential-registrators |
โ | - |
GET /{realm}/default-default-client-scopes |
โ | - |
PUT /{realm}/default-default-client-scopes/{clientScopeId} |
โ | - |
DELETE /{realm}/default-default-client-scopes/{clientScopeId} |
โ | - |
GET /{realm}/default-groups |
โ | - |
PUT /{realm}/default-groups/{groupId} |
โ | - |
DELETE /{realm}/default-groups/{groupId} |
โ | - |
GET /{realm}/default-optional-client-scopes |
โ | - |
PUT /{realm}/default-optional-client-scopes/{clientScopeId} |
โ | - |
DELETE /{realm}/default-optional-client-scopes/{clientScopeId} |
โ | - |
GET /{realm}/events |
โ | KeycloakEventsApi::getUserEvents |
DELETE /{realm}/events |
โ | clear login events |
GET /{realm}/events/config |
โ | events flags |
PUT /{realm}/events/config |
โ | events config authoring |
GET /{realm}/group-by-path/{path} |
โ | candidate |
GET /{realm}/localization |
โ | realm i18n |
GET /{realm}/localization/{locale} |
โ | realm i18n |
POST /{realm}/localization/{locale} |
โ | realm i18n |
DELETE /{realm}/localization/{locale} |
โ | realm i18n |
GET /{realm}/localization/{locale}/{key} |
โ | realm i18n |
PUT /{realm}/localization/{locale}/{key} |
โ | realm i18n |
DELETE /{realm}/localization/{locale}/{key} |
โ | realm i18n |
POST /{realm}/logout-all |
โ | |
POST /{realm}/partial-export |
โ | - |
POST /{realm}/partialImport |
โ | - |
POST /{realm}/push-revocation |
โ | - |
DELETE /{realm}/sessions/{session} |
โ | |
POST /{realm}/testSMTPConnection |
โ | realm SMTP config |
GET /{realm}/users-management-permissions |
โ | FGAP admin permissions |
PUT /{realm}/users-management-permissions |
โ | FGAP admin permissions |
Development Ideas
Package layout (feature-first)
Each feature keeps its interface, implementation, and DTOs together. Interfaces carry the Keycloak
prefix so an imported symbol is self-describing inside a larger host codebase.
Unit and Integration Tests
Two tiers:
- Unit (
tests/Unit) - fast, hermetic. Real logic only (DTO/collection parsing tolerance, token cache, array-body encoding, query building, the non-2xx โUnexpectedKeycloakResponseException(withstatusCode) mapping) driven through a PSR-18 mock. - Integration / E2E (
tests/Integration) - runs the client against a real Keycloak 26.5.3 in Docker (tests/Integration/docker-compose.ymlimports two self-contained realms). This proves the wire contract unit tests cannot. The write suite (KeycloakUserWritesE2ETest) creates uniquely named users and proves a written credential by really logging in with it, so it is re-runnable against a long-lived instance.
Log into the Keycloak admin console at http://localhost:9911 with admin / admin. Seeded users all
have password changeit.
Two realms are imported so the wire contract is proven in both authorization modes โ classic
realm-management roles and Fine-Grained Admin Permissions (FGAP). The FGAP realm drives the
caller-relative access map (KeycloakUser::$access) and per-caller write authorisation: a user bearer is
obtained via the public e2e-login direct-grant client (tests/Support/DirectGrantTokenProvider), so calls run
as that user and Keycloak evaluates that user's own grants.
| Realm | Admin Permissions (FGAP) | Notable seeded users / caller identity |
|---|---|---|
test-realm |
off (classic roles) | service account (admin-api, realm-management roles), login-user (none), jane in /staff |
test-realm-fgap |
on | admin-user (roles), login-user (none), sarah + jane in /staff, emma in /endusers |
FGAP staff policy (baked into realm-import-fgap.json)
Staff read everyone, edit endusers, can't touch other staff:
License
MIT
All versions of keycloak-admin-api with dependencies
ext-json Version *
psr/http-client Version ^1.0
psr/http-factory Version ^1.0
psr/http-message Version ^1.1 || ^2.0