passbolt/passbolt_api · error · UnauthorizedException
The duo authentication subscriber does not match the…
Error message
The duo authentication subscriber does not match the operator username.
What it means
Thrown by assertDuoAuthenticationSubscriber() when the security setting passbolt.security.mfa.duo.verifySubscriber is true and the Duo-authenticated subscriber differs from the passbolt operator username. This ensures the person who authenticated with Duo is the logged-in passbolt user.
Solutions
- Align the user's Duo username with their passbolt username, or vice versa.
- If divergent usernames are intentional policy-wise, set passbolt.security.mfa.duo.verifySubscriber to false in config (security trade-off).
- Check for case/whitespace differences in both systems' usernames.
- Confirm the user authenticated with their own Duo account, not a shared one.
Example fix
// before: config mismatched by design 'passbolt' => ['security' => ['mfa' => ['duo' => ['verifySubscriber' => true]]]] // after (if usernames legitimately differ) 'verifySubscriber' => false
Defensive patterns
Strategy: validation
Validate before calling
// pre-check alignment outside the flow
$matches = mb_strtolower($duoSubscriber) === mb_strtolower($operatorUsername);
if (!$matches && Configure::read('passbolt.security.mfa.duo.verifySubscriber')) {
// fail fast with a user-facing message
} Try / catch
try {
$service->verify($uac, $mfaToken, $duoCode);
} catch (UnauthorizedException $e) {
$this->logSecurityEvent('duo_subscriber_mismatch', $uac);
throw $e;
} Prevention
- Keep passbolt and Duo usernames aligned (use same email directory).
- Only enable verifySubscriber if username parity is guaranteed by provisioning.
- Sync user renames across passbolt and Duo.
When it happens
Trigger: Verifying a duo code when the Duo username differs from the passbolt username (case-insensitively) while verifySubscriber is enabled.
Common situations: User's Duo account uses a different email/username than passbolt; admin renamed a user in one system but not the other; company policy enables verifySubscriber but account names were never aligned.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The duo authentication origin endpoint does not match the…
- The token should reference an active Duo callback…
- Unable to authenticate to Duo.
- Unable to authenticate to Duo.
- Unable to verify Duo code against Duo service.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/e5027b516791bc34.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Service/Duo/MfaDuoVerifyDuoCodeService.php:143
throw new UnauthorizedException($msg);
}
}
/**
* Assert that the Duo subscriber who authenticated matches the user's username.
*
* @see https://duo.com/docs/oauthapi
* @param string $duoSubscriber Duo subscriber from callback
* @param string $operatorUsername Operator username
* @return void
* @throws \Cake\Http\Exception\UnauthorizedException if the duo authentication subscriber does not match the operator username
*/
private function assertDuoAuthenticationSubscriber(string $duoSubscriber, string $operatorUsername): void
{
$verifySubscriber = Configure::read(self::PASSBOLT_SECURITY_MFA_DUO_VERIFY_SUBSCRIBER);
if ($verifySubscriber === true && mb_strtolower($duoSubscriber) !== mb_strtolower($operatorUsername)) {
$msg = __('The duo authentication subscriber does not match the operator username.');
throw new UnauthorizedException($msg);
}
}
}
View on GitHub (pinned to 31c1bbc10f)