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