- m_user_mfa_factor is now the single 2FA gate. DSC enroll callback writes a factor row (factor_type=DSC), revoke flips disabled_on when the last cert goes. AuthenticationApiResource and TwoFactorAuthenticationFilter drop the direct m_bank_user_dsc check so disabling from the UI actually stops the challenge at login. - SecurityConfig exempts /api/*/dsc/** and /api/*/mfa/factors from the TWOFACTOR_AUTHENTICATED gate. Without this a user with a verified factor can't manage their own factors after they break the device. - MfaFactorType gains a DSC enum value; SelfUserMfaFactorServiceImpl error message lists it. - dsc-helper: CBSnexora-branded header (logo, title, subtitle, accent palette), 8-column cert table (Holder Name, Alias, Organisation, DSC Type, Serial, Issuer, Valid From, Expires), LdapName-based DN parsing, sign+verify proof- of-possession that picks SHA256withRSA / SHA256withECDSA from the key's own algorithm (works on RSA, RSA Signing-only, EC), pattern-matched JNLP age check, dscType JNLP-arg override with KeyUsage fallback. - generate-test-dsc.ps1 produces a realistic self-signed DSC with strong key protection so dev testing sees real CN/O values and a PIN prompt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>