bitwarden/server · error · UnauthorizedAccessException
Unauthorized.
Error message
Unauthorized.
What it means
Thrown at SecretsTrashController.cs:51 inside ListByOrganizationAsync. After the SM-access check passed, the second guard requires OrganizationAdmin; if false the controller throws UnauthorizedAccessException, which ExceptionHandlerEndpointFilter maps to HTTP 401 with body "Unauthorized.". Trash listing is admin-only: an SM member who is not an org admin cannot enumerate trashed secrets.
Source
Thrown at src/Api/SecretsManager/Controllers/SecretsTrashController.cs:51
_currentContext = currentContext;
_secretRepository = secretRepository;
_emptyTrashCommand = emptyTrashCommand;
_restoreTrashCommand = restoreTrashCommand;
_userService = userService;
_eventService = eventService;
}
[HttpGet("secrets/{organizationId}/trash")]
public async Task<SecretWithProjectsListResponseModel> ListByOrganizationAsync(Guid organizationId)
{
if (!_currentContext.AccessSecretsManager(organizationId))
{
throw new NotFoundException();
}
if (!await _currentContext.OrganizationAdmin(organizationId))
{
throw new UnauthorizedAccessException();
}
var secrets = await _secretRepository.GetManyDetailsByOrganizationIdInTrashAsync(organizationId);
return new SecretWithProjectsListResponseModel(secrets);
}
[HttpPost("secrets/{organizationId}/trash/empty")]
public async Task EmptyTrashAsync(Guid organizationId, [FromBody] List<Guid> ids)
{
if (!_currentContext.AccessSecretsManager(organizationId))
{
throw new NotFoundException();
}
if (!await _currentContext.OrganizationAdmin(organizationId))
{
throw new UnauthorizedAccessException();
}View on GitHub (pinned to e93b962371)
Solutions
- Have an organization admin perform the trash listing.
- Promote the user to an admin role in the organization if trash access is required.
- Use an admin-scoped API token for automated trash queries.
Example fix
// before: SM user (non-admin) lists trash
await smUserClient.GetAsync($"/secrets/{orgId}/trash"); // 401
// after: admin identity lists trash
var adminClient = ClientFor(orgAdminCredential);
await adminClient.GetAsync($"/secrets/{orgId}/trash"); Defensive patterns
Strategy: validation
Validate before calling
if (!await IsOrganizationAdminAsync(orgId))
throw new UnauthorizedAccessException("Trash listing requires org admin");
await adminClient.GetAsync($"/secrets/{orgId}/trash"); Try / catch
try { await client.GetAsync($"/secrets/{orgId}/trash"); }
catch (ApiException ex) when (ex.StatusCode == HttpStatusCode.Unauthorized) { Log.Warn("Admin role required for trash"); } Prevention
- Restrict the trash view to org admins.
- Use an admin-scoped token for automated trash queries.
- Re-check admin role when roles change.
When it happens
Trigger: GET /secrets/{orgId}/trash by a user who has Secrets Manager access but is not an organization admin (e.g. a custom role or standard SM user).
Common situations: Non-admin SM user opening the trash view; service account or limited role attempting trash enumeration; admin rights removed after SM seat granted.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Resource not found.
- Resource not found.
- Resource not found.
- Resource not found.
- Last synced date must be in the past.
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/c060f383802830a0.
Report an issue: GitHub.