docs/keycloak/enforce-otp-internal.md

100 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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**: `12`
- **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 dont 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.