bitwarden/server · error · BadRequestException

You do not have permission to update this connection.

Error message

You do not have permission to update this connection.

What it means

Thrown by UpdateConnection (PUT /organizations/connections/{id}) when HasPermissionAsync returns false against the existing connection's OrganizationId and Type. Crucially, the permission check uses the persisted connection's type (existingOrganizationConnection.Type), not the request body's type, so the claim must match what is stored. Scim requires ManageScim; the default branch requires OrganizationOwner. Maps to HTTP 400.

Source

Thrown at src/Api/AdminConsole/Controllers/OrganizationConnectionsController.cs:94

    }

    [HttpPut("{organizationConnectionId}")]
    public async Task<OrganizationConnectionResponseModel> UpdateConnection(Guid organizationConnectionId, [FromBody] OrganizationConnectionRequestModel model)
    {
        if (model == null)
        {
            throw new NotFoundException();
        }

        var existingOrganizationConnection = await _organizationConnectionRepository.GetByIdOrganizationIdAsync(organizationConnectionId, model.OrganizationId);
        if (existingOrganizationConnection == null)
        {
            throw new NotFoundException();
        }

        if (!await HasPermissionAsync(existingOrganizationConnection.OrganizationId, existingOrganizationConnection.Type))
        {
            throw new BadRequestException("You do not have permission to update this connection.");
        }

        if (model.Type != existingOrganizationConnection.Type)
        {
            throw new BadRequestException("The connection type cannot be changed.");
        }

        if (await HasConnectionTypeAsync(model, organizationConnectionId, model.Type))
        {
            throw new BadRequestException($"The requested organization already has a connection of type {model.Type}. Only one of each connection type may exist per organization.");
        }

        switch (model.Type)
        {
            case OrganizationConnectionType.CloudBillingSync:
                return await CreateOrUpdateOrganizationConnectionAsync<BillingSyncConfig>(organizationConnectionId, model, ValidateBillingSyncConfig);
            case OrganizationConnectionType.Scim:
                return await CreateOrUpdateOrganizationConnectionAsync<ScimConfig>(organizationConnectionId, model);

View on GitHub (pinned to e93b962371)

Solutions

  1. Ensure the calling user holds the permission matching the stored connection type (Owner for CloudBillingSync, ManageScim for Scim).
  2. If the user's role changed, have them re-authenticate so the refreshed token carries the updated claims.
  3. Use an account/API key explicitly granted the needed organization-scoped permission.
  4. Confirm the connection being edited belongs to an organization the caller is a member of.
Defensive patterns

Strategy: validation

Validate before calling

// Permission is checked against the STORED type, not the body
var existing = await GetConnectionAsync(connectionId);
var neededOwner = existing.Type != OrganizationConnectionType.Scim;
var ok = neededOwner
    ? await currentUser.IsOrganizationOwnerAsync(existing.OrganizationId)
    : await currentUser.CanManageScimAsync(existing.OrganizationId);
if (!ok) throw new UnauthorizedAccessException();

Prevention

When it happens

Trigger: PUT on a connection the caller lacks rights to: a non-owner editing a CloudBillingSync connection; a user without ManageScim editing a Scim connection; calling as a member of a different organization than the one that owns the connection.

Common situations: A demoted former owner still holds a cached id and tries to edit; a custom-scoped API token missing the specific claim for the connection's type; an admin who can read the list but lacks the elevated permission to write.

Related errors


AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13). Data as JSON: /api/errors/8fbaa598f58ff838. Report an issue: GitHub.