{"record":{"id":"e5027b516791bc34","repo":"passbolt/passbolt_api","slug":"the-duo-authentication-subscriber-does-not-match-the","errorCode":null,"errorMessage":"The duo authentication subscriber does not match the operator username.","messagePattern":"The duo authentication subscriber does not match the operator username\\.","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"plugins/PassboltCe/MultiFactorAuthentication/src/Service/Duo/MfaDuoVerifyDuoCodeService.php","lineNumber":143,"sourceCode":"            throw new UnauthorizedException($msg);\n        }\n    }\n\n    /**\n     * Assert that the Duo subscriber who authenticated matches the user's username.\n     *\n     * @see https://duo.com/docs/oauthapi\n     * @param string $duoSubscriber Duo subscriber from callback\n     * @param string $operatorUsername Operator username\n     * @return void\n     * @throws \\Cake\\Http\\Exception\\UnauthorizedException if the duo authentication subscriber does not match the operator username\n     */\n    private function assertDuoAuthenticationSubscriber(string $duoSubscriber, string $operatorUsername): void\n    {\n        $verifySubscriber = Configure::read(self::PASSBOLT_SECURITY_MFA_DUO_VERIFY_SUBSCRIBER);\n        if ($verifySubscriber === true && mb_strtolower($duoSubscriber) !== mb_strtolower($operatorUsername)) {\n            $msg = __('The duo authentication subscriber does not match the operator username.');\n            throw new UnauthorizedException($msg);\n        }\n    }\n}\n","sourceCodeStart":125,"sourceCodeEnd":147,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/MultiFactorAuthentication/src/Service/Duo/MfaDuoVerifyDuoCodeService.php#L125-L147","documentation":"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.","triggerScenarios":"Verifying a duo code when the Duo username differs from the passbolt username (case-insensitively) while verifySubscriber is enabled.","commonSituations":"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.","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."],"exampleFix":"// before: config mismatched by design\n'passbolt' => ['security' => ['mfa' => ['duo' => ['verifySubscriber' => true]]]]\n// after (if usernames legitimately differ)\n'verifySubscriber' => false","handlingStrategy":"validation","validationCode":"// pre-check alignment outside the flow\n$matches = mb_strtolower($duoSubscriber) === mb_strtolower($operatorUsername);\nif (!$matches && Configure::read('passbolt.security.mfa.duo.verifySubscriber')) {\n    // fail fast with a user-facing message\n}","typeGuard":null,"tryCatchPattern":"try {\n    $service->verify($uac, $mfaToken, $duoCode);\n} catch (UnauthorizedException $e) {\n    $this->logSecurityEvent('duo_subscriber_mismatch', $uac);\n    throw $e;\n}","preventionTips":["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."],"tags":["mfa","duo","authentication","identity-mismatch"],"backgroundTag":"permission-denied","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}