Required action with configuration

1,062 views
Skip to first unread message

Eduard Schaf

unread,
Jul 14, 2021, 1:47:11 PM7/14/21
to Keycloak User
Hi all,

I'm looking for a way to create a custom required action that is configurable. 

What I want to do is to configure the api key for a REST service call within my required action. The required action will then be used as input for the "PUT /{realm}/users/{id}/execute-actions-email" call using the Keycloak Admin REST API.

Is there a way to do this with the keycloak authentication spi ? Do I have to use System Properties (I want to avoid that)?

An alternative would be to use the same flow that my custom reset credentials flow is using, starting from the "send Reset Email" Authenticator Execution, as I'm currently using the logic I would like to implement for this flow.

Is there a way to reuse my custom Authenticator Execution for this task, maybe with the keycloak action token spi

I'm happy to get responses for either options!

Best regards

Justin Gregory

unread,
Jun 2, 2022, 2:40:29 PM6/2/22
to Keycloak User
Did you every have any luck with this?  I see that you can set the required action's config via the Admin REST API (not on POST but on a subsequent PUT), but as best I can tell from the source code, Keycloak never actually does anything with it.  When the required action is init'ed, it only uses the system properties.

Justin Gregory

unread,
Jun 6, 2022, 11:53:36 AM6/6/22
to Keycloak User
If anyone else is looking to do this in the future, I was able to configure my required action via the Keycloak vault.  In our app, that's through Kubernetes secrets, but should be possible through any other vault mechanism, as well.  Probably a better way to store sensitive config settings, anyways.

MyRequiredActionFactory.java:
    @Override
    public RequiredActionProvider create(KeycloakSession session) {
        return new MyRequiredAction(session);
    }

MyRequiredActionProvider.java:
    private final String mySecretConfig;

    public MyRequiredAction(KeycloakSession session) {
        try (VaultStringSecret secret = session.vault().getStringSecret("${vault.my_secret_config}")) {
            mySecretConfig = secret.get().orElse("");
        }
    }

my-keycloak-secrets.yaml:
apiVersion: v1
kind: Secret
metadata:
  name: my-keycloak-secrets
  namespace: default
type: Opaque
stringData:
  my_secret_config: "abc123..."


keycloak-deploy.yaml:  (note that the key path has to mangled to include the realm name -- you can do this multiple times if you need the secret in more than one realm)
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...
  template:
    ...
    spec:
      containers:
        - name: keycloak
          image: mycompany/keycloak
          ...
          env:
            ...
            - name: KC_VAULT
              value: file
            - name: KC_VAULT_DIR
              value: /secrets
          volumeMounts:
            - name: secrets
              mountPath: "/secrets"
              readOnly: true
      volumes:
        - name: secrets
          secret:
            secretName: my-keycloak-secrets
            items:
              - key: my_secret_config
                path: myrealm_my__secret__config

Reply all
Reply to author
Forward
0 new messages