TOTP with Keycloak, AWS Cognito, and Okta: an operator's guide
How to configure TOTP in Keycloak, AWS Cognito, Okta, and Salesforce: the policy knobs that matter, the enrollment gotchas, and what a stolen seed database means.

Somewhere right now a developer is implementing TOTP from scratch for a login page that sits behind an identity provider that already ships it. The ticket said "add 2FA," nobody checked what the IAM server could do, and in six weeks there's a bespoke verification endpoint with a look-ahead window nobody has thought about. If your users log in through Keycloak, AWS Cognito, Okta, or Salesforce, that code already exists, maintained by people who've survived the edge cases you're about to discover. What's left is real work, though: which knobs exist, what they trade away, and where each platform hides its sharp edges.
We've covered what TOTP is and how the shared-secret machinery works, and there's a from-first-principles implementation guide if you genuinely need to write the code. This is the operator's complement: you're not implementing the math, you're configuring somebody else's implementation. Different skill, different mistakes, same standard.
The case for letting the identity provider do it
TOTP is 150 lines of arithmetic any competent developer can write in an afternoon, and almost none of the hard parts are arithmetic: they're enrollment (getting a secret onto a phone without leaking it), drift, recovery, and admin tooling — and a mature identity provider answers all four. But the IdP doesn't make the decisions disappear. Every platform's MFA settings are knobs encoding security trade-offs, tuned for ecosystem compatibility rather than your threat model. Knowing the factor landscape helps you decide whether TOTP is the right second factor at all; this post is about the how — and about the questions that turn out identical across all four.
Keycloak's OTP policy
Keycloak is the open-source identity server with Red Hat lineage — Red Hat's commercial SSO product is built on it, and the FreeOTP authenticator is its sibling. If you're running your own auth stack, it's probably already in the room; TOTP ships in every realm.
Getting users onto it is either a required action or a flow decision: the Configure OTP action walks each user through enrollment at next login, while authentication flows put an OTP form step into the browser flow, required for everyone or gated on conditions — "mandatory MFA for the finance group, optional for everyone else" without a second realm.
The heart of it is the OTP policy. The knobs: hash algorithm (SHA-1/256/512), digits (6 through 8), token period, look-ahead window, and the initial counter if you've chosen HOTP. Each is a trade-off dressed as a dropdown.
The look-ahead window says how many future time steps the server accepts codes from. The default tolerates modest clock skew; widen it and users with badly-set phones stop filing tickets — but every extra step is another window in which a previously valid code still verifies. It's the knob operators silently break: the cost is invisible until it's an incident report, and RFC 6238 is strict about one-time use for a reason.
SHA-256, SHA-512, and eight digits sound like free upgrades. They aren't: the authenticator ecosystem converged on SHA-1, six digits, thirty seconds, and plenty of apps handle deviations badly. If the Keycloak TOTP policy deviates, test enrollment against several apps before committing.
Keycloak also does WebAuthn as a second factor — security keys registered per user, verified by the same flows. For employees with laptops they control, that's stronger than TOTP, and it removes the shared secret from your database entirely. (The project docs track the console layout, which changes between versions.)
AWS Cognito
Cognito user pools are AWS's managed identity service, and the MFA menu is short: TOTP software token, SMS, or both. The pool-level setting comes first — MFA required, optional, or off — and when it's required, you pick which factors are allowed. (The Cognito docs rename things occasionally; the model is stable.)
Cognito TOTP enrollment is a two-step dance, and the step teams skip is the second: the user associates a software token — the pool issues a secret, your app shows it as a QR code — then verifies by submitting a live code. Only after verification does the token count. If your flow ends at "show the QR code," you'll find out when a user loses their phone and support has nothing finished to reset.
The classic AWS Cognito MFA gotchas are both SMS-shaped: texts cost money per message, need a verified phone number, plus region-dependent origination setup — and NIST guidance deprecated SMS as a second factor years ago because of SIM-swap attacks. Take the hint: TOTP as the primary factor, SMS only where users genuinely can't do better, and a plan to sunset it.
Okta
Okta organizes second factors around a factor catalog. Okta Verify is the first-party app — push approvals and TOTP codes in one place. Third-party authenticators hang off the factor historically labeled Google Authenticator — despite the name, it means "any RFC 6238 app": FreeOTP, Aegis, and friends enroll fine. Then there's FIDO2/WebAuthn — security keys and platform authenticators.
The admin machinery is where Okta earns its invoice: authentication policies require a possession factor per app, per group, per network. "MFA always for the VPN app, only off-network for the wiki" is a policy rule, not a code change. Duo sells the same taxonomy with a different logo; the concepts transfer.
The direction of travel matters, though: Okta, like everyone, is pushing phishing-resistant factors, because an Okta TOTP code can be relayed by a convincing fake login page in real time and a push can be fatigue-attacked at 2 a.m. The endgame is WebAuthn; TOTP remains the pragmatic baseline — every phone, works offline — but treat it as the floor, not the ceiling. (Okta's developer docs and the admin-console docs are separate universes.)
Salesforce
Salesforce keeps it simple: Salesforce Authenticator (TOTP with push approvals layered on), standard authenticator apps, and security keys. The notable part of the Salesforce 2FA story: Salesforce made MFA mandatory for direct logins to its products, phased in from 2022 onward, and the enforcement dates shifted more than once during the rollout. Check Salesforce's current documentation for your org rather than any third-party summary with a year in it.
The parts every provider shares
Configure all four and the differences look cosmetic: the underlying concerns are identical, and they're worth briefing your security team on.
Seed storage. TOTP secrets are shared secrets: the server needs the exact key the phone holds, so the IdP's database holds a working key for every user. Unlike password hashes, they can't be one-way — the server needs them to verify codes — so they're encrypted at rest, and the service holds the keys. A compromise is quiet: no alarms, just an attacker generating valid codes for everyone until every seed is rotated. When you evaluate a provider, ask what protects the seed store: HSMs, per-tenant keys, access logging. The honest answer to expect: "encrypted, monitored, and a very bad day if it walks out."
Enrollment binding. Every platform above has a verify-before-enable step: the user proves a working code before the factor goes live. Don't bypass it — a user marked MFA-enabled with an unverified enrollment is locked out at next login, and the remedy is a ticket. The implementation guide explains why this catches mistyped secrets and drifted clocks early; the operator's version is: leave the step on.
Recovery. Admin resets and backup codes are where your MFA strength gets spent. All four platforms have both, and none will stop you from building a recovery flow that quietly undoes the second factor — a helpdesk process with weaker identity proofing than the login it bypasses. Keep recovery rate-limited, logged, and reviewed.
Clock skew. The look-ahead window is the server-side answer to phones that drift. Pick a modest window, keep servers on NTP, and when codes fail everywhere, suspect clocks first.
When you should still build it yourself
Almost never. The defensible reasons: nothing sits in front of the login page (an embedded device, a CLI tool), a requirement that you own the code, or you're building an IdP yourself. If one of those is you, the implementation guide walks the whole pipeline from scratch. Everyone else: configure the IdP, and spend the saved weeks on the recovery flow, which is where the actual incidents live.
One habit worth keeping either way: when you're testing an enrollment flow, paste the issued secret into our guest generator and compare codes — two independent implementations agreeing on the same six digits in the same second is the fastest smoke test that your policy and your users' apps speak the same dialect. It runs entirely in the browser; no account, no network requests, nothing stored.
Frequently asked questions
Does Keycloak support TOTP two-factor authentication?
Yes, built into every realm. You enable it as the Configure OTP required action or through authentication flows, users enroll by scanning a QR code, and the OTP policy controls algorithm, digits, period, and look-ahead window. It also supports HOTP and WebAuthn security keys. The console changes between versions more than the concepts do.
Is TOTP better than SMS for AWS Cognito MFA?
For almost everyone, yes. TOTP costs nothing per authentication, works offline, and isn't exposed to SIM-swap attacks. SMS carries per-message costs, requires verified phone numbers, and is deprecated in NIST guidance as a second factor. Cognito supports both; treat SMS as a legacy compatibility option, not a default.
Can I use Google Authenticator with Okta?
Yes. Okta's third-party TOTP factor — historically labeled "Google Authenticator" in the admin console — accepts any standards-compliant RFC 6238 app, so Google Authenticator, FreeOTP, and Aegis all enroll fine. The name is a relic from when one app was the whole ecosystem, not a restriction.
Does Salesforce require MFA?
Salesforce has required MFA for direct logins to its products, phased in from 2022 onward. The timeline shifted several times during the rollout and the details vary by product and contract, so check Salesforce's own documentation rather than any third-party summary with a date in it.
What happens if an identity provider's TOTP secrets are stolen?
The attacker can generate valid codes for every affected user until the seeds are rotated, because each TOTP secret is shared between the server and that user's phone. Providers encrypt seed stores at rest, but the decryption capability has to live with the verification service. A serious incident means forced re-enrollment for everyone affected — which is why seed-store protection and rotation are fair questions to ask any vendor.