Tuesday, May 16, 2017

Credential References

The last post showed how to create credential store and manage aliases of credentials there. We will continue down the road to show how to use them.

What is Credential Reference?

Credential reference is new type of attribute one can find in management model of WildFly and API to work with it. Credential reference is object type attribute consisting of several simple attributes:
  • credential store - name of credential store)
  • credential alias - name of the alias
  • credential type - type of credential the reference denotes
  • clear text - simple clear text attribute to be used as password credential or interpreted as command from underlying OS

How Credential Reference Works?

For developers: look at utility class org.jboss.as.controller.security.CredentialReference it contains definitions of attribute and builders ready to use. The class is located at wildfly-core module controller.
The key part is method getCredentialSourceSupplier which returns in fact returns CredentialSource supplier with Exception (ExceptionSupplier<CredentialSource, Exception>). CredentialSource is used later to resolve credential using one of its getCredential methods.

For administrators: use credential-reference attribute on resources where you want or need to hide clear text passwords from configuration (you should do it in production systems anyway ;-) ).

Through Credential Store

Define your credential store (suppose we have the definition from older blog post).
First thing first, create your alias
/subsystem=elytron/credential-store=test/alias=test_db_password:add(secret-value="sa")

Let's add new data source using this command
data-source add --name=testDS --jndi-name=java:/testDS --driver-name=h2 --connection-url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE --user-name=sa --credential-reference={store=test, alias=test_db_password}

We can check the result now with command /subsystem=datasources/data-source=testDS:read-resource(recursive=true)
{
    "outcome" => "success",
    "result" => {
        "allocation-retry" => undefined,
        "allocation-retry-wait-millis" => undefined,
        "allow-multiple-users" => false,
        "authentication-context" => undefined,
        "background-validation" => undefined,
        "background-validation-millis" => undefined,
        "blocking-timeout-wait-millis" => undefined,
        "capacity-decrementer-class" => undefined,
        "capacity-decrementer-properties" => undefined,
        "capacity-incrementer-class" => undefined,
        "capacity-incrementer-properties" => undefined,
        "check-valid-connection-sql" => undefined,
        "connectable" => false,
        "connection-listener-class" => undefined,
        "connection-listener-property" => undefined,
        "connection-url" => "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE",
        "credential-reference" => {
            "store" => "test",
            "alias" => "test_db_password"
        },
        "datasource-class" => undefined,
        "driver-class" => undefined,
        "driver-name" => "h2",
        "elytron-enabled" => false,
        "enabled" => true,
        "enlistment-trace" => false,
        "exception-sorter-class-name" => undefined,
        "exception-sorter-properties" => undefined,
        "flush-strategy" => undefined,
        "idle-timeout-minutes" => undefined,
        "initial-pool-size" => undefined,
        "jndi-name" => "java:/testDS",
        "jta" => true,
        "max-pool-size" => undefined,
        "mcp" => "org.jboss.jca.core.connectionmanager.pool.mcp.SemaphoreConcurrentLinkedDequeManagedConnectionPool",
        "min-pool-size" => undefined,
        "new-connection-sql" => undefined,
        "password" => undefined,
        "pool-fair" => undefined,
        "pool-prefill" => undefined,
        "pool-use-strict-min" => undefined,
        "prepared-statements-cache-size" => undefined,
        "query-timeout" => undefined,
        "reauth-plugin-class-name" => undefined,
        "reauth-plugin-properties" => undefined,
        "security-domain" => undefined,
        "set-tx-query-timeout" => false,
        "share-prepared-statements" => false,
        "spy" => false,
        "stale-connection-checker-class-name" => undefined,
        "stale-connection-checker-properties" => undefined,
        "statistics-enabled" => false,
        "track-statements" => "NOWARN",
        "tracking" => false,
        "transaction-isolation" => undefined,
        "url-delimiter" => undefined,
        "url-selector-strategy-class-name" => undefined,
        "use-ccm" => true,
        "use-fast-fail" => false,
        "use-java-context" => true,
        "use-try-lock" => undefined,
        "user-name" => "sa",
        "valid-connection-checker-class-name" => undefined,
        "valid-connection-checker-properties" => undefined,
        "validate-on-match" => undefined,
        "connection-properties" => undefined,
        "statistics" => undefined
    }
}
Note the credential-reference attribute and password is undefined.

Simple masked password credential

It is credential reference compatible with older PicketBox Vault masked password hash which can be generated using WildFly Elytron Tool (peek to $JBOSS_HOME/bin directory or wait for next blog post).
Create mask string:
./bin/elytron-tool.sh mask -i 351 -s A1B2C3D4 -x sa

Credential reference attribute syntax:
credential-reference={clear-text="MASK-Ewcyuqd/nP9;A1B2C3D4;351"}

OS command supplied password credential

There are use cases when it is reasonable to get password credential from underlying OS command (read it from standard output). For this we have another for of credential-reference. We are supporting two types of syntax. Space delimited and comma delimited command line arguments.
Space delimited:
credential-reference={clear-text="{EXT}/usr/bin/getpass.sh arg1 arg2 arg3", type="COMMAND"}

Comma delimited:
credential-reference={clear-text="{CMD}/usr/bin/getpass.sh,arg1,arg2,arg3", type="COMMAND"}

Directly specified clear text password credential

There also the simplest way to specify password credential without anyhow obscuring the value. Use with caution.
credential-reference={clear-text="sa"}

Note on security

All mentioned obscuring cases are not bullet proof and there should be further means to make it harder to reveal the credential from configuration.

2 comments:

  1. Thanks for the post and simple explanations. I wonder if there is a lit of where we could use Credential Store, and what for we still need to stick to the password vault. I.e. can we use it for:
    - security-realm secret value ?
    - cluster password in messaging-activemq
    - remote-connector trust-store-password value ?
    - bridge password?
    Thanks

    ReplyDelete
  2. Hello, I would put in the credential store not only the password but the username too.
    How could I reference this username in the connection string?

    ReplyDelete