Skip to content

feat: pass totpSecretKeyUri to the totp template#50122

Open
whawker wants to merge 1 commit into
keycloak:mainfrom
whawker:feat/pass-otpauth-uri-to-ftl
Open

feat: pass totpSecretKeyUri to the totp template#50122
whawker wants to merge 1 commit into
keycloak:mainfrom
whawker:feat/pass-otpauth-uri-to-ftl

Conversation

@whawker

@whawker whawker commented Jun 18, 2026

Copy link
Copy Markdown

Exposes the otpauth:// key URI (the same URI that is already encoded into the TOTP QR code) directly to the login-config-totp template via a new totp.totpSecretKeyUri attribute.

Why

During a setup TOTP flow, if you're already using your mobile device, you can't scan the QR code on your screen. If we instead offer the URI as a clickable link it will open in their chosen authenticator application, asking if the user wants to add the secret key.

This change surfaces that existing URI so custom themes can render it (e.g. as a tappable link on mobile), without having to reconstruct it client-side from the secret, issuer, algorithm, digits and period.

Security considerations

The key URI contains the shared TOTP secret in plaintext — but this exposes nothing new: the same secret is already present on the same page, in the QR image (which is the encoded URI) and in the existing ${totp.totpSecret} hidden form field sent to the same client. No additional data leaves the server.

AI usage disclosure

Parts of this contribution (the TotpUtils/TotpBean accompanying tests) were created with the assistance of an AI coding agent.

@whawker whawker requested a review from a team as a code owner June 18, 2026 12:46
Copilot AI review requested due to automatic review settings June 18, 2026 12:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR exposes the canonical otpauth:// TOTP key URI to the login-config-totp FreeMarker model as totp.totpSecretKeyUri, so themes can render it (e.g., as a deep link on mobile) without reconstructing the URI client-side.

Changes:

  • Added TotpUtils.keyUri(...) to build and reuse the same key URI that is embedded in the QR code.
  • Added totpSecretKeyUri to TotpBean (new getter for template access).
  • Added unit tests covering issuer fallback behavior and bean exposure of the key URI.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
services/src/main/java/org/keycloak/utils/TotpUtils.java Introduces keyUri(...) and reuses it from qrCode(...) to centralize key-URI construction.
services/src/main/java/org/keycloak/forms/login/freemarker/model/TotpBean.java Exposes totpSecretKeyUri on the FreeMarker model so templates can access the otpauth:// URI directly.
services/src/test/java/org/keycloak/utils/TotpUtilsTest.java Adds tests for issuer selection/fallback behavior in TotpUtils.keyUri(...).
services/src/test/java/org/keycloak/forms/login/freemarker/model/TotpBeanTest.java Adds tests verifying the bean exposes the correct key URI and its expected components.

Comment thread services/src/main/java/org/keycloak/utils/TotpUtils.java
Copilot AI review requested due to automatic review settings June 18, 2026 12:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment on lines 75 to +77
this.totpSecretEncoded = TotpUtils.encode(totpSecret);
this.totpSecretQrCode = TotpUtils.qrCode(session, totpSecret, realm, user);
this.totpSecretKeyUri = TotpUtils.keyUri(session, totpSecret, realm, user);
Signed-off-by: Will Hawker <whawker@users.noreply.github.com>
@whawker whawker force-pushed the feat/pass-otpauth-uri-to-ftl branch from 6936121 to 75e8fff Compare June 18, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants