Score:0

Wildfly standalone.xml - passing secret to KeyCloak SPI from elytron credential store

br flag

I'm migrating KeyCloak v15 (WildFly v23) passwords from the old vault to elytron credential store. It works fine for the standard use case. In standalone.xml, I have: /server/extensions/extension:

<extension module="org.wildfly.extension.elytron"/>

/server/profile/subsystem:

<subsystem xmlns="urn:wildfly:elytron:13.0" final-providers="elytron" disallowed-providers="OracleUcrypto">
    <providers>
        <provider-loader name="elytron" module="org.wildfly.security.elytron"/>
    </providers>
    <audit-logging>
        <file-audit-log name="local-audit" path="audit-log.log" relative-to="jboss.server.log.dir" format="JSON"/>
    </audit-logging>
    <credential-stores>
        <credential-store name="credStore" location="/data/credStore.jceks">
            <implementation-properties>
                <property name="keyStoreType" value="JCEKS"/>
            </implementation-properties>
            <credential-reference clear-text="MASK-123456789;salt123;42"/>
        </credential-store>
    </credential-stores>
</subsystem>

and I access the passwords using /server/profile/subsystem[@xmlns="urn:jboss:domain:jgroups:8.0"]/stacks/stack[@name="tcp"]/auth-protocol/digest-token/shared-secret-reference:

<shared-secret-reference store="credStore" alias="myBlock::mySecret"/>

However, there is one secret I need to pass to a SPI in a property. Any idea how to do it? This was the old vault way:

/server/system-properties/property:

<property name="secret" value="${VAULT::myBlock::mySecret::1}"/>

/server/profile/subsystem[@xmlns="urn:jboss:domain:keycloak-server:1.1"]/spi:

<spi name="mySpi">
    <provider name="file" enabled="true">
        <properties>
            <property name="password" value="${secret}"/>
        </properties>
    </provider>
</spi>
Score:0
br flag

I found 2 possibilities:

  1. Rewrite the SPI to retrieve the secret directly from Elytron credential store in Java
  2. Set an environment variable beforehand (export SECRET="$(secret-getter-script)") and use the variable in standalone.xml:
<spi name="mySpi">
    <provider name="file" enabled="true">
        <properties>
            <property name="password" value="${env.SECRET}"/>
        </properties>
    </provider>
</spi>
McLayn avatar
br flag
In the end, using an environment variable wasn't safe enough for our use and I had to teach our SPI to read Elytron credential store contents
Score:0
br flag

I had to rewrite our SPI to read Elytron credential store contents:

import org.jboss.as.server.CurrentServiceContainer;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceRegistry;
import org.wildfly.security.credential.PasswordCredential;
import org.wildfly.security.credential.store.CredentialStore;
import org.wildfly.security.credential.store.CredentialStoreException;
import org.wildfly.security.password.Password;
import org.wildfly.security.password.interfaces.ClearPassword;
  private static String getClientSecret(String credentialStore, String secretAlias) {
    final ServiceName SERVICE_NAME_CRED_STORE = ServiceName.of("org", "wildfly", "security", "credential-store");
    final ServiceName sn = ServiceName.of(SERVICE_NAME_CRED_STORE, credentialStore);
    final ServiceRegistry registry = CurrentServiceContainer.getServiceContainer();
    final ServiceController<?> credStoreService = registry.getService(sn);
    final CredentialStore cs = (CredentialStore) credStoreService.getValue();
//    if (!cs.exists(secretAlias, PasswordCredential.class)) {
//      throw new CredentialStoreException("Alias " + secretAlias + " not found in credential store.");
//    }
    final Password password;
    try {
      password = cs.retrieve(secretAlias, PasswordCredential.class).getPassword();
    } catch (CredentialStoreException e) {
      e.printStackTrace();
      return null;
    }
    if (!(password instanceof ClearPassword)) {
      throw new ClassCastException("Password is not of type ClearPassword");
    }
    return new String(((ClearPassword) password).getPassword());
  }
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.