The "root" identifier is how we identify the root key in configuration, so it is the phrase we should use in this documentation.
169 lines
7.8 KiB
Plaintext
169 lines
7.8 KiB
Plaintext
---
|
|
layout: docs
|
|
page_title: Data Encryption
|
|
description: |-
|
|
How Boundary secures data at rest
|
|
---
|
|
|
|
# Data Security in Boundary
|
|
|
|
Boundary has multiple mechanisms to ensure secure end-to-end behavior of the
|
|
system. A key part of this is [support for various Key Management
|
|
Systems](/docs/configuration/kms) that protect the base encryption keys used
|
|
for various functions. This page describes the various KMS key purposes that
|
|
Boundary supports and how they are used within the system.
|
|
|
|
## The `worker-auth-storage` KMS Key
|
|
|
|
The `worker-auth-storage` KMS key is used by a [PKI
|
|
Worker](/docs/configuration/worker/pki-worker) for storage of authentication
|
|
keys. It is optional for PKI workers; if not specified the authentication keys
|
|
will not be encrypted on disk. This is not used by KMS workers.
|
|
|
|
## The `root` KMS Key and Per-Scope KEK/DEKs <sup>OSS Only</sup>
|
|
|
|
Following best practices of using different encryption keys for different
|
|
purposes, Boundary has a number of encryption keys generated within each scope.
|
|
Each key further contains versions, which hold the key material used to encrypt
|
|
data. You can create new key versions by _rotating_ the keys. A key version
|
|
can be destroyed, which will re-encrypt any existing data before destroying the
|
|
key material permanently.
|
|
|
|
The `root` KMS key acts as a KEK (Key Encrypting Key) for the scope-specific
|
|
KEKs (also referred to as the scope's `root` key). The scope's `root` KEK
|
|
and the various DEKs (Data Encryption Keys) are created when a scope is created.
|
|
The DEKs are encrypted with the scope's `root` KEK, and this is in turn
|
|
encrypted with the KMS key marked for the `root` purpose.
|
|
|
|
The current 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](/docs/configuration/events).
|
|
|
|
- `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.
|
|
|
|
### Key version lifecycle Management
|
|
|
|
You can control the lifecycles of the per-scope KEK and DEKs via the CLI or
|
|
API using the key endpoints under the scopes section. To rotate all the keys
|
|
in a scope, use the `rotate-keys` endpoint:
|
|
|
|
```shell-session
|
|
$ boundary scopes rotate-keys -scope-id p_A4jfDjZ9jf
|
|
```
|
|
|
|
This endpoint creates new key versions for all keys in the scope
|
|
`p_A4jfDjZ9jf`, and makes these key versions the active key versions for
|
|
encrypting new data. The previous key version(s) will continue to be used for
|
|
decrypting existing data. You can use the `-rewrap` flag to immediately rewrap
|
|
all DEK versions with the new KEK version. Otherwise, the DEK versions remain
|
|
encrypted by the prior KEK version from when they were created.
|
|
|
|
To list all keys in a scope and their versions, use the `list-keys` endpoint:
|
|
|
|
```shell-session
|
|
$ boundary scopes list-keys -scope-id p_A4jfDjZ9jf
|
|
```
|
|
|
|
To destroy a key version, use the `destroy-key-version` endpoint:
|
|
|
|
```shell-session
|
|
$ boundary scopes destroy-key-version -scope-id p_A4jfDjZ9jf -key-version-id kdkv_tr6ZN8opYr
|
|
```
|
|
|
|
The latest key version cannot be destroyed, so if you want to destroy the
|
|
latest key version, you will need to call the `rotate-keys` endpoint first,
|
|
to create a new set of key versions. The `oplog` purpose key versions also
|
|
cannot be destroyed at this time.
|
|
|
|
Destroying a key version sometimes requires background work before it can be
|
|
completed. This is because DEK versions that currently encrypt data
|
|
necessitate re-encrypting that data with the latest DEK version for each
|
|
purpose before they can be deleted. You can monitor the progress of this
|
|
re-encryption job via the `list-key-destruction-jobs` endpoint:
|
|
|
|
```shell-session
|
|
$ boundary scopes list-key-version-destruction-jobs -scope-id p_A4jfDjZ9jf
|
|
```
|
|
|
|
Once the job disappears from this list, the associated key version will have
|
|
been destroyed and any existing data will have been re-encrypted.
|
|
|
|
## The `previous-root` KMS key <sup>OSS Only</sup>
|
|
|
|
The `previous-root` KMS key is used when migrating to a new `root` key. Adding
|
|
the `previous-root` KMS key to your configuration informs the Controller to use
|
|
it for decrypting the existing information in the database, allowing you to
|
|
rotate and rewrap the KEKs to complete the migration to the new root key.
|
|
|
|
## The `worker-auth` KMS Key <sup>OSS Only</sup>
|
|
|
|
The `worker-auth` KMS key is a key shared by the Controller and Worker in order
|
|
to authenticate a Worker to the Controller. Specifics of this mechanism can be
|
|
found on the [Connections/TLS page](/docs/concepts/security/connections-tls). If
|
|
a worker is used with [PKI
|
|
authentication](/docs/configuration/worker/pki-worker) this is unnecessary.
|
|
|
|
## The `recovery` KMS Key <sup>OSS Only</sup>
|
|
|
|
The `recovery` KMS key is used for rescue/recovery operations that can be used
|
|
by a client to authenticate almost any operation within Boundary. Its mechanism
|
|
of operation is very similar to the `worker-auth` flow in terms of using a
|
|
shared KMS between the client and the Controller for authentication. A nonce and
|
|
creation time are included as an encrypted payload, formatted as a token and
|
|
sent to the Controller. The time and nonce are used to ensure that a value
|
|
cannot be replayed by an adversary, and also to ensure that each operation must
|
|
be individually authenticated by a client so that revoking access to the KMS has
|
|
an immediate result.
|
|
|
|
~> **Note:** It is not required for this `kms` configuration block to exist in the
|
|
Controller's configuration file. It's best practice 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 will show a user of `u_recovery`. This
|
|
mechanism _cannot_ be used to authorize a session, as there is no uniquely
|
|
identifying user information available.
|
|
|
|
There are some other situations where this mechanism can be useful. For example,
|
|
it is possible to use this mechanism, along with some defaults in the Terraform
|
|
provider, to ensure that _everything_ in Boundary is created through Terraform,
|
|
with the exception of resources that cannot themselves be deleted. (This
|
|
consists of built-in anonymous (`u_anon`), authenticated (`u_auth`), and
|
|
recovery (`u_recovery`) users and the `global` scope.). By initializing Boundary
|
|
with the options to skip creating default resources, Terraform can be used to
|
|
create the specific resources needed instead, with the `recovery` KMS used to
|
|
authenticate setting up the initial auth method(s).
|
|
|
|
## The `config` KMS Key <sup>OSS Only</sup>
|
|
|
|
This key can be used to encrypt values within Boundary's configuration file. By
|
|
sharing this block between Boundary and an operator, the operator can put
|
|
sensitive or secret values (such as cloud API keys for KMSes) in Boundary's
|
|
configuration file, run `boundary config encrypt` to encrypt the file, and then
|
|
safely pass the file to a change control system. Only another operator or system
|
|
with access to that KMS can decrypt the values. Boundary will check for a
|
|
`config` KMS block on startup, and if it exists, will use it to decrypt any
|
|
encrypted values found at startup time.
|