Data encryption and key rotation
Overview
Data encryption and key rotation are essential elements of HashiCorp Boundary's security framework, ensuring the protection and integrity of sensitive information. Boundary employs strong encryption methods to secure data both at rest and in transit. Implementing regular key rotation helps mitigate the risks associated with prolonged key usage, enhancing overall security. Boundary’s encryption and key rotation capabilities enable you to comply with industry standards and regulatory requirements, such as GDPR, HIPAA, and PCI-DSS, which mandate stringent data protection measures.
Encryption at rest
Boundary employs strong encryption algorithms to secure data stored within its system. This includes encrypting sensitive information such as access credentials, session recordings, and audit logs. The encryption at rest ensures that even if the underlying storage is compromised, the data remains protected and inaccessible without the proper decryption keys.
Encryption in transit
Boundary ensures that data transmitted between clients, controllers, and workers is encrypted using TLS (Transport Layer Security). This prevents eavesdropping and man-in-the-middle attacks, ensuring that data remains confidential and unaltered during transmission.
KMS providers
The KMS provider provides the root of trust for keys used in various encryption operations within Boundary, such as encrypting sensitive data stored in the Boundary database or encrypting the data used to authenticate a KMS worker to a controller.
Boundary supports various KMS providers, including HashiCorp Vault, AWS KMS, Azure Key Vault, GCP Cloud KMS, and more. You can configure KMS providers as part of the Boundary controller configuration. For detailed instructions on configuring KMS providers, please refer to this documentation.
Key types
The root key provides the root of trust for all scope-specific encrypted data in the Boundary database. This works by having several layers of encryption that all link back to the root key. Whenever you create a new scope, Boundary immediately creates one key-encryption-key (KEK), several data-encryption-keys (DEKs), and a new key version for each of the keys. The key version holds the keying material for the key. Using key versions allows you to rotate keying material, while retaining the same key resource.
Boundary creates following per-scope keys:
- A single key encrypting key (KEK), that is the “root” key for that scope. This key’s responsibility is to encrypt the other keys in that scope.
- One or more data encrypting keys (DEKs), each defined for a specific purpose.
Every KEK is encrypted by an external KMS provider. The external KMS is defined as part of the configuration file (potentially with encrypted parameters via a config KMS).
External KMS key types
Boundary uses KMS keys for various purposes, such as protecting secrets, authenticating workers, recovering data, encrypting values in Boundary’s configuration, and more. KMS configurations can specify one or more purposes per defined key. These are the currently defined purposes:
“root”: The root KMS key acts as a KEK for the scope-specific KEKs (also referred to as the scope's root key).
“previous-root”: The previous-root KMS key is utilized during the migration to a new root key. Including the previous-root KMS key in your configuration directs the boundary controller to use it for decrypting existing information in the database. This step is essential for rotating and rewrapping the KEKs, thereby completing the migration to the new root key.
“worker-auth”: The worker-auth KMS key is a key shared by the controller and worker in order to authenticate a worker to the controller. If a worker is registered using worker-led or controller-led methods, this is not needed.
“recovery”: The recovery KMS key is used for rescue/recovery operations that can be used by a client to authenticate almost any operation within Boundary.
Note
It is not required for this kms configuration block to exist in the controller's configuration file. We highly recommend to leave it out except when actually needed, and to use change control capabilities to ensure that the configuration file modification is authorized. After it's no longer needed, the block should be removed. On the client side, a user can use the -recovery-config
flag with any operation on the CLI to specify a configuration file containing a suitable kms block. This functionality is also accessible via the Go SDK
Note
Requests authorized via this mechanism show a user of `u_recovery`. This mechanism cannot be used to authorize a session, as there is no uniquely identifying user information available.“config”: This key can be used to encrypt values within Boundary's configuration file. The config kms block allows you to encrypt sensitive or secret values, such as cloud API keys for KMS's, in boundary’s configuration file. This enables you to safely pass the file to a change control system. Only another operator or system with access to that KMS can decrypt the values. Boundary checks for a config KMS block at startup, and if it exists, uses it to decrypt any encrypted values during startup.
“bsr”: The bsr KMS key is required for session recording. If you do not add a bsr key to your controller configuration, you will receive an error when you attempt to enable session recording. The key is used for encrypting data and checking the integrity of recordings.
DEK key types
DEKs are used to encrypt sensitive/secret application data in the database. Boundary encrypts each scope's DEKs with the corresponding scope's root KEK. This KEK is further encrypted using the KMS key designated for the root purpose. This way, only the root of trust (the root key) can be used to decrypt the data in the database, since you need to decrypt the KEK first, which can then be used to decrypt the DEKs, which in turn can be used to decrypt the application data.
The scoped DEKs and their purposes are detailed below:
audit: This is used to encrypt secret values in the event log. For more information about the event log, refer to the events config.
database: This is the general-purpose DEK used to encrypt values within the database. Values that are encrypted are those generally considered to be secret, such as API keys, third-party tokens, certificate private keys, and so on.
oidc: This is used to encrypt OIDC information in cookies and authentication requests.
oplog: This is used for encrypting oplog (operation log) values for the given scope.
tokens: This is used for encrypting tokens generated by auth methods within the given scope.
sessions: This is used as a base key against which to derive session-specific encryption keys.
Rotating keys
We recommend rotating keys regularly in alignment with security best practices and industry standards such as PCI DSS, which mandate periodic key rotation.
Rotating keys provides several advantages:
- Limiting the amount of data encrypted by the same key version reduces the risk of successful attacks.
- In the event a key is compromised, regular rotation minimizes the number of messages vulnerable to compromise. If there's any suspicion that a key has been compromised, it should be rotated and revoked immediately to mitigate potential damage.
- Regular rotation ensures that Boundary remains resilient and can handle manual rotation effectively during security incidents like key compromise.
When rotating keys, Boundary generates a new key version for the KEK and all DEKs within the specified scope. These new key versions are then used for future encryption operations, while older key versions remain available for decrypting existing data in the database.
Additionally, you have the option to use the rotate key command to rewrap existing key versions with the new KEK version. This process involves re-encrypting both new and existing DEK versions with the new KEK version, ensuring all DEK versions, both new and old, are encrypted with the latest KEK version. This is particularly useful when you want to discontinue using an old KEK version.
For detailed instructions on key rotation and rewrapping, refer to the key version lifecycle management documentation.
KMS root key migration
There are several reasons to consider migrating from one root key to another. For instance, you might want to transition from an old AWS KMS configuration that was set up with an account you no longer wish to use. Alternatively, you may prefer to migrate to an entirely new KMS provider, potentially opting for a cloud-agnostic solution like HashiCorp Vault.
Updating the “root” key configuration
The first step is to update the existing root purpose KMS stanza to previous-root. This informs Boundary to use this key provided by the KMS for decrypting the existing data in the database. For instance, if you were using an AEAD KMS provider, the configuration might look like this:
kms "aead" {
purpose = "root"
purpose = "previous-root"
key_id = "your-existing-key-id"
... // other configuration parameters
}
This configuration ensures that Boundary can decrypt the existing database entries using the specified previous-root key during the transition to a new root key.
Adding a new root purpose KMS stanza
Next, add a new root purpose KMS stanza with the new KMS provider configuration and restart the controller. After the restart, Boundary will immediately begin using the new KMS provider for any newly created scopes. However, the existing scopes will still contain KEKs encrypted with the previous root key.
For example, if you are transitioning to a new KMS provider, your configuration might look like this:
kms "aead" {
purpose = "root"
key_id = "new-key-id"
... // other configuration parameters
}
This configuration ensures that any new scopes created after the controller restarts will use the new KMS provider, while old scopes will continue to function with their KEKs encrypted by the previous root key.
To address this, you need to rotate the keys in all the old scopes, ensuring to specify the rewrap option. This process will re-encrypt all the KEKs with the new root key.
$ boundary scopes rotate-keys -scope-id global -rewrap
$ boundary scopes rotate-keys -scope-id <org-id> -rewrap
$ boundary scopes rotate-keys -scope-id <project-id> -rewrap
You can now remove the previous-root purpose KMS stanza from the configuration file and restart Boundary again. By doing this, you’ve successfully migrated from one KMS provider to another.
References: