Prerequisites

Install OpenJDK 21

sudo apt update
sudo apt install openjdk-21-jdk -y
java -version
Download and Setup Keycloak

Create Admin Account (Remotely or Non-Interactively):

Set the environment variables to bootstrap the admin user:

export KC_BOOTSTRAP_ADMIN_USERNAME=<username>
export KC_BOOTSTRAP_ADMIN_PASSWORD=<password>

Start Keycloak in Development Mode:
Inside the /keycloak-26.2.4/bin directory, run:

./kc.sh start-dev
Keycloak will start in development mode, and the admin account will be available at:
http://<your-vm-ip>:8080

Keycloak Configuration

Create Realm

  • Open Keycloak Admin Console: http://<your-vm-ip>:8080
  • Login with the admin credentials
  • Click Realm Selector → Create Realm
  • Enter the realm name (e.g., myrealm)
  • Click Create

Create Client

  • Go to Clients → Create Client
  • Fill in the following:
    • Client ID: my_client
    • Client Name: ${my_client}
  • Click Next
  • Leave Capabilities as default
  • Click Next
  • Under Login settings:
    • Valid Redirect URIs: http://localhost:5173/*
    • Web Origins: http://localhost:5173
  • Click Save

Create Role

  • Navigate to Roles
  • Click Create Role
  • Role Name: admin or user (as needed)
  • Click Create

Create User

  • Go to Users → Add User
  • Username: manager1
  • (Optional) Email, First Name, Last Name
  • Click Create
  • Go to Credentials tab
  • Set password: Pass@123
  • Disable “Temporary”
  • Click Set Password

Create a Group and Attach Role

Step 1: Create the Group

  • Navigate to Realm → Groups
  • Click “Create group”
  • In the dialog:
    • Group Name: mfaGroup
  • Click Save

Step 2: Assign Role to the Group

  • After creating mfaGroup, you’ll land on the group’s settings page.
  • Click on the “Role Mappings” tab.
  • Under Available Roles:
    • Find and select the role: require_otp_role
    • Click “Add selected” 

Realm Settings

Navigate to Realm Settings

  • In the left sidebar, click Realm Settings (under your realm, e.g., myrealm).

Login Settings

Enable the following under Realm Settings → Login tab:

  • User registration: On
  • Forgot password: On
  • Remember me: On

These options allow:

  • Users to self-register
  • Recover passwords
  • Have a persistent login (Remember Me)

Click Save

Email Configuration

Open Realm Settings → Email tab, and enter the following:

  • From: youremail@example.com
  • Host: smtp.gmail.com
  • Port: 587
  • Enable StartTLS: Checked
  • Enable Auth: Checked
  • Username: youremail@example.com
  • Password: Your Gmail password or App password

If 2FA is enabled in your Google account, use an App Password.
Visit: https://myaccount.google.com/apppasswords

Test Email

  • Click Test Connection
  • Then click Test Email
  • If successful, click Save

Keycloak MFA Enablement – OTP Configuration & Flow Setup

Step 1: Configure OTP Policy

Navigate to:
Realm → Authentication → Policies tab

Configure the following OTP settings:

  • OTP Type: Time-Based
  • Hash Algorithm: SHA1
  • Number of Digits: 6
  • Look Ahead Window: 1
  • OTP Token Period: 30
  • OTP Supported Applications: (leave as default or enter e.g., Google Authenticator)

Step 2: Enable OTP Configuration as Required Action

  • Go to:
    Realm → Authentication → Required Actions tab
  • Find Configure OTP
    Click Enable

Step 3: Create Role for MFA Enforcement

  • Go to:
    Realm → Roles → Add Role
  • Create a Role with name:
    require_otp_role

Step 4: Create Custom Authentication Flow

  1. Navigate to:
    Realm → Authentication → Flows
  2. Click on Browser → Click Actions → Duplicate
  3. Name the duplicated flow:
    mfa_otp_flow

Step 5: Modify mfa_otp_flow to Add Role-Based Conditional OTP

Inside mfa_otp_flow:

  1. Delete Existing Conditional OTP (if exists):
    • Navigate to:
      Realm → Authentication → Flows → mfa_otp_flow
    • Locate any existing Conditional OTP Form step.
    • Click the ⚙️ Actions dropdown → Delete

      Add New Execution Step (Conditional OTP Form)

2. Add Execution:

    • Click Add execution
  1. Select:

           Conditional OTP Form

    • Click Add

3. Set it to REQUIRED:

    • From the Actions ⚙️ dropdown next to the new Conditional OTP Form, click:
    • Set as REQUIRED

Configure the Conditional OTP Form

  • Click ⚙️ Actions → Config
  • Fill in the values below:
    • Alias: mfa-otp-check
    • Force OTP for Role: require_otp_role
  • Click Save

This ensures:

  • OTP will be enforced only for users who have the require_otp_role.

Click Save after configuration.

Final Result

Your mfa_otp_flow is now ready with role-based OTP enforcement.

  • OTP is required only for users who are assigned the require_otp_role.

Migrate AWS Cognito Users to Keycloak — Step-by-Step Guide

If you’re planning to move away from AWS Cognito and shift your identity management to Keycloak, this guide will walk you through exporting Cognito users and importing them into Keycloak.

This method is suitable for one-time migrations (not for real-time sync).

Why Migrate?

You may want to move from AWS Cognito to Keycloak because:

  • You’re consolidating user management
  • You want more customization
  • You’re hosting your own identity server
  • You’re reducing dependency on AWS

Step 1: Export Users from AWS Cognito

Use the AWS CLI to export user data from your Cognito user pool.

bash

CopyEdit

aws cognito-idp list-users --user-pool-id <your-pool-id> --max-items 60 --output json > users.json

This creates a users.json file with your Cognito users.

Step 2: Install jq on Windows

You’ll need jq, a lightweight tool for parsing and manipulating JSON data.

  • Option 1: Use winget (Recommended)


Open Command Prompt as Administrator and run:

winget install jqlang.jq

After installation, verify it:

jq --version

Step 3: Create JQ Filter to Convert Users

Create a file named convert.jq using Notepad or VS Code.

Paste the following filter script:

jq

{
  realm: "realm_name",
  users: (.Users | map({
    username: .Username,
    email: (.Attributes[] | select(.Name == "email") | .Value),
    emailVerified: ((.Attributes[] | select(.Name == "email_verified") | .Value) == "true"),
    enabled: .Enabled,
    requiredActions: ["CONFIGURE_TOTP"],
groups: ["mfaGroup"],
    realmRoles: ["require_otp_role"]



  }))
}

Save this as convert.jq.

Step 4: Convert Cognito JSON to Keycloak Format

Now use jq to process the exported JSON into a Keycloak-compatible format:

jq -f convert.jq users.json > "%USERPROFILE%\Downloads\converted_users.json"

The resulting file, converted_users.json, will be saved in your Downloads folder.

Step 5: Verify Converted JSON

Open:

C:\Users\<your-username>\Downloads\converted_users.json

Check the file in Notepad or VS Code. You should see user entries formatted like:

{
  "realm": "realm-name",
  "users": [
    {
      "username": "user1",
      "email": "user1@example.com",
      "emailVerified": true,
      "enabled": true,
       "requiredActions": [
        "CONFIGURE_TOTP"
      ],
      "groups": [
        "mfaGroup"
      ],
      "realmRoles": [
        "require_otp_role"
      ]


    },
    ...
  ]
}

Step 6: Import into Keycloak (GUI Method)

  1. Open the Keycloak Admin Console
  2. Navigate to Realm Settings → Users
  3. Click the Action button (top right) and choose Partial Import
  4. Upload converted_users.json
  5. Select the number of users to import (or leave default)
  6. Click Import

You should see a success message after the import completes.

Step 7: Verify Imported Users

After importing, go to:

  • Users tab → You’ll see the migrated users.
  • Click on any user → Confirm:
    • username
    • email
    • emailVerified
    • enabled status
Final Thoughts

This guide offers a clean, one-time migration path for moving users from AWS Cognito to Keycloak. Once imported, you can continue managing your users fully in Keycloak with custom authentication flows, roles, and federations.