[[CredentialStore]]
= Credential Store

One new component included with WildFly Elytron for the secure storage of credentials is the Credential Store.  Previous versions of the application server made use of the Vault which was used for the secure storage of clear text strings; the credential store moves forward a step to focus on the secure storage of credentials.  As with the Vault the stored credentials could be clear text passwords however other formats are also supported.

WildFly Elytron contains a default credential store implementation `KeyStoreCredentialStore` which is a store implementation backed by a `KeyStore`.

This documentation will be focused on using the `KeyStoreCredentialStore`; however the section <<Custom_CredentialStore, Custom CredentialStore>> will describe how to convert a vault to a credential store. 

== KeyStoreCredentialStore

=== Creation

==== Command Line

Included with WildFly is a command line tool which amongst other things allows for the creation of and manipulation of credential stores.  A script to execute this tool can be found within the `bin` folder of the application server installation.  The WildFly Elytron tool supports a number of commands, one of which being `credential-store` which operates on a credential store.  By default this command assumes the type of the store is a `KeyStoreCredentialStore` backed by a `JCEKS` `KeyStore`.

The following command provides a summary of the command line arguments which can be used with the `credential-store` command: -

[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store
----

NOTE: These commands are making use of the `.sh` script on linux; the `elytron-tool.bat` and `elytron-tools.ps1` scripts can be used on Microsoft Windows.

A new credential store can be created using the following command: -

[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store --create --location=standalone/configuration/mycredstore.cs
Credential store password: 
Confirm credential store password: 
Credential Store has been successfully created
----

This command prompts twice for the password that should be used to secure the store.  Alternatively the password can be passed in using the `--password` argument however that may mean the password is cached in the local command history or visible to other users viewing the list of running processes.

==== Management Operation

It is also possible to operate on a credential store using management operations against a running server using the application server's CLI.

The following operation can be used to add a `credential-store` resource to the `elytron` subsystem referencing this newly created credential store.

[source,options="nowrap"]
----
/] /subsystem=elytron/credential-store=mycredstore:add(location=mycredstore.cs, relative-to=jboss.server.config.dir, credential-reference={clear-text=StorePassword})
{"outcome" => "success"}
----

In this example the resource was added to reference an existing credential store, however with a small change this command can also automatically create the store if it does not exist.

[source,options="nowrap"]
----
/] /subsystem=elytron/credential-store=mycredstore:add(location=mycredstore.cs, relative-to=jboss.server.config.dir, credential-reference={clear-text=StorePassword}, create=true)
{"outcome" => "success"}
----

NOTE: The file representing the credential store is not created immediately, it will instead be created the first time a credential is added.

Previous versions of the application server supported a single vault definition only; credential stores however are cross referenced by name so multiple credential stores can be defined simultaneously.

=== Adding a Credential

As with all the manipulation options it is possible to use either the command line tool or management operations against a running server to modify the contents of the store.

WARNING: Care should be taken when using the command line tool to ensure the store is not currently in use by any other processes.  If the store is in use by another process which updates the contents of the store changes made by the tool could be lost.

Using the tooling it is possible to add a clear text password as a credential.

==== Command Line

The following command adds a new credential with an alias of `example` to the store using the command line tool: -

[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store --add=example --location=standalone/configuration/mycredstore.cs
Credential store password: 
Confirm credential store password: 
Secret to store: 
Confirm secret to store: 
Alias "example" has been successfully stored
----

==== Management Operation

Using a management operation the following command can be used to add a new alias of `example` to the credential store.

[source,options="nowrap"]
----
[standalone@localhost:9990 /] /subsystem=elytron/credential-store=mycredstore:add-alias(alias=example, secret-value=ExamplePassword)
{
    "outcome" => "success",
    "result" => undefined
}
----

=== Listing Aliases

It is possible to list the aliases contained within the credential store, however it is not possible to list the actual values stored.

==== Command Line

Using the command the command line tool will show a list of aliases stored within the credential store: -

[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store --aliases --location=standalone/configuration/mycredstore.cs
Credential store password: 
Confirm credential store password: 
Credential store contains following aliases: example
----

==== Management Operation

The following management operation will also show the aliases contained within the credential store.

[source,options="nowrap"]
----
/] /subsystem=elytron/credential-store=mycredstore:read-aliases
{
    "outcome" => "success",
    "result" => ["example"]
}
----

=== Removing Aliases

Finally it is also possible to remove an alais from the credential store.

==== Command Line

Using the WildFly Elytron Tool the following command will remove an alias from the store.

[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store --remove=example --location=standalone/configuration/mycredstore.cs
Credential store password: 
Confirm credential store password: 
Alias "example" has been successfully removed
----

==== Management Operation

The following management operation can be used to remove an alias from the credential store.

[source,options="nowrap"]
----
/] /subsystem=elytron/credential-store=mycredstore:remove-alias(alias=example)
{
    "outcome" => "success",
    "result" => undefined,
    "response-headers" => {"warnings" => [{
        "warning" => "Update dependent resources as alias 'example' does not exist anymore",
        "level" => "WARNING",
        "operation" => {
            "address" => [
                ("subsystem" => "elytron"),
                ("credential-store" => "mycredstore")
            ],
            "operation" => "remove-alias"
        }
    }]}
}
----

== Referencing Credentials

After being able to populate and manipulate a credential store the next step is being able to reference the stored credential so that it can be used.

=== Management Model References

Various resources that make use of credentials across the application server's management model contain `credential-reference` attributes that can be used either to specify a `clear-password` or to cross reference a credential from within a configured credential store.

The following is an example of how how to define a `key-store` within the Elytron subsystem specifying a clear text password to access the store.

[source,options="nowrap"]
----
/] /subsystem=elytron/key-store=exampleKS:add(relative-to=jboss.server.config.dir, path=example.keystore,    \ 
                                              type=JCEKS, credential-reference={clear-text=ExamplePassword})
{"outcome" => "success"}
----

To reference a credential from the previously defined credential store the following command could be used instead.

[source,options="nowrap"]
----
/] /subsystem=elytron/key-store=exampleKS:add(relative-to=jboss.server.config.dir, path=example.keystore, type=JCEKS, credential-reference={store=mycredstore, alias=example})
{"outcome" => "success"}
----

The above command assumes that the referenced credential already exists in the previously defined credential store.
The next section will describe how credentials can automatically be added to the previously defined credential store.

=== Automatic Updates of Credential Stores

Instead of needing to add a credential to a previously defined credential store in order to reference it from a `credential-reference`,
it is possible to have the credential get added automatically to the previously defined credential store by specifying both
the `store` and `clear-text` attributes for the `credential-reference`. In particular, when adding a new `credential-reference`
with both the `store` and `clear-text` attributes specified:

* If the `alias` attribute is also specified, then one of the following will then occur:
** If the previously defined credential store does not contain an entry for the given alias, a new entry will be added
to the credential store to hold the clear text password that was specified. The `clear-text` attribute will then be
removed from the management model.
** If the credential store does contain an entry for the given alias, the existing credential will be replaced with the
clear text password that was specified. The `clear-text` attribute will then be removed from the management model.
* If the `alias` attribute is not specified, an alias will be generated and a new entry will be added to the credential
store to hold the clear text password that was specified. The `clear-text` attribute will then be removed from the
management model.

As an example, the following CLI command will result in a new entry being added to the previously defined credential
store, `mycredstore`, with alias `myNewAlias` and credential `myNewPassword`:

[source,options="nowrap"]
----
/subsystem=elytron/key-store=exampleKS:add(relative-to=jboss.server.config.dir, path=example.keystore, type=JCEKS, credential-reference={store=mycredstore, alias=myNewAlias, clear-text=myNewPassword})
{
    "outcome" => "success",
    "result" => {"credential-store-update" => {
        "status" => "new-entry-added",
        "new-alias" => "myNewAlias"
    }}
}
----

When updating an existing `credential-reference` that contains both the `alias` and `store` attributes to also specify
the `clear-text` attribute:

* The existing credential in the previously defined credential store will be replaced with the clear text password that
was specified. The `clear-text` attribute will then be removed from the management model.

As an example, the following CLI command will result in updating the credential for the `myNewAlias` entry that was just
added to the previously defined credential store:

[source,options="nowrap"]
----
/subsystem=elytron/key-store=exampleKS:write-attribute(name=credential-reference.clear-text,value=myUpdatedPassword)
{
    "outcome" => "success",
    "result" => {"credential-store-update" => {"status" => "existing-entry-updated"}},
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}
----

NOTE: If an operation that includes a ```credential-reference``` parameter fails for any reason,
      no automatic credential store update will take place, i.e., any credential store that was
      specified via the ```credential-reference``` attribute will contain the same contents as it
      did before the operation was executed.

=== wildfly-config.xml

If you are making use of the `wildfly-config.xml` descriptor it is also possible to define a credential store within this descriptor to obtain credentials without requiring them to be in-lined within the configuration.

As an example the CLI can be executed with a configuration: -

[source,options="nowrap"]
----
]$ bin/jboss-cli.sh -c -Dwildfly.config.url=bin/wildfly-config.xml
----

Without using a credential store the username and credential can be specified in the clear e.g.

[source,xml,options="nowrap"]
----
<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <authentication-client xmlns="urn:elytron:1.0">
        <authentication-rules>
                    <rule use-configuration="default" />
        </authentication-rules>
        <authentication-configurations>
            <configuration name="default">
                <sasl-mechanism-selector selector="DIGEST-MD5" />
                <providers>
                    <use-service-loader/>
                </providers>
                <set-user-name name="User" />
                <credentials>
                    <clear-password password="UserPassword" />
                </credentials>
             </configuration>
        </authentication-configurations>
    </authentication-client>
</configuration>
----

However it is possible to move this password to the credential store and update the configuration to load it from the store e.g.

[source,xml,options="nowrap"]
----
<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <authentication-client xmlns="urn:elytron:1.0">
        <credential-stores>
            <credential-store name="mycredstore">
                <attributes>
                    <attribute name="keyStoreType" value="JCEKS" />
                    <attribute name="location" value="standalone/configuration/mycredstore.cs" />
                </attributes>
                <protection-parameter-credentials>
                    <clear-password password="StorePassword" />
                </protection-parameter-credentials>
            </credential-store>
        </credential-stores>

        <authentication-rules>
                    <rule use-configuration="default" />
        </authentication-rules>
        <authentication-configurations>
            <configuration name="default">
                <sasl-mechanism-selector selector="DIGEST-MD5" />
                <providers>
                    <use-service-loader/>
                </providers>
                <set-user-name name="User" />
                <credentials>
                    <credential-store-reference store="mycredstore" alias="User" />
                </credentials>
             </configuration>
        </authentication-configurations>
    </authentication-client>
</configuration>
----

Within this second example the key changes being the addition of the `<credential-stores />` section and updating the `<credentials/>` section to use a `<credential-store-reference/>` to specify which credential store should be used and which alias from that credential store should be used.

In the above example, the credential store's protection parameter is specified as a clear password, but it is also possible
to specify it as a masked password.

[source,xml,options="nowrap"]
----
<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <authentication-client xmlns="urn:elytron:1.4">
        <credential-stores>
            <credential-store name="mycredstore">
                <attributes>
                    <attribute name="keyStoreType" value="JCEKS" />
                    <attribute name="location" value="standalone/configuration/mycredstore.cs" />
                </attributes>
                <protection-parameter-credentials>
                    <masked-password masked-password="M3loEZ7uua1X1PiYCYJDpg==" iteration-count="100" salt="12345678"/>
                </protection-parameter-credentials>
            </credential-store>
        </credential-stores>

        <authentication-rules>
                    <rule use-configuration="default" />
        </authentication-rules>
        <authentication-configurations>
            <configuration name="default">
                <sasl-mechanism-selector selector="DIGEST-MD5" />
                <providers>
                    <use-service-loader/>
                </providers>
                <set-user-name name="User" />
                <credentials>
                    <credential-store-reference store="mycredstore" alias="User" />
                </credentials>
             </configuration>
        </authentication-configurations>
    </authentication-client>
</configuration>
----

== CredentialStore APIs

It is also possible to make use of the CredentialStore APIs directly.  This could be useful for applications that require access to securely stored credentials.  This could also be an option for an application to populate a credential store for use elsewhere.

The following code demonstrates how to obtain an initialised instance of `KeyStoreCredentialStore` so it can be used to store and retrieve credentials.

[source,java,options="nowrap"]
----
Password storePassword = ClearPassword.createRaw(ClearPassword.ALGORITHM_CLEAR, "StorePassword".toCharArray());
ProtectionParameter protectionParameter = new CredentialSourceProtectionParameter(IdentityCredentials.NONE.withCredential(new PasswordCredential(storePassword)));

CredentialStore credentialStore = CredentialStore.getInstance("KeyStoreCredentialStore", CREDENTIAL_STORE_PROVIDER);

Map<String, String> configuration = new HashMap<>();
configuration.put("location", "mystore.cs");
configuration.put("create", "true");

credentialStore.initialize(configuration, protectionParameter);
----

The following code illustrates how a couple of different credential types can be added to a credential store: -

[source,java,options="nowrap"]
----
Password clearPassword = ClearPassword.createRaw(ClearPassword.ALGORITHM_CLEAR, "ExamplePassword".toCharArray());
credentialStore.store("clearPassword", new PasswordCredential(clearPassword));

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
SecretKey secretKey = keyGenerator.generateKey();
credentialStore.store("secretKey", new SecretKeyCredential(secretKey));
----

These credentials can then be obtained again from the store: -

[source,java,options="nowrap"]
----
Password password = credentialStore.retrieve("clearPassword", PasswordCredential.class).getPassword();
SecretKey secretKey = credentialStore.retrieve("secretKey", SecretKeyCredential.class).getSecretKey();
----

NOTE: As the type is specified when retrieving a credential it is possible to store multiple credentials under the same alias.

Please use the published javadoc for more information in relation to the APIs and the credential types supported within WildFly Elytron.

== Migrating Existing Vaults

If migrating from a prior version of the application server it is possible that you already are making use of a PicketBox vault for the storage of clear text passwords.  The tooling provided can be used to convert the vault to the format used by the `KeyStoreCredentialStore`.

Within the WildFly Elytron command line tool an additional command `vault` is available specifically for the conversion of legacy vaults to a credential store.  A complete vault can be converted to a credential store with the following command: - 

The following command can be used to convert a single entry from a vault to a credential store: -

[source,options="nowrap"]
----
]$ bin/elytron-tool.sh vault --enc-dir standalone/configuration/vault --keystore standalone/configuration/vault.keystore --iteration 44 --salt 00000000 --alias vault \ 
    --location standalone/configuration/newcredstore.cs 
Vault password: 
Confirm vault password: 
Vault (enc-dir="standalone/configuration/vault";keystore="standalone/configuration/vault.keystore") converted to credential store "standalone/configuration/newcredstore.cs"
----

When executing this command the destination credential store must not already exist.  The password used for the credential store will be the password originally used for the vault.

Entries stored within the vault would have been stored specifying a "block" and "alias" value; within the credential store the new alias will be `block::alias`.

[[Custom_CredentialStore]]
== Custom Credential Store

It is also possible to provide custom credential store implementations.  Overall the pattern to implementing a custom credential store is very similar to the pattern that would be followed to implement a custom key store.

 * Extend the SPI
 * Implement a `java.security.Provider` to register the implementation.

The SPI to be extended is `org.wildfly.security.credential.store.CredentialStoreSpi`.  The custom implementation will be required to implement the following methods.

[source,java,options="nowrap"]
----
public abstract void initialize(Map<String, String> attributes, CredentialStore.ProtectionParameter protectionParameter, Provider[] providers) throws CredentialStoreException;
----

This method is required to perform the initialisation of the credential store, by taking in a `Map` of attributes it allows for custom configuration to be provided as required by the store.

[source,java,options="nowrap"]
----
public abstract boolean isModifiable();
----

A credential store needs to advertise if it supports modifications so clients can determine if the modification APIs can be used.

[source,java,options="nowrap"]
----
public abstract <C extends Credential> C retrieve(String credentialAlias, Class<C> credentialType, String credentialAlgorithm, AlgorithmParameterSpec parameterSpec, CredentialStore.ProtectionParameter protectionParameter) throws CredentialStoreException;
----

The `retrieve` method is essential for all credential store implementations to retrieve credentials of a specific type using the alias specified.

In addition to `retrieve` there are two more methods that can optionally be implemented.

[source,java,options="nowrap"]
----
public boolean exists(String credentialAlias, Class<? extends Credential> credentialType) throws CredentialStoreException;

public Set<String> getAliases() throws UnsupportedOperationException, CredentialStoreException;
----

A default implementation of `exists` already is implemented which checks if a call to `retrieve` returns a credential as requested.  However it could be optimal to check the existence of a credential without actually loading it.  The `getAliases` method is optional as some implementations may only be able to retrieve a credential by name rather than query all available credentials.

The next set of methods to implement are the methods needed for updates to be applied to the underlying credential store.

[source,java,options="nowrap"]
----
public abstract void store(String credentialAlias, Credential credential, CredentialStore.ProtectionParameter protectionParameter)
            throws CredentialStoreException, UnsupportedCredentialTypeException;
            
public abstract void remove(String credentialAlias, Class<? extends Credential> credentialType, String credentialAlgorithm, AlgorithmParameterSpec parameterSpec) throws CredentialStoreException;

public void flush() throws CredentialStoreException;
----

The `store` and `remove` methods either add credentials to a credential store or remove them.  Implementing the `flush` method is optional but this method can be used as a trigger for a store to persist its state.

The final stage is to provide an implementation of `java.security.Provider` which can return an instance of the SPI for the `CredentialStore` service type.  The WildFly Elytron provider which makes the Elytron implementations available is `org.wildfly.security.credential.store.WildFlyElytronCredentialStoreProvider`.  The source code for this provider can be used as an example.

== Reference

The previous sections have made use of either the WildFly Elytron Tool or the management operations and specified the arguments and configuration options required for the action being performed.  These operations and tools however support a variety of other options so this section provides some additional detail.

=== Elytron Tool - `credential-store` Command

Examples of how to structure calling the `credential-store` command were provided earlier.  When using the `credential-store` command the following actions are possible: -

.credential-store Actions
|===
|Action |Description

|-a,--add <alias>
|Add a new entry to the credential store using the specified alias.

|-c,--create
|Create a new credential store instance.

|-e,--exists <alias>
|Test if the specified alias already exists in the credential store.

|-r,--remove <alias>
|Remove the aliad specified from the credential store.

|-v,--aliases
|Display all aliases

|-f,--summary
|Print summary, especially command how to create this credential store

|-h,--help
|Get help with usage of this command
|===

The following parameters can be provided for each action to specify how to load the store.

.credential-store Parameters
|===
|Parameter |Description

|-d,--debug
|Print stack trace when error occurs.

|-i,--iteration <arg>
|Iteration count for final masked password of the credential store

|-l,--location <loc>
|Location of credential store storage file

|-n,--entry-type <type>
|Type of entry in credential store

|-o,--other-providers <providers>
|Comma separated list of JCA provider names. Providers will be supplied to the credential store instance.  Each provider must be installed through java.security file or through service loader from properly packaged jar file on classpath.

|-p,--password <pwd>
|Password for credential store

|-q,--credential-store-provider <cs-provider>
|Provider name containing CredentialStoreSpi implementation.  Provider must be installed through java.security file or through service loader from properly packaged jar file on classpath.

|-s,--salt <arg>
|Salt to apply for final masked password of the credential store

|-t,--type <type>
|Credential store type

|-u,--properties <arg>
| Implementation properties for credential store type in form of "prop1=value1; ... ;propN=valueN"

|-x,--secret <secret to store>
|Password credential value

|===

=== Elytron Tool - `vault` Command

The `vault` command is used to convert a legacy vault to a credential store and supports the following parameters.

.vault Parameters
|===
|Parameter |Description

|-b,--bulk-convert <description file>
|Bulk conversion with options listed in description file.

|-d,--debug
|Print stack trace when error occurs.

|-e,--enc-dir <dir>
|Vault directory containing encrypted files (defaults to "vault")

|-f,--summary
|Print summary of conversion

|-h,--help
|Get help with usage of this command

|-i,--iteration <arg>
|Iteration count (defaults to "23")

|-k,--keystore <keystore>
|Vault keystore URL (defaults to "vault.keystore")

|-l,--location <loc>
|Location of credential store storage file (defaults to "converted-vault.cr-store" in vault encryption directory)

|-o,--other-providers <providers>
|Comma separated list of JCA provider names. Providers will be supplied to the credential store instance.  Each provider must be installed through java.security file or through service loader from properly packaged jar file on classpath.

|-p,--keystore-password <pwd>
|Vault keystore password, used to open original vault key store, and used as password for new converted credential store

|-q,--credential-store-provider <cs-provider>
|Provider name containing CredentialStoreSpi implementation.  Provider must be installed through java.security file or through service loader from properly packaged jar file on classpath.

|-s,--salt <salt>
|8 character salt (defaults to "12345678")

|-t,--type <type>
|Converted credential store type (defaults to "KeyStoreCredentialStore")

|-u,--properties <arg>
|Configuration parameters for credential store in form of: "parameter1=value1; ... ;parameterN=valueN"

|-v,--alias <arg>
|Vault master key alias within key store (defaults to "vault")

|===

=== KeyStoreCredentialStore

When configuring the `KeyStoreCredentialStore` the following configuration options are supported.

.KeyStoreCredentialStore Configuration
|===
|Name |Default |Description

|create
|false
|If the credential store does not exist should it be created?

|cryptographicAlgorithm
|AES/CBC/NoPadding
|The algorithm to use when using an external store.

|external
|false
|Should external storage be used?

|externalPath
|N/A
|Path to external storage.

|keyAlias
|cs_key
|The alias to use from the KeyStore when working with external storage.

|keyStoreType
|`KeyStore.getDefault()`
|The type of the key store used for the credential store.

|location
|N/A
|The location of the credential store.

|modifiable
|true
|Should the store be modifiable via the exposed API.

|===