bitwarden/server · error · BadRequestException

Passkeys cannot be created for your account. SSO login is re

Error message

Passkeys cannot be created for your account. SSO login is required.

What it means

BadRequestException 'Passkeys cannot be created for your account. SSO login is required.' is thrown in ValidateIfUserCanUsePasskeyLogin when the RequireSsoPolicyRequirement.CanUsePasskeyLogin flag is false for the user. This organization policy (Require Sso) disallows passkey creation for affected users.

Source

Thrown at src/Api/Auth/Controllers/WebAuthnController.cs:129

            throw new BadRequestException("The token associated with your request is expired. A valid token is required to continue.");
        }

        var credential = await _createWebAuthnLoginCredentialCommand.CreateWebAuthnLoginCredentialAsync(user, model.Name, tokenable.Options, model.DeviceResponse, model.SupportsPrf, model.EncryptedUserKey, model.EncryptedPublicKey, model.EncryptedPrivateKey);
        if (credential == null)
        {
            throw new BadRequestException("Unable to complete WebAuthn registration.");
        }

        return new WebAuthnCredentialResponseModel(credential);
    }

    private async Task ValidateIfUserCanUsePasskeyLogin(Guid userId)
    {
        var requireSsoPolicyRequirement = await _policyRequirementQuery.GetAsyncVNext<RequireSsoPolicyRequirement>(userId);

        if (!requireSsoPolicyRequirement.CanUsePasskeyLogin)
        {
            throw new BadRequestException("Passkeys cannot be created for your account. SSO login is required.");
        }
    }

    [Authorize(Policies.Application)]
    [HttpPut()]
    public async Task UpdateCredential([FromBody] WebAuthnLoginCredentialUpdateRequestModel model)
    {
        var tokenable = _assertionOptionsDataProtector.Unprotect(model.Token);
        if (!tokenable.TokenIsValid(WebAuthnLoginAssertionOptionsScope.UpdateKeySet) || tokenable.Options == null)
        {
            throw new BadRequestException("The token associated with your request is invalid or has expired. A valid token is required to continue.");
        }

        var (_, credential) = await _assertWebAuthnLoginCredentialCommand.AssertWebAuthnLoginCredential(tokenable.Options, model.DeviceResponse);
        if (credential == null || credential.SupportsPrf != true)
        {
            throw new BadRequestException("Unable to update credential.");
        }

View on GitHub (pinned to e93b962371)

Solutions

  1. Disable or exclude the user from the organization's Require Sso policy if passkey login is intended.
  2. Have the user authenticate via SSO instead of creating a passkey.
  3. Confirm with an org admin whether the policy is intended for this user.
  4. If the policy is wrong, the admin updates it and the user retries after policy refresh.

Example fix

// before: policy enforced, user tries passkey
api.post('/webauthn', { ... }) // 400
// after: org admin disables Require Sso
// admin: orgPolicyApi.put(orgId, { type: 'requireSso', enabled: false })
// user retries after policy sync
api.post('/webauthn', { ... });
Defensive patterns

Strategy: validation

Validate before calling

const req = await policyService.getRequireSsoRequirement(userId);
if (!req.canUsePasskeyLogin) throw new Error('SSO required; passkey creation blocked by policy');

Try / catch

try { await api.post('/webauthn', model); }
catch (e) {
  if (e.response?.status === 400 && /SSO login is required/.test(e.response.data?.message)) {
    throw new UserFacingError('Your organization requires SSO; passkeys are disabled. Contact an admin.');
  }
  throw e;
}

Prevention

When it happens

Trigger: POST /webauthn (passkey creation, line 129) by a user who is a member of an organization that enforces the Require Sso policy, which sets CanUsePasskeyLogin = false. The check runs before credential creation.

Common situations: Org admin enabled the 'Require Sso' policy, the user is now forced to log in via SSO and cannot create new passkeys, or the policy was applied org-wide and the user attempted a local passkey setup.

Related errors


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