> ## Documentation Index
> Fetch the complete documentation index at: https://docs.authsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Adding passkey autofill to your Keycloak login flow

> Learn how to add passkey autofill to your Keycloak login flow with Authsignal.

## Overview

Passkey autofill provides an incredibly seamless and secure way for users to sign-in using their passkey.

In this guide, we will show you how to add passkey autofill to your Keycloak sign-in flow using Authsignal.

When clicking on the username or password
input fields, users will be prompted to authenticate with their passkey that they added through Authsignal's pre-built UI.

<Frame caption="Passkey autofill.">
  <video controls className="w-full aspect-video" src="https://mintcdn.com/authsignal-23/8bvDamO56aVu-Ay2/images/docs/integrations/keycloak/keycloak-passkey-autofill.mp4?fit=max&auto=format&n=8bvDamO56aVu-Ay2&q=85&s=578b13cbfa00a064b91115f92d1f120e" data-path="images/docs/integrations/keycloak/keycloak-passkey-autofill.mp4" />
</Frame>

<Card icon="github" horizontal title="Keycloak provider code example" href="https://github.com/authsignal/authsignal-keycloak-providers" />

<Note>The above example can be extended to meet your specific requirements.</Note>

## Prerequisites

* You have completed the previous guide on [adding passkey MFA to your Keycloak login flow](/integrations/keycloak/keycloak-passkey-signup-with-prebuilt-UI).

## Authsignal configuration

### Local development

To make things easy, we will make a few simple changes to your local development setup so that you can simulate a production environment, locally.
We will use `mkcert` to create a local SSL certificate and `local-ssl-proxy` to proxy requests to your local Keycloak server.

<Info>
  Replace `keycloak-demo.authsignallabs.com` with your domain. If using the pre-built UI, this will
  differ from your Authsignal custom domain. i.e. `keycloak-demo.authsignallabs.com` which our demo
  app uses vs `keycloak-demo-auth.authsignallabs.com` where the pre-built UI is running - in this
  demonstration.
</Info>

<Tabs>
  <Tab title="macOS/Linux">
    <Steps>
      <Step title="SSL Certificate Setup">
        ```bash theme={null}
        brew install mkcert
        mkcert -install
        mkcert your_domain # e.g. mkcert keycloak-demo.authsignallabs.com
        ```

        <Info>
          Take note of the path to the `.pem` files that are created as you'll need them in the next steps.
        </Info>
      </Step>

      <Step title="Custom Domain to Local IP Address Mapping">
        Map your custom domain to your local IP address by adding the following line to your `hosts` file:

        ```bash theme={null}
        sudo vim /etc/hosts
        ```

        Add this line:

        ```
        127.0.0.1 your_domain # e.g. 127.0.0.1 keycloak-demo.authsignallabs.com
        ```
      </Step>

      <Step title="Run the proxy server">
        ```bash theme={null}
        npx local-ssl-proxy --key keycloak-demo.authsignallabs.com-key.pem --cert keycloak-demo.authsignallabs.com.pem --source 8444 --target 8443
        ```
      </Step>

      <Step title="Run your Keycloak server">
        Learn more about the [Keycloak server configuration options](https://www.keycloak.org/server/enabletls).

        ```bash theme={null}
        bin/kc.sh start-dev \
        --hostname=keycloak-demo.authsignallabs.com \
        --https-certificate-file=keycloak-demo.authsignallabs.com.pem \
        --https-certificate-key-file=keycloak-demo.authsignallabs.com-key.pem \
        --http-host=127.0.0.1
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Windows">
    <Steps>
      <Step title="SSL Certificate Setup">
        ```powershell theme={null}
        # Install mkcert
        winget install mkcert
        mkcert -install
        mkcert your_domain # e.g. mkcert keycloak-demo.authsignallabs.com
        ```

        <Info>
          Take note of the path to the `.pem` files that are created as you'll need them in the next steps.
        </Info>
      </Step>

      <Step title="Custom Domain to Local IP Address Mapping">
        Open Notepad as Administrator and open the hosts file located at:
        `C:\Windows\System32\drivers\etc\hosts`

        Add this line:

        ```
        127.0.0.1 your_custom_domain # e.g. 127.0.0.1 keycloak-demo.authsignallabs.com
        ```
      </Step>

      <Step title="Run the proxy server">
        ```powershell theme={null}
        npx local-ssl-proxy --key keycloak-demo.authsignallabs.com-key.pem --cert keycloak-demo.authsignallabs.com.pem --source 8444 --target 8443
        ```
      </Step>

      <Step title="Run your Keycloak server">
        Learn more about the [Keycloak server configuration options](https://www.keycloak.org/server/enabletls).

        ```powershell theme={null}
        .\bin\kc.bat start-dev ^
        --hostname=keycloak-demo.authsignallabs.com ^
        --https-certificate-file=keycloak-demo.authsignallabs.com.pem ^
        --https-certificate-key-file=keycloak-demo.authsignallabs.com-key.pem ^
        --http-host=127.0.0.1
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

<Steps>
  <Step title="Sign in to your Keycloak server" stepNumber={5}>
    Open your browser and navigate to `https://your_domain:8443` (e.g. `https://keycloak-demo.authsignallabs.com:8443`) which will redirect you to the admin sign-in page on your proxied https Keycloak server.

    <Frame caption="Opening the Keycloak admin sign-in page">
      <img src="https://mintcdn.com/authsignal-23/8bvDamO56aVu-Ay2/images/docs/integrations/keycloak/keycloak-admin-sign-in.png?fit=max&auto=format&n=8bvDamO56aVu-Ay2&q=85&s=42dea38e1d390a5d4dde3482bf17c842" alt="" width="980" height="645" data-path="images/docs/integrations/keycloak/keycloak-admin-sign-in.png" />
    </Frame>
  </Step>
</Steps>

### Changes to your Keycloak configuration

In your Keycloak admin UI, navigate to the **Authentication** section and click on your custom flow. Delete the default username and password flow.

<Frame caption="Delete the default username and password flow">
  <img src="https://mintcdn.com/authsignal-23/8bvDamO56aVu-Ay2/images/docs/integrations/keycloak/keycloak-admin-remove-username-password.png?fit=max&auto=format&n=8bvDamO56aVu-Ay2&q=85&s=319bd2a692f06179509826f99a0536dc" alt="" width="2850" height="1446" data-path="images/docs/integrations/keycloak/keycloak-admin-remove-username-password.png" />
</Frame>

Click on the Authsignal Authenticator settings and toggle on **Enable Passkey Autofill**.

<Frame caption="Enable Passkey Autofill">
  <img src="https://mintcdn.com/authsignal-23/8bvDamO56aVu-Ay2/images/docs/integrations/keycloak/keycloak-authsignal-settings-button.png?fit=max&auto=format&n=8bvDamO56aVu-Ay2&q=85&s=bcf21fec599a288bfad954b3fdb6b304" alt="" width="2058" height="378" data-path="images/docs/integrations/keycloak/keycloak-authsignal-settings-button.png" />
</Frame>

<Frame caption="Enable Passkey Autofill">
  <img src="https://mintcdn.com/authsignal-23/8bvDamO56aVu-Ay2/images/docs/integrations/keycloak/keycloak-enable-passkey-autofill.png?fit=max&auto=format&n=8bvDamO56aVu-Ay2&q=85&s=db76a76cbf3e4dd279f0f69d976d4556" alt="" width="2876" height="1452" data-path="images/docs/integrations/keycloak/keycloak-enable-passkey-autofill.png" />
</Frame>

### Sign-in UI configuration

We need to add some custom code to the Keycloak sign-in page so that it can use [Authsignal's Web SDK](/sdks/client/web/setup) to handle passkey autofill.

Start by creating a new theme for your Keycloak instance, at the following path: `themes/mytheme/login/login.ftl` on your keycloak server.

You can call the theme whatever you want, but for this example, we will call it `mytheme`.

Add the following code to the `login.ftl` file. This code will allow autofill to work when the user clicks the username or password input fields.

```html themes/mytheme/login/login.ftl theme={null}
<link rel="stylesheet" href="${url.resourcesPath}/css/styles.css" />
<script src="${url.resourcesPath}/js/script.js"></script>
<div class="login-container">
  <div class="login-card">
    <div class="login-header">
      <p>Please enter your credentials to continue</p>
    </div>

    <form action="${url.loginAction}" method="post" class="login-form">
      <div class="form-group">
        <label for="username">Username</label>
        <input
          id="username"
          name="username"
          type="text"
          autocomplete="username webauthn"
          placeholder="Enter your username"
        />
      </div>

      <div class="form-group">
        <label for="password">Password</label>
        <input
          id="password"
          name="password"
          type="password"
          placeholder="Enter your password"
          autocomplete="current-password webauthn"
        />
      </div>

      <button type="submit">Sign In</button>
    </form>
  </div>
</div>
```

<Warning>
  `webauthn` has to be the last autocomplete attribute value in the list otherwise it will not work.
</Warning>

Create a Javascript file at `themes/mytheme/login/resources/js/script.js` and add the following code. This code is required to allow autofill to work when the user clicks the input.

```js themes/mytheme/login/resources/js/script.js theme={null}
function setWebauthnAttribute() {
  var usernameInput = document.getElementById("username");
  var passwordInput = document.getElementById("password");

  const formElement = document.querySelector("form");

  if (usernameInput && passwordInput) {
    usernameInput.setAttribute("autocomplete", "username webauthn");

    // NOTE: Replace the following values with your Authsignal tenant ID and server URL
    var client = new window.authsignal.Authsignal({
      tenantId: "YOUR_TENANT_ID",
      baseUrl: "https://api.authsignal.com/v1",
    });

    client.passkey
      .signIn({ autofill: true })
      .then((response) => {
        if (response) {
          const hiddenTokenInput = document.createElement("input");
          hiddenTokenInput.type = "hidden";
          hiddenTokenInput.name = "token";
          hiddenTokenInput.value = response.token;
          formElement.appendChild(hiddenTokenInput);
          formElement.submit();
        }
      })
      .catch((error) => {
        console.log("error", error);
      });
  }
}

function loadAuthsignalSdk() {
  var script = document.createElement("script");
  script.onload = setWebauthnAttribute;
  script.src = "https://unpkg.com/@authsignal/browser@0.5.2/dist/index.min.js";
  document.head.appendChild(script);
}

document.addEventListener("DOMContentLoaded", loadAuthsignalSdk);
```

Restart your Keycloak server, and navigate to the **Realm settings** section in the Keycloak admin UI. Click **Themes**.
On the **Login theme** line, select `mytheme` and click **Save**.

<Frame caption="Opening the Keycloak admin sign-in page">
  <img src="https://mintcdn.com/authsignal-23/8bvDamO56aVu-Ay2/images/docs/integrations/keycloak/keycloak-admin-add-theme.png?fit=max&auto=format&n=8bvDamO56aVu-Ay2&q=85&s=fbd58363385fad6dccf7ce5451fb61b4" alt="" width="1637" height="746" data-path="images/docs/integrations/keycloak/keycloak-admin-add-theme.png" />
</Frame>

<Info>
  You can style your theme by adding your own CSS to the
  `themes/mytheme/login/resources/css/styles.css` file.
</Info>

Navigate to your realm's sign-in page and you should see the new theme.

<Info>
  You can find your realm's sign in page URL by selecting your realm and then navigating to the
  **Clients** section in the Keycloak admin UI and clicking **Home URL**.
</Info>

<Frame caption="Find your realm's Home URL">
  <img src="https://mintcdn.com/authsignal-23/8bvDamO56aVu-Ay2/images/docs/integrations/keycloak/keycloak-client-url.png?fit=max&auto=format&n=8bvDamO56aVu-Ay2&q=85&s=16c95982d3b1b56bf066f1b76f8ef182" alt="" width="2888" height="820" data-path="images/docs/integrations/keycloak/keycloak-client-url.png" />
</Frame>

### Passkey configuration updates

Before passkeys can be used on your Keycloak login page, you need to ensure that you have added your
Keycloak login page domain as an [expected origin](/authentication-methods/passkey/prebuilt-ui#configure-passkeys-in-the-authsignal-portal).

As an example, in this demo the passkey configuration is as follows:

* Relying Party ID: `authsignallabs.com`
* Expected Origins: `keycloak-demo.authsignallabs.com` (Keycloak login page) and `keycloak-demo-auth.authsignallabs.com` (pre-built UI custom domain)

<Frame caption="Passkey autofill.">
  <video controls className="w-full aspect-video" src="https://mintcdn.com/authsignal-23/8bvDamO56aVu-Ay2/images/docs/integrations/keycloak/keycloak-passkey-autofill.mp4?fit=max&auto=format&n=8bvDamO56aVu-Ay2&q=85&s=578b13cbfa00a064b91115f92d1f120e" data-path="images/docs/integrations/keycloak/keycloak-passkey-autofill.mp4" />
</Frame>

## Conclusion

That's it! You've successfully added passkey autofill to your Keycloak sign-in flow using Authsignal.
