`ORG_USER_MANAGER` should allow managing user credentials/MFA factors, or provide a least-privilege role for this
Preflight Checklist
- I could not find a solution in the existing issues, docs, nor discussions
- I have joined the ZITADEL chat
Describe your problem
We are using service accounts to call the ZITADEL API and are trying to follow a least-privilege model.
For service accounts that should only manage users within an organization, we assign the built-in ORG_USER_MANAGER role. According to the administrator role description, this role is intended to “Manage users and their authorizations within an organization.”
However, we found that a service account with ORG_USER_MANAGER cannot add some user authentication factors / credentials. For example, calling the User v2 AddOTPSMS endpoint fails with 403 PermissionDenied.
The same operation works when the service account has ORG_OWNER.
There is also an inconsistency in behavior:
ORG_USER_MANAGERcan remove OTP SMS from a user.ORG_USER_MANAGERcannot add OTP SMS to a user.
Current behavior
A service account with ORG_USER_MANAGER receives a 403 when calling:
POST /v2/users/{user_id}/otp_smsExample API:
zitadel.user.v2.UserService.AddOTPSMSBut the same service account can remove OTP SMS from the user:
DELETE /v2/users/{user_id}/otp_smsExample API:
zitadel.user.v2.UserService.RemoveOTPSMSExpected behavior
A service account with ORG_USER_MANAGER should be able to manage the user’s authentication factors / credentials that are part of user administration, including adding OTP SMS, OTP Email, passkeys, or other credential/MFA-related methods where appropriate.
At minimum, the role should include the credential-management permissions required for this use case, such as:
user.credential.write
user.passkey.writeAlternatively, if adding these permissions to ORG_USER_MANAGER is considered too broad, ZITADEL should provide a dedicated least-privilege built-in role for managing user credentials / MFA factors without requiring ORG_OWNER.
Why this matters
For automated user-management integrations, using ORG_OWNER is too broad. A service account that only needs to manage users and their authentication factors should not need full organization ownership privileges.
This makes it difficult to implement least privilege for user lifecycle automation, especially when MFA enrollment or credential setup is part of the user-management process.
Technical findings
From the default role mappings, ORG_OWNER includes credential-related permissions such as:
user.credential.write
user.passkey.writeBut ORG_USER_MANAGER does not include those permissions.
This explains why the service account can update users generally, but cannot add credentials / MFA factors.
There also appears to be an implementation-level difference between adding and removing OTP SMS:
- Adding OTP SMS calls the credential update permission check:
checkPermissionUpdateUserCredentials(...)- Removing OTP SMS calls the regular user update permission check:
checkPermissionUpdateUser(...)This explains why ORG_USER_MANAGER can remove OTP SMS but cannot add OTP SMS.
Additional note
If this behavior is intentional, it would be helpful to document it more explicitly in the administrator permission matrix and in the affected API reference pages, especially for endpoints such as AddOTPSMS, AddOTPEmail, passkey registration, and similar credential/MFA-management operations.
Describe your ideal solution
Please update the default ORG_USER_MANAGER role to include the credential-management permissions required to manage user credentials / authentication factors, for example:
- "user.credential.write"
- "user.passkey.write"Or introduce a separate built-in role such as ORG_USER_CREDENTIAL_MANAGER / ORG_USER_MFA_MANAGER that allows managing user credentials and MFA factors without granting full ORG_OWNER.
Version
4.15.0
Environment
ZITADEL Cloud
Additional Context
No response
Source: zitadel/zitadel