# Secrets in Configuration

Use encrypted configuration values to protect sensitive passwords, secrets, tokens and keys.

A secret configuration may be expressed as `${handler::value}`, where the `handler` is the name of a `io.smallrye.config.SecretKeysHandler` to decode or decrypt the `value`.

## Encrypt Configuration values

To encrypt and later decrypt configuration values, add the following managed dependency:

pom.xml

    <dependency>
        <groupId>io.smallrye.config</groupId>
        <artifactId>smallrye-config-crypto</artifactId>
    </dependency>

Use the Quarkus CLI command to add a new encrypted value or encrypt an existent value in `application.properties`:

CLI

    quarkus config set --encrypt my.secret 1234

For more information about how to install the Quarkus CLI and use it, please refer to the Quarkus CLI guide.

The configuration property `my.secret` will be added to `application.properties` with the value `1234` encrypted and encoded in Base64 and an expression `${aes-gcm-nopadding::}`, with the required secret handler to decrypt the value. If it doesn’t exist, an encryption key is also generated and set into `smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key`.

    my.secret=${aes-gcm-nopadding::DLTb_9zxThxeT5iAQqswEl5Dn1ju4FdM9hIyVip35t5V}

    smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key=DDne5obnfH1RSeTg71xSZg

| The default secret handler uses the `AES/GCM/NoPadding` algorithm and requires the expression `${aes-gcm-nopadding::value}` to decrypt the `value`.

## Read Encrypted Configuration

Quarkus configuration system, will automatically decrypt the configuration value when looking up `my.secret`.

The encryption key used to encrypt the value must be the same used to decrypt the value and set into `smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key`.

    class BusinessBean {
        @Inject
        SmallRyeConfig config;

        public void businessMethod() {
            ConfigValue mySecret = config.getConfigValue("my.secret");
            mySecret.getValue(); (1)
        }
    }

1 | Returns the value `1234`.

## Store secrets in a Keystore

While having encrypted values, is better than plain values, we would still like to avoid having these set up in `application.properties`.

Java KeyStore is used as a file-based `Vault`. Sensitive data can be imported to and securely stored in this `Vault` as Java `SecretKey` values. To use the `KeyStore` `ConfigSource` add the following managed dependency:

    <dependency>
        <groupId>io.smallrye.config</groupId>
        <artifactId>smallrye-config-source-keystore</artifactId>
    </dependency>

### Create a KeyStore

The following command creates a simple KeyStore:

    echo DLTb_9zxThxeT5iAQqswEl5Dn1ju4FdM9hIyVip35t5V | keytool -importpass -alias my.secret -keystore properties -storepass arealpassword -storetype PKCS12 -v

The `-alias my.secret` option stores the configuration property name `my.secret` in the KeyStore with the value `DLTb_9zxThxeT5iAQqswEl5Dn1ju4FdM9hIyVip35t5V`. The `-storepass arealpassword` is the password required to access the keystore.

We also need to safely store the encryption key. You shouldn’t store the key with the rest of the secrets, so we can create another `KeyStore` for the key:

    echo DDne5obnfH1RSeTg71xSZg | keytool -importpass -alias smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key -keystore key -storepass anotherpassword -storetype PKCS12 -v

### Use the KeyStore

To use the newly created `KeyStore`s, add the following configuration to `application.properties`:

    smallrye.config.source.keystore."properties".path=properties (1)
    smallrye.config.source.keystore."properties".password=arealpassword (2)
    smallrye.config.source.keystore."properties".handler=aes-gcm-nopadding (3)

    smallrye.config.source.keystore."key".path=key (4)
    smallrye.config.source.keystore."key".password=anotherpassword (5)

1 | The path to the ´KeyStore` with properties secrets
2 | The `KeyStore` password to be able to extract the `KeyStore` secrets
3 | The `SecretKeyHandler` to decrypt the `KeyStore` secrets
4 | The path to the ´KeyStore` with encryption key.
5 | The `KeyStore` password to be able to extract the encryption key

## Protect the KeyStore password

You need to specify a `KeyStore` password in `application.properties` for Quarkus be able to extract secrets from the keystore. This keystore password is a sensitive value, and therefore you should consider how to minimize a risk of leaking it and how to protect it.

One important thing you should be aware of is that leaking this password does not necessarily mean the actual secrets stored in the keystore will also be leaked since an unauthorized person will also need to access the actual keystore file. Restricting access to the keystore file to a limited number of roles and having Quarkus processes running in one of these roles will make it harder for anyone outside the group access the keystore. The keystore password can be set as an environment variable and this password should be periodically changed to limit a window during which an attacker can try to get to the keystore.