Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a use case driven guide for using encrypted expressions to replace sentitive information specified using clear-text #2121

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
137 changes: 137 additions & 0 deletions _posts/2024-03-19-credential-store-for-encrypted-expressions.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
layout: post
title: 'Using Credential Stores With Encrypted Expressions on WildFly'
date: 2024-03-19
tags: credential-store encryption
synopsis: How to set up encrypted expressions and use it to replace sensitive information specified as clear-text on applications deployed to WildFly.
author: prarthonapaul
---

:toc: macro
:toc-title:

WildFly allows the use of credential stores to keep alias for sensitive information, such as, passwords for external services. Credential stores can be used to store different credentials under aliases and use credential-reference to specify them in server configuration. As a result, the credential is no longer visible in clear text.

toc::[]

== Prerequisite
To follow along with this guide you will need:

* about 10 minutes
* WildFly with credential-store support

== About Encrypted Expressions
https://wildfly-security.github.io/wildfly-elytron/blog/tag/credential-store-for-passwords/[A previous guide] demonstrates how to use credential stores to avoid using clear-text passwords. However, as you may have noticed, the password for the credential store was specified in clear-text. And while having access to the credential-store password does not allow a human to read the contents of a credential-store, it is still not secure. Additionally, there are other types of sensitive information we may use when configuring a server which we would not want to appear in the standalone.xml file.

This is where encrypted expressions are useful. Support for encrypted expressions allow us to specify sensitive information, like the password for a credential-store without using plain-text values. Encrypted expressions can also be used for system properties, where a value expression is specified.
And lastly, credential-store can only be used for credential-reference attributes. But there are other attributes where we can enter sensitive information, but it does not include a credential reference. This guide will explain the these three use cases for encrypted expressions and how to configure them.

== Configuring Encrypted Expressions
Let's first create a `secret-key-credential-store` that we can use to store the encrypted expressions. Just like a regular credential-store file, this will also create a .cs file inside the directory you specify. However, this will be human readable.
```
/subsystem=elytron/secret-key-credential-store=newCredStore:add(path=newSecretKeyCred.cs, relative-to=jboss.server.config.dir)
```
If you already had a .cs file that you would like to use, then you can specify the path here and set the `create` and `populate` attributes to `false`. These attributes are `true` by default as seen here:
```
{
"outcome" => "success",
"result" => {
"path" => "newSecretKeyCred.cs",
"relative-to" => "jboss.server.config.dir",
"create" => true,
"default-alias" => "key",
"key-size" => 256,
"populate" => true
}
}
```
Here is an example of the contents of the newSecretKeyCred.cs file:
```
# Properties Credential Store (Do Not Modify)
key=RUxZAUsOhzQhCv7KbD9f2SGBgWkmTC9l0lgu28FWM4UfRBY7QQ==
```
As you can see there as been a key created for you already using the default alias `key`. You can create a new key with a new alias of your own using the following command:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/ as been/ has been

```
/subsystem=elytron/secret-key-credential-store=newCredStore:generate-secret-key(alias=newSecretKey, key-size=128)
```
Now let's use these keys for the use cases mentioned above.

== Encrypted Expression for Credential Reference
Now that we have a generated secret key in a credential store we can activate the resource responsible for handling encrypted expressions. And we can use that to convert a clear-text password phrase into an encrypted expression which will be stored in the credential-store.
```
/subsystem=elytron/expression=encryption:add(resolvers=[{name=initial-resolver, credential-store=newCredStore, secret-key=key}])
/subsystem=elytron/expression=encryption:create-expression(resolver=initial-resolver, clear-text=MyPassword)
```
the second command will give you an output like this which we will use to specify the password instead of the clear-text phrase:
```
{
"outcome" => "success",
"result" => {"expression" => \
"${ENC::initial-resolver:RUxZAUMQEH6CP3xXyAqYzqsC3oNayyeGH32wsdAZ8VLkkxaEmWc=}"}
}
```
Now if we wanted to create another credential-store, then we can use this encrypted expression to create it as follows:
```
/subsystem=elytron/credential-store=main:add(path=mySecondCredStore.cs, relative-to=jboss.server.config.dir, credential-reference= {clear-text="${ENC::initial-resolver:RUxZAUMQEH6CP3xXyAqYzqsC3oNayyeGH32wsdAZ8VLkkxaEmWc=}"}, create=true)
```
This does not just apply to credential stores, we can also do this with any other resource that uses credential-reference, such as a `key-store` or a `key-manager`.

== Encrypted Expression for System Property
System properties can be used to customize the behaviour of the server. These are key-value pairs that can be specified using the cli commands. System properties can be specified as follows:
```
/system-property=foo:add(value=bar)
{"outcome" => "success"}
```
However, sometimes the value may be something you do not want to specify in plaintext. If we configure it as shown above, the value can easily be discovered using the read-resource function. So, we need a way to specify it without using clear-text. However, since this does not use credential-reference we cannot use a credential-store directly. Instead, we can use encrypted expressions.

We can encrypt the value for a system property using encrypted expressions as follows:
```
/subsystem=elytron/expression=encryption:create-expression(resolver=initial-resolver, clear-text=bar)
{
"outcome" => "success",
"result" => {"expression" => "${ENC::initial-resolver:RUxZAUMQXSp3dFy+4aUcAzpayRZVeHHNTU/4bE3iUW8LGPplXkA=}"}
}
```
We can now update our value to this encrypted expression:
```
/system-property=foo:write-attribute(name=value, value=${ENC::initial-resolver:RUxZAUMQXSp3dFy+4aUcAzpayRZVeHHNTU/4bE3iUW8LGPplXkA=})
```
If we use the read-resource function on our system property, we can no longer see the value in plaintext.

== Encrypted Expressions to Replace Other Passwords
The WildFly has some resources which contain sensitive information, such as passwords, without using credential-reference. One such example is the `truststore-password` attribute under the `secure-deployment` resource under tne `elytron-oidc-client` subsystem. These values can also be specified using encrypted expressions. We can encrypt the value as follows:
```
/subsystem=elytron/expression=encryption:create-expression(resolver=initial-resolver, clear-text=secret)
{
"outcome" => "success",
"result" => {"expression" => "${ENC::initial-resolver:RUxZAUMQdZ5/RHt5Oj+Whv
K3l+rtR2AnjrtOhBkKW6X58vUtrUw=}"}
}
```
Once the encrypted expression has been added, it can easily be used to specify sensitive information, like as seen below:
```
/subsystem=elytron-oidc-client/secure-deployment=simple-webapp.war:write-attribute(name=truststore-password,value="${ENC::initial-resolver:RUxZAUMQA6O7VXU/6cdzA4qlQNU1SM34N5kk53l8DjsljXoEYTc=}")
{"outcome" => "success"}
```
and for the naming subsystem example, we can use the following commands:
```
/subsystem=naming/binding=java\:global\/federation\/ldap\/example:write-attribute(name=environment, value={java.naming.security.credentials="${ENC::initial-resolver:RUxZAUMQA6O7VXU6cdzA4qlQNU1SM34N5kk53l8DjsljXoEYTc=}"})
```

== Disabling Cli History
As you may notice some of the commands still include sensitive information. And since the jboss cli caches all executed commands, we need to disable history to hide all inputs using the command below:
```
history --disable
```
Caching can be enabled again using the command below:
```
history --enable
```
== Summary
This guide demonstrates three use cases where we can use encrypted expressions to specify sensitive information.

== Resources
* https://docs.wildfly.org/30/WildFly_Elytron_Security.html#EncryptedExpressions[Encrypted Expressions]
* https://docs.wildfly.org/30/WildFly_Elytron_Security.html#CredentialStore[Credential Stores]
* https://docs.wildfly.org/30/wildscribe/system-property/index.html[System Properties]
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor, superfluous asterisk