docs/keycloak/enforce-otp-internal.md

4.1 KiB

Enforce OTP (TOTP) 2FA for Internal Users in Keycloak

Goal: Enforce OTP-based two-factor authentication (2FA) for internal users managed inside Keycloak in the Digitalboard realm, while external users coming from Microsoft Entra ID as Identity Provider are not prompted for OTP.


Prerequisites

  • Admin access to the Keycloak Admin Console for the Digitalboard realm.
  • A running Keycloak instance (TLS termination handled by Traefik or Keycloak itself).
  • Microsoft Entra ID already set up as an Identity Provider for the realm.
  • Internal users stored directly in Keycloak (username/password authentication).

Steps

Step 1 — Verify External Identity Provider

  1. In the Digitalboard realm, open the Admin Console.
  2. Navigate to Identity Providers.
  3. Confirm that Microsoft Entra ID is configured (OpenID Connect or SAML).
  4. Ensure that external users sign in via this IdP.

Step 2 — Configure OTP Policy

  1. In the left-hand menu of the Digitalboard realm, go to Authentication → OTP Policy (or Realm Settings → Security Defenses → OTP Policy, depending on Keycloak version).
  2. Configure the following:
    • Type: totp (time based)
    • Digits: 6
    • Period: 30 seconds
    • Algorithm: sha512
    • Look ahead window: 1-2
    • Reusable token: off

Click Save.


Step 3 — Copy the Browser Flow

  1. Navigate to Authentication → Flows.
  2. Locate the built-in Browser flow.
  3. Click Copy.
  4. Enter the new name: browser-internal-otp.

This custom flow will handle internal (local) user logins for the Digitalboard realm.


Step 4 — Add OTP Requirement

  1. Open the browser-internal-otp flow.
  2. Inside the Browser Forms sub-flow, locate the Username Password Form.
  3. After it, click Add execution → select OTP Form (or Conditional OTP if available).
  4. Set requirement to Required.

This ensures OTP is enforced for all username/password logins (internal users).


Step 5 — Enable “Configure OTP” Required Action

  1. In the Digitalboard realm, go to Authentication → Required Actions.
  2. Locate Configure OTP.
  3. Ensure the status is Enabled.

With this enabled, internal users without an OTP configured will be prompted to set it up during login.


Step 6 — Bind the Flow

  1. In the Digitalboard realm, go to Authentication → Flows.
  2. Click the flow browser-internal-otp to open it.
  3. In the top-right, open Actions → Bind flow.
  4. In the dialog, choose Browser flow and click Save.

This makes browser-internal-otp the default Browser flow, so internal (local) users who log in with username/password must use OTP.

Important for external (Entra) users:

  • Go to Identity Providers → (Microsoft Entra) and ensure Post Login Flow / Post Broker Login Flow is None (or a flow without OTP), so external users don't get a Keycloak OTP prompt after IdP login.

Step 7 — Test the Setup

  1. Log in with an internal Keycloak user in the Digitalboard realm:
    • After entering username and password, you should be prompted for OTP (or OTP setup if not already configured).
  2. Log in with an external Microsoft Entra user:
    • You should be redirected to Entra ID for login.
    • After successful login, you should be signed in without an additional OTP prompt from Keycloak.

Troubleshooting

  • External users see OTP prompt: Check that Post Broker Login Flow is not set to browser-internal-otp.
  • Internal users not asked for OTP: Verify that the OTP Form is present in browser-internal-otp and set to Required.
  • Looping on OTP setup: Ensure realm time synchronization (NTP) and correct OTP policy values.

Next Steps

  • Roll out OTP to internal users gradually (pilot group).
  • Provide instructions for enrolling an authenticator app (Google Authenticator, Microsoft Authenticator, FreeOTP).
  • Monitor login events in the Digitalboard realm to confirm expected OTP usage.