Skip to main content
Version: Next

Service Users

A service user is a machine identity for an integration, an agent, an MCP client or a pipeline. It is a Pimcore user of type serviceuser (a Pimcore\Model\User whose isServiceUser() is true) and is authorized like a user: permissions, roles, workspaces, class and document type restrictions and MCP server Access apply to it. It differs from a human user:

  • It is never an administrator, has no usable password (the core stores an unusable random value) and no two-factor authentication.
  • It cannot log in to Studio, and password recovery does not reach it.
  • It is not part of the user tree or the user collection. Names are unique across users and service users.

Managing service users​

The endpoints require the users permission and are documented in the OpenAPI specification under "Service User Management".

Method and pathPurpose
GET /pimcore-studio/api/service-usersList service users
GET /pimcore-studio/api/service-user/{id}Get one service user
POST /pimcore-studio/api/service-userCreate a service user and its OAuth client
POST /pimcore-studio/api/service-user/from-user/{id}Create a service user from a user
PUT /pimcore-studio/api/service-user/{id}Update contact email, permissions, roles, restrictions and workspaces
POST /pimcore-studio/api/service-user/{id}/deactivateDeactivate a service user
DELETE /pimcore-studio/api/service-user/{id}Delete a service user
POST /pimcore-studio/api/service-user/{id}/rotate-secretRotate the client secret
POST /pimcore-studio/api/service-user/{id}/mcp-tokenIssue an MCP access token
DELETE /pimcore-studio/api/service-user/{id}/mcp-tokenRevoke all MCP access tokens

Creating a service user also registers its confidential OAuth client (see Service-user clients). The response contains the client id and the client secret. The secret is shown only in that response; only its hash is stored. Rotate the secret to get a new one; the previous secret stops working at once. Access tokens already issued with the old secret stay valid until they expire, at most client_credentials.access_token_ttl seconds.

Creating a service user from a user copies the user's permissions, roles, class and document type restrictions, translation language restrictions and workspaces. The user is not changed and admin rights are never copied. Only an administrator may create a service user from an administrator.

The update endpoint accepts only email, permissions, roles, classes, docTypes and the three workspace lists. Any other key, such as name, password, admin, active or a misspelled field, is refused with 422, whatever its value, so nothing is silently ignored. The name stays fixed because MCP server access is granted by name; a service user is deactivated through its deactivate endpoint.

MCP access tokens​

Until OAuth Client Credentials is enabled (pimcore_studio_backend.oauth.client_credentials.enabled), a service user authenticates at the MCP endpoints with an MCP access token. Static personal access tokens (pimcore_studio_backend.mcp.authentication.tokens) are deprecated and are not used for service users.

A token lives 1 to 90 days (default 30). It is shown once; only its hash is stored. Issue one through the API or on the command line:

# issue a token valid for 30 days for service user 42
bin/console studio-backend-bundle:service-user:mcp-token 42 --ttl-days=30

# revoke every MCP access token of service user 42
bin/console studio-backend-bundle:service-user:mcp-token 42 --revoke

Store the token in a secret store and send it as Authorization: Bearer <token>. To let the service user use an MCP server, grant its name Access in the server's sharing settings.

Which credential to use​

Use the OAuth client (client id and secret, client_credentials grant) for pipelines and integrations that can perform the grant, and only once pimcore_studio_backend.oauth.client_credentials.enabled is on. Use an MCP access token for everything else, such as MCP clients that take a bearer token. The service-user schema reports which one works: clientCredentialsEnabled is false while the grant is off (the client secret then authenticates nothing), and mcpTokens summarises the tokens as active (tokens that have not expired) and latestExpiresAt (the latest expiry among them, null without one). Neither the tokens nor their hashes are ever returned.

While the grant is off, the clientSecret in the create and rotate responses is null, so no unusable secret reaches the browser. The OAuth client is still registered on create, and rotating the secret while the grant is off still invalidates the old secret, but the new one is withheld; turn the grant on and rotate again to get a usable secret.

Deactivation and deletion​

  • Deactivating a service user stops new client-credentials tokens from being issued, and refuses its OAuth and MCP access tokens from the next request on.
  • Deleting a service user deletes its OAuth client, revokes its OAuth tokens (by jti) and MCP access tokens, and removes its entries from the access lists of all MCP servers stored in a writeable location. This happens whichever way the service user is deleted, so a later user or service user with the same name inherits nothing. An MCP server shipped in read-only configuration cannot be changed; a warning is logged, and the entry has to be removed from that configuration by hand.