[[CredentialStore]]
= Credential Store

ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]

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 two default credential store implementations.  The first implementation is the `KeyStoreCredentialStore` which is an
implementation backed by a `KeyStore`.  The `KeyStoreCredentialStore` implementation supports the storage of various credential types,
`PasswordCredential`, `KeyPairCredential`, and `SecretKeyCredential`.  The second implementation is the `PropertiesCredentialStore`.  This credential
store is dedicated to the storage of `SecretKeyCredential` instances using a properties file.  The `PropertiesCredentialStore` does not offer any protection
of the credentials it stores so its primary purpose is to provide an initial key to a server environment.

This documentation is primarily focused on the `KeyStoreCredentialStore` and `PropertiesCredentialStore`; however the section <<Custom_CredentialStore, Custom CredentialStore>> describes the SPIs for implementing a custom credential store and the section <<Migrating_Existing_Vaults, Migrating Existing Vaults>> describes how to convert a vault to a credential store.

It is possible to operate on credential stores using either a standalone command line tool `elytron-tool.sh` which is included with WildFly or by using management operations through the `jboss-cli.sh`, management console or other management client calling the management interface directly.

The `elytron-tool.sh` script to execute the command line 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.  The commands in this documentation are making use of the `.sh` script on linux; the `elytron-tool.bat` and `elytron-tools.ps1` scripts can be used on Microsoft Windows.

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
----

== Credential Store Creation

=== KeyStoreCredentialStore / credential-store

The `KeyStoreCredentialStore` supports the largest number of credential types which can be stored within a credential store, additionally as the implementation is backed by a Java KeyStore the storage is protected using the mechanisms provided by the KeyStore implementations.

==== Command Line

When using the `credential-store` command of the `elytron-tool.sh` script by default, this command assumes the type of the store is a `KeyStoreCredentialStore` backed by a `JCEKS` `KeyStore`.

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.

NOTE: The command line tool only creates the instance of the credential store on the underlying file system; the management operation is still required to define the credential store in the `elytron` subsystem.

==== 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(path=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(path=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.

=== PropertiesCredentialStore / secret-key-credential-store

This is a simple credential store implementation which can only be used to store `SecretKey` instances.  This credential store also does not offer any protection of the contents.
Within an application server environment it is always possible to get into a cycle of how is an initial secret provided to unlock further resources, this is primarily the purpose
of this credential store.  The strategy in the past had been to use masking of a password using password based encryption, the down side of this approach was the password used for
the masking was stored in the source code and being an open source project this means the password is well known.  By using the `PropertiesCredentialStore` installations are back
in control of the initial secret.  Although this credential store does not offer its own protection filesystem level access control can still be used to restrict access ideally to
just the application server process.

==== Command Line

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

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

==== 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 `secret-key-credential-store` resource to the `elytron` subsystem referencing this newly created credential store.

[source,options="nowrap"]
----
/] /subsystem=elytron/secret-key-credential-store=mycredstore:add(path=propcredstore.cs, relative-to=jboss.server.config.dir, create=false, populate=false)
{"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, and
populate it with a generated SecretKey under the alias `key` if it does not already exist.

[source,options="nowrap"]
----
/] /subsystem=elytron/secret-key-credential-store=mycredstore:add(path=propcredstore.cs, relative-to=jboss.server.config.dir)
{"outcome" => "success"}
----

WARNING: If you rely on automatic generation of a `SecretKey` be sure to create a backup of the key as soon as possible.  If you were to loose the key we do not have a mechanism to decrypt anything
encrypted with the lost key.


== Credential Manipulation

The contents of the credential stores can be manipulated using either the command line tool or by using management operations.  Unlike key stores the credential store APIs allow for multiple entries to be stored under a single alias provided each entry is of a different credential type.

=== Adding Credentials

The different credential store implementations support different credential types as illustrated in this table.

[%autowidth,cols="h,1,1",stripes=even]
|===
| Credential Type | KeyStoreCredentialStore | PropertiesCredentialStore

| PasswordCredential
| Supported
| Unsupported

| KeyPairCredential
| Supported
| Unsupported

| SecretKeyCredential
| Supported
| Supported
|===

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.

==== PasswordCredential

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: 
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
}
----

==== KeyPairCredential

===== Command Line

The following command allows you to import a key pair credential with an alias of `example` from a file containing
a private key in OpenSSH format:
[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store --import-key-pair example --private-key-location /home/user/.ssh/id_rsa --location=standalone/configuration/mycredstore.cs
Credential store password:
Confirm credential store password:
Passphrase to be used to decrypt private key (can be nothing if no passphrase was used to encrypt the key): secret
Confirm passphrase to be used to decrypt private key (can be nothing if no passphrase was used to encrypt the key): secret
Alias "example" has been successfully stored
----

The following command allows you to import a key pair credential with an alias of `example` by specifying a private key in OpenSSH format :
[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store --import-key-pair example --private-key-string="-----BEGIN OPENSSH PRIVATE KEY-----
                                                   b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABCdRswttV
                                                   UNQ6nKb6ojozTGAAAAEAAAAAEAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlz
                                                   dHAyNTYAAABBBAKxnsRT7n6qJLKoD3mFfAvcH5ZFUyTzJVW8t60pNgNaXO4q5S4qL9yCCZ
                                                   cKyg6QtVgRuVxkUSseuR3fiubyTnkAAADQq3vrkvuSfm4n345STr/i/29FZEFUd0qD++B2
                                                   ZoWGPKU/xzvxH7S2GxREb5oXcIYO889jY6mdZT8LZm6ZZig3rqoEAqdPyllHmEadb7hY+y
                                                   jwcQ4Wr1ekGgVwNHCNu2in3cYXxbrYGMHc33WmdNrbGRDUzK+EEUM2cwUiM7Pkrw5s88Ff
                                                   IWI0V+567Ob9LxxIUO/QvSbKMJGbMM4jZ1V9V2Ti/GziGJ107CBudZr/7wNwxIK86BBAEg
                                                   hfnrhYBIaOLrtP8R+96i8iu4iZAvcIbQ==
                                                   -----END OPENSSH PRIVATE KEY-----"
                                                   --location=standalone/configuration/mycredstore.cs
Credential store password:
Confirm credential store password:
Passphrase to be used to decrypt private key (can be nothing if no passphrase was used to encrypt the key): secret
Confirm passphrase to be used to decrypt private key (can be nothing if no passphrase was used to encrypt the key): secret
Alias "example" has been successfully stored
----

NOTE: If specifying your key in PKCS format rather than OpenSSH format, you must specify both the private and public key. The
PKCS private key must also not be encrypted with a passphrase.

Alternatively to importing, you may use the command line tool to generate and store a key pair credential in a credential store.
The following command allows you to generate and store a key pair credential under the alias `example` using the ecdsa algorithm:
[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store --generate-key-pair example --algorithm EC --location=standalone/configuration/mycredstore.cs
Credential store password:
Confirm credential store password:
Alias "example" has been successfully stored
----

You can then export the public key generated in OpenSSH format using the following command:
[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store --export-key-pair-public-key example
Credential store password:
Confirm credential store password:
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMfncZuHmR7uglb0M96ieArRFtp42xPn9+ugukbY8dyjOXoi
cZrYRyy9+X68fylEWBMzyg+nhjWkxJlJ2M2LAGY=
----

==== SecretKeyCredential

===== Command Line

Each of the examples in this section uses the `KeyStoreCredentialStore` to use the `PropertiesCredentialStore` this can be specified on the command line by adding the `--type PropertiesCredentialStore` parameter to the command line.

A new secret key can be generated with the following command.

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

By default this will create a 256 bit secret key, if either a 128 bit or 192 bit secret key is desired this can be specified with the `--size=128` or `--size=192` parameters respectively.

An existing secret key can be exported with the following command.

[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store --export-secret-key=example --location=standalone/configuration/mycredstore.cs
Credential store password: 
Exported SecretKey for alias example=RUxZAUucgH8RSMNvoUj/rMz+pBZddttGCuT9of4TgfYLnN5Z1w==
----

NOTE: The exported key uses a custom representation to allow Elytron to recognise exported keys.

Finally a previously exported secret key can be imported with the following command.

[source,options="nowrap"]
----
]$ bin/elytron-tool.sh credential-store --import-secret-key=imported --location=standalone/configuration/mycredstore.cs
Credential store password: 
SecretKey to import: RUxZAUucgH8RSMNvoUj/rMz+pBZddttGCuT9of4TgfYLnN5Z1w==
Alias "imported" has been successfully stored
----

It is possible to also specify the key to import on the command line e.g. `--key=RUxZAUucgH8RSMNvoUj/rMz+pBZddttGCuT9of4TgfYLnN5Z1w==` but this would be vieweable by others users that can consult running processes and might also be cached in the history of the shell executing the commands.

===== Management Operations

For secret key manipulation the same set of command are available for both the `credential-store` resource and the `secret-key-credential-store` resource.

A new secret key can be generated with the following command.

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

To generate either a 128 bit key or 192 bit key the parameter `key-size=128` or `key-size=192` can be specified respectively.

An existing secret key can be exported with the following command.

[source,options="nowrap"]
----
[standalone@localhost:9990 /] /subsystem=elytron/credential-store=mycredstore:export-secret-key(alias=example)
{
    "outcome" => "success",
    "result" => {"key" => "RUxZAUs+Y1CzEPw0g2AHHOZ+oTKhT9osSabWQtoxR+O+42o11g=="}
}

----

[source,options="nowrap"]
----
Finally a previously exported secret key can be imported with the following commands.

[standalone@localhost:9990 /] history --disable
[standalone@localhost:9990 /] /subsystem=elytron/credential-store=mycredstore:import-secret-key(alias=imported, key="RUxZAUs+Y1CzEPw0g2AHHOZ+oTKhT9osSabWQtoxR+O+42o11g==")
{"outcome" => "success"}
[standalone@localhost:9990 /] history --enable
----

In this last example we also temporarily disable the history in the CLI to prevent the key from being cached in the CLI hisory.

=== 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 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: 
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 Credentials

Finally, it is also possible to remove an alias 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"
        }
    }]}
}
----

By default the `credential-store` resource assumes the type to be removed is `PasswordCredential`.  If a different type is to be removed it can be specified with the `entry-type=SecretKeyCredential` parameter.  The `secret-key-credential-store` only holds secret keys so the entry type never needs to be specified.

== 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 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 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]]
== 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: - 

[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 alias specified from the credential store.

|-g,--generate-key-pair <alias>
|Generate a new key pair credential and add it as an entry to the credential store using the specified alias.

|--generate-secret-key <alias>
|Generate a new secret key credential and add it as an entry to the credential store using the specified alias.

|--export-secret-key <alias>
|Export a secret key credential identified using the specified alias.

|-xp,--export-key-pair-public-key <alias>
|Display the public key of a key pair credential entry under the specified alias in OpenSSH format.

|--import-secret-key <alias>
|Import a secret key credential and add it as an entry to the credential store using the specified alias.

|-ikp,--import-key-pair <alias>
|Add a new key pair credential entry to the credential store using the specified alias.

|--encrypt <alias>
|Encrypt a clear text string using the secret key stored under the specified alias.

|-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 Jakarta Connectors 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

|===

The following parameters can be provided for the `generate-key-pair` command:

.generate-key-pair Parameters
|===
|Parameter |Description |Default Value

|-k, --algorithm <algorithm name>
|The encryption algorithm to be used. One of: RSA, DSA, or EC
|RSA

|-j,--size <size in bytes>
|Size of the private key in bytes
|RSA: 2048, DSA: 2048, EC: 256
|===

The following parameter can be provided for the `generate-secret-key` command:

.generate-secret-key Parameter
|===
|Parameter |Description |Default Value

|--size
|Size of the secret key in bits, can be one of 128, 192, or 256.
|256
|===


The following parameters can be provided for the `import-key-pair` command:

.import-key-pair Parameters
|===
|Parameter |Description

|-pvk, --private-key-string <private key to store>
|The private key as a string. Alternative to `private-key-location`

|-pvl, --private-key-location <path>
|The path to a file containing a private key. Alternative to `private-key-string`

|-pbk, --public-key-string <public key to store>
|The public key as a string. Alternative to `public-key-location`

|-pbl, --public-key-location <path>
|The path to a file containing a public key. Alternative to `public-key-string`

|-kp, --key-passphrase <passphrase>
|The passphrase used to decrypt the private key if needed. Can also be specified via prompt
|===

The following parameter can be provided for the `import-secret-key` command:

.import-secret-key Parameter
|===
|Parameter |Description |Default Value

|--key
|The secret key to be imported, if not specified the key will be prompted for.
|N/A
|===

The following parameters can be provided for the `encrypt` command:

.encrypt Parameters
|===
|Parameter |Description |Default Value

|--clear-text <clear text>
|The clear text string to encrypt, if omitted this wil be prompted for.
|N/AThe following parameters can be provided for the `generate-key-pair` command:

.generate-key-pair Parameters
|===
|Parameter |Description |Default Value

|-k, --algorithm <algorithm name>
|The encryption algorithm to be used. One of: RSA, DSA, or EC
|RSA

=== 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 Jakarta Connectors 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 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.

|===
