Skip to content

Two-Factor authentication (TOTP)#3712

Merged
nabokihms merged 5 commits into
dexidp:masterfrom
deckhouse:totp
Mar 18, 2026
Merged

Two-Factor authentication (TOTP)#3712
nabokihms merged 5 commits into
dexidp:masterfrom
deckhouse:totp

Conversation

@nabokihms
Copy link
Copy Markdown
Member

@nabokihms nabokihms commented Aug 26, 2024

Overview

This pull request implements multi-factor authentication (MFA) support in Dex with an extensible architecture designed for future authenticator types (WebAuthn, etc.).

MFA secrets are stored in UserIdentity objects. Authenticators are defined globally and referenced by clients via mfaChain. A server-wide defaultMFAChain applies to clients without explicit configuration. Authenticators can be scoped to specific connector types (e.g., LDAP, local) to avoid redundancy with providers that have built-in MFA.

Upon first login, users enroll by scanning a QR code; subsequent logins require a TOTP code. The feature requires the DEX_SESSIONS_ENABLED=true feature flag.

Example configuration:

mfa:
  authenticators:
  - id: totp-1
    type: TOTP
    config:
      issuer: "dex"
    connectorTypes:
    - ldap
    - mockCallback
  defaultMFAChain:
  - totp-1

Per-client override:

staticClients:
- id: my-app
  mfaChain:    # overrides defaultMFAChain; use [] to explicitly disable
  - totp-1

What this PR does / why we need it

Enhancing Dex with 2FA adds an additional layer of security, making unauthorized access significantly more difficult. This is particularly valuable for connectors like LDAP and local connectors that do not inherently support 2FA. By implementing 2FA, we align Dex with industry best practices for identity management, meet higher security compliance requirements, and ensure better protection for user data, thereby building greater trust with our users.

Special notes for your reviewer

image

image

@nabokihms nabokihms added the release-note/new-feature Release note: Exciting New Features label Aug 26, 2024
@nabokihms
Copy link
Copy Markdown
Member Author

closes #352

@nabokihms
Copy link
Copy Markdown
Member Author

closes #1547

@nabokihms
Copy link
Copy Markdown
Member Author

closes #1270

@cnd4
Copy link
Copy Markdown

cnd4 commented Dec 3, 2024

I'm not a maintainer nor a reviewer so I'm not sure this is the best place to ask this, but would it be possible to display the "textual" code below the QR code?

This is useful when you can't scan the QR code, for example when your TOTP application is directly on your computer.

(Edit: typo)

@lanord
Copy link
Copy Markdown

lanord commented Dec 11, 2024

Do we know if we are going to see this merge in the near future ? This would be a great feature to see deployed. As more and more security requirement ask for 2FA on auth provider.

@nabokihms
Copy link
Copy Markdown
Member Author

@sambonbonne good addition, thanks!
@lanord I am willing to merge it this year after figuring out some API nuances.

@Kludex
Copy link
Copy Markdown

Kludex commented Jan 28, 2025

@nabokihms Is there a way to fund the work in this PR?

@shaohme
Copy link
Copy Markdown

shaohme commented Apr 9, 2025

Nice feature to have indeed.

Have you considered supporting slapo-otp(5) when you started the project?

@p-alexander
Copy link
Copy Markdown

p-alexander commented Oct 4, 2025

Hi, is TOTP still planned for this year? My team would like to use this amazing feature with local connectors. 🙏

A small update: I've taken a look at the PR and noticed that totp.Generate is always called with an empty secret option and generally it is good to have it randomized, but for simpler use cases (e.g. in-memory storage), it might be worth supporting a static secret in order to keep offlineSessions.TOTP idempotent between restarts. Kind of similar to how static passwords are already handled in Dex.

@braginini
Copy link
Copy Markdown

Would love to see this one merged as we are planning to integrate Dex in NetBird.

@jjzazuet
Copy link
Copy Markdown

Super cool feature right here. Any chances of merging? Thanks!

@nabokihms
Copy link
Copy Markdown
Member Author

For all waiting the feature. We are working now on the proposal, which will make this PR be merged in the future.

You can see the progress here #4560

Comment thread server/handlers.go
Comment thread server/mfa.go
Comment thread server/mfa.go
Comment thread server/mfa.go
Comment thread t Outdated
Copy link
Copy Markdown
Member

@sagikazarmark sagikazarmark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had some comments, but it probably needs a closer look to see if they are valid, hence just comments.

Comment thread server/mfa.go Outdated
Comment thread server/server.go Outdated
Comment thread server/mfa.go Outdated
<p>Enter the code from your authenticator app.</p>
<p class="theme-heading">{{ .Issuer }}</p>
{{ end }}
<form method="post" action="{{ .PostURL }}">
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we don't do that in other places, but this is a security sensitive form that would probably benefit from CSRF.

Copy link
Copy Markdown
Member Author

@nabokihms nabokihms Mar 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a kind of CSRF protection using HMAC. It's generated server-side with a secret key and validated on submission, so a forged request from an external origin would fail verification. Same principle as a synchronizer token, just delivered via the URL rather than a hidden form field.

We use it all over critical forms. I can open an issue to add a different CSRF mechanism, but not in the scope of this PR.

Comment thread storage/storage.go
Comment thread server/mfa.go
Comment thread server/mfa.go
Comment thread server/mfa.go
Comment thread server/mfa.go Outdated
Comment thread server/mfa.go Outdated
Comment thread server/mfa.go Outdated
Comment thread cmd/dex/serve.go
Comment thread server/templates.go
@nabokihms nabokihms requested a review from AlwxSin March 18, 2026 10:31
Signed-off-by: maksim.nabokikh <max.nabokih@gmail.com>
Signed-off-by: maksim.nabokikh <max.nabokih@gmail.com>
Signed-off-by: maksim.nabokikh <max.nabokih@gmail.com>
Signed-off-by: maksim.nabokikh <max.nabokih@gmail.com>
Signed-off-by: maksim.nabokikh <max.nabokih@gmail.com>
@nabokihms
Copy link
Copy Markdown
Member Author

No API to recover mfa and no recovery codes for now, but I still think it is ok to be merged now. We will add the API later.

@nabokihms nabokihms merged commit 86abd33 into dexidp:master Mar 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note/new-feature Release note: Exciting New Features

Projects

None yet

Development

Successfully merging this pull request may close these issues.