bitwarden/server · error · UnauthorizedAccessException
Unauthorized.
Error message
Unauthorized.
What it means
Thrown as UnauthorizedAccessException by ValidateOrganizationAccessAsync, the shared guard for OrganizationDomainController endpoints (Get/GetAll/Post/Verify/RemoveDomain). It fires when _currentContext.ManageSso(orgIdGuid) returns false — the authenticated user lacks the Manage SSO permission for that organization. This is the first check; the org-existence check (NotFoundException) only runs after this passes. Maps to HTTP 401.
Source
Thrown at src/Api/AdminConsole/Controllers/OrganizationDomainController.cs:145
[AllowAnonymous]
[HttpPost("domain/sso/verified")]
public async Task<VerifiedOrganizationDomainSsoDetailsResponseModel> GetVerifiedOrgDomainSsoDetailsAsync(
[FromBody] OrganizationDomainSsoDetailsRequestModel model)
{
var ssoResults = (await _organizationDomainRepository
.GetVerifiedOrganizationDomainSsoDetailsAsync(model.Email))
.ToList();
return new VerifiedOrganizationDomainSsoDetailsResponseModel(
ssoResults.Select(ssoResult => new VerifiedOrganizationDomainSsoDetailResponseModel(ssoResult)));
}
private async Task ValidateOrganizationAccessAsync(Guid orgIdGuid)
{
if (!await _currentContext.ManageSso(orgIdGuid))
{
throw new UnauthorizedAccessException();
}
var organization = await _organizationRepository.GetByIdAsync(orgIdGuid);
if (organization == null)
{
throw new NotFoundException();
}
}
}
View on GitHub (pinned to e93b962371)
Solutions
- Ensure the calling user has the Manage SSO permission for the target organization (typically an Owner / SSO admin role).
- Re-authenticate after a permission change so the token carries updated claims.
- Use an API key / service account explicitly granted ManageSso for the org.
- Confirm orgId in the route matches an organization the caller can administer.
Defensive patterns
Strategy: validation
Validate before calling
// Confirm Manage SSO before any organization-domain call
if (!await currentUser.CanManageSsoAsync(orgId))
throw new UnauthorizedAccessException("Caller lacks Manage SSO for this organization."); Prevention
- Gate all organization-domain calls behind a ManageSso check resolved from trusted context.
- Re-authenticate after permission changes so claims refresh.
- Confirm orgId matches an org the caller can administer.
- Use an API key explicitly granted Manage SSO.
When it happens
Trigger: Any organization-domain endpoint (GET/POST/DELETE /organizations/{orgId}/domain/...) called by a user without the ManageSso claim for that org; calling as a non-admin member; calling with a token scoped to a different org.
Common situations: A standard org member (not an SSO admin/owner) trying to manage custom domains; an API token without the SSO scope; a user whose ManageSso was revoked but who still holds a valid session token; cross-tenant request with the wrong orgId.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Not authorized.
- An organization the user is a part of has enabled Automatic
- Invalid permissions.
- OrganizationUserAccessRevoked
- Unauthorized.
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/f4da2c650fb2f3b0.
Report an issue: GitHub.