Custom role email visibility differs between UI and API
### Summary
When a **custom admin role** is configured with permissions that allow viewing user email addresses, the **GitLab UI** exposes those email addresses, but the **API** does not return them for the same user and role. This results in inconsistent behavior between UI and API for the same permission set.
This prevents administrators from building automations that rely on user email data while using least privilege custom roles.
---
### Use case
A self-managed customer wants to:
* Use **SMTP (external mail infrastructure)** instead of GitLab’s built-in mail delivery.
* Retrieve **user email addresses via the API** to drive outbound communication and automation.
* Avoid granting full admin privileges by using a **custom admin role** with the minimal required permissions (for example, “view all users”).
With this role:
* The administrator can see user email addresses in the **GitLab UI**.
* The same administrator **cannot** retrieve those email addresses through the API when authenticated with their personal access token.
This forces the customer either to:
* Use a **full admin account** and broader access than necessary, or
* Build unreliable workarounds that rely only on public profile fields (which may not be set).
---
### Steps to reproduce
1. On a self managed instance, enable and configure **custom roles**.
2. Create a **custom admin role** (or group level custom role, depending on implementation) that includes permission(s) equivalent to **“view all users”**.
3. Assign this role to a non-owner user (call this user **AdminUser**).
4. As **AdminUser**, sign in to the GitLab UI and:
* Navigate to **Admin \> Users** (or the relevant user listing surface).
* Confirm that **email addresses** for other users are visible in the UI.
5. As **AdminUser**, create a **personal access token** with the appropriate scopes for user / admin level APIs (for example, `read_api` or stronger, as required by current implementation).
6. Use that token to call a users related API endpoint, for example:
* `GET /api/v4/users`
* `GET /api/v4/users/:id`
7. Inspect the response for the same users whose email addresses were visible in the UI.
---
### Expected behavior
* If a custom role grants permissions that allow **viewing user email addresses** in the UI, then:
* The same role, when used via a **personal access token**, should grant access to **equivalent email fields** via the API.
* UI and API behavior should be **consistent** for the same permission set.
In other words, permission checks for viewing user emails should be aligned between UI and API.
---
### Actual behavior
* **UI**:
* AdminUser with the custom role can view other users’ email addresses in the administrative views.
* **API**:
* When calling the users API endpoints with AdminUser’s personal access token, the response does **not** include the same email information that is visible in the UI.
* From the customer’s perspective, the API appears to ignore the custom role’s “view all users” capability for email data.
---
### Impact
* Customers who want to:
* Use external email infrastructure,
* Rely on GitLab as the **source of truth** for user identities, and
* Follow **least privilege** principles with custom roles,
are unable to implement a robust solution.
* They must either:
* Escalate to **full admin** access for automation accounts, which broadens the blast radius, or
* Fall back to partial or manually maintained data sources.
This is especially problematic for:
* Large organizations that rely on **automated synchronization** between GitLab and other systems.
* Environments where **auditability** and strict separation of duties are required.
---
### Environment details
* GitLab: self managed Ultimate (customer example)
* GitLab version: 18.7.1 (customer example from Support ticket)
* Installation type: Helm chart (customer example)
The issue is described from Support observations and customer reports, so exact version ranges may be broader than the example above.
---
### Additional notes
* Related Support ticket: internal Zendesk ticket `702252` (GitLab Support).
* This issue is about **consistency of permission checks** between UI and API for custom roles, not about exposing new data to roles that cannot already see that data.
* A resolution that ensures consistent behavior would allow customers to:
* Keep using custom admin roles with “view all users” style permissions.
* Reliably consume user email data via the API using least privilege automation accounts.
---
### Possible direction
* Ensure that the same permission logic used by the UI to determine whether a user may view email addresses is also applied in the API layer when deciding which email fields to expose for a user with a custom role.
* Document clearly which email related fields are expected to be available via the API for users with these permissions, so customers can design automations against a stable contract.
issue