Script-based authenticator deployed but not appearing in authentication flow builder

Running KeyCloak 12.0.1 (latest current).
Ubuntu 20.04.

Server started with standalone.sh -Dkeycloak.profile.feature.scripts=enabled.

To be sure, ./standalone/configuration/profile.properties contains:

feature.scripts=enabled
profile=preview

My script-based authenticator is successfully deployed according both to the logs:

2020-12-27 21:48:32,121 INFO  [org.jboss.as.server] (ServerService Thread Pool -- 33) WFLYSRV0010: Deployed "sentinel-authenticator.jar" (runtime-name : "sentinel-authenticator.jar")

… and the deployments directory listing:

-rw-r----- 1 keycloak keycloak 8888 Dec 19 18:17 README.txt
-rw-rw---- 1 keycloak keycloak 1509 Dec 27 22:21 sentinel-authenticator.jar
-rw-r--r-- 1 keycloak keycloak   26 Dec 27 22:21 sentinel-authenticator.jar.deployed

My .jar file is verified to expand to the following:

META-INF/
          keycloak-scripts.json
sentinel-role-authenticator.js

where keycloak-scripts.json contains:

{
    "authenticators": [
        {
            "name": "Sentinel Role Authenticator",
            "fileName": "sentinel-role-authenticator.js",
            "description": "Sentinel Role Authenticator"
        }
    ]
}%

And here is the content of sentinel-role-authenticator.js itself:

AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationFlowError");

 function authenticate(context) {
    var MANDATORY_ROLE = 'sentinel';
    var username = user ? user.username : "anonymous";

    var client = session.getContext().getClient();

    LOG.debug("Checking access to authentication for client '" + client.getName() + "' through mandatory role '" + MANDATORY_ROLE + "' for user '" + username + "'");

    var mandatoryRole = client.getRole(MANDATORY_ROLE);

    if (mandatoryRole === null) {
        LOG.debug("No mandatory role '" + MANDATORY_ROLE + "' for client '" + client.getName() + "'");
        return context.success();
    }

    if (user.hasRole(mandatoryRole)) {
        LOG.info("Successful authentication for user '" + username + "' with mandatory role '" + MANDATORY_ROLE + "' for client '" + client.getName() + "'");
        return context.success();
    }

    LOG.info("Denied authentication for user '" + username + "' without mandatory role '" + MANDATORY_ROLE + "' for client '" + client.getName() + "'");
    return denyAccess(context, mandatoryRole);
 }

 function denyAccess(context, mandatoryRole) {
    var formBuilder = context.form();
    var client = session.getContext().getClient();
    var description = !mandatoryRole.getAttribute('deniedMessage').isEmpty() ? mandatoryRole.getAttribute('deniedMessage') : [''];
    var form = formBuilder
        .setAttribute('clientUrl', client.getRootUrl())
        .setAttribute('clientName', client.getName())
        .setAttribute('description', description[0])
        .createForm('denied-auth.ftl');
    return context.failure(AuthenticationFlowError.INVALID_USER, form);
 }%

PROBLEM: Although the script is deployed, it is not available in the KeyCloak authentication flow builder.

Obviously, I’ve restarted KeyCloak time and again…

Thoughts?

Since we are facing the exact same problem right now: Did you find a solution for your problem?

I found a temporary solution—namely, uploading the script via the deprecated script UI—but the script generally stopped working as of 12.0.3… I’m at a loss. KeyCloak has proven entirely inadequate so far to help with non-extraordinary use-cases like this one. Major time loss…