-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
097a266
commit f104bd7
Showing
1 changed file
with
82 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# RFC 009: Secure PV Injection | ||
|
||
## Objective | ||
|
||
Setting up an encrypted volume mount using the `cryptsetup` container should be | ||
automated during `contrast generate`. This can be done similar to injecting the | ||
Initializer and Service Mesh components. | ||
|
||
## Problem Statement | ||
|
||
Contrast provides deployments with a shared workload secret which can be used to | ||
setup an encrypted volume mount. This is useful for storing persistent sensitive | ||
data (see [RFC 007](007-shared-workload-secret.md)). Currently, the process of | ||
setting up an encrypted volume mount is by manually setting up an additional | ||
init container running the `cryptsetup` subcommand of the Initializer as | ||
described in the | ||
[docs](https://docs.edgeless.systems/contrast/next/architecture/secrets). This | ||
can be automated and made more user-friendly by automatically generating the | ||
necessary YAML for the encrypted volume mount during `contrast generate`. This | ||
includes a Persistent Volume Claim, an `EmptyDir` volume used for the shared | ||
state, and the necessary volume mounts in the Initializer init container. | ||
|
||
## Proposal | ||
|
||
A new annotation `contrast.edgeless.systems/secure-pv-name` will be introduced | ||
which specifies the name of the shared `EmptyDir` volume which will be used to | ||
provide the decrypted state of the PV. If the annotation is set, this PV will | ||
be used by the Initializer to setup an encrypted mount. To use the encrypted | ||
volume, it needs to be mounted in the workload containers manually. The | ||
annotation `contrast.edgeless.systems/secure-pv-size` can be used to specify the | ||
size of the PV. If the annotation isn't set, the default size of 1Gi will be | ||
used. | ||
|
||
Currently, the Initializer uses the `cryptsetup` subcommand to setup an | ||
encrypted volume. The container running the `cryptsetup` subcommand is running | ||
separately from the Initializer container which attest to the Coordinator and | ||
writes the Contrast secrets. Injecting the `cryptsetup` logic into the YAML, we | ||
can simplify the process by: | ||
- Running the `cryptsetup` subcommand in the same container as the Initializer | ||
container. | ||
- Deciding whether to quit the container after writing the secrets or to | ||
continue with the `cryptsetup` and keep running. | ||
|
||
In case the Initializer keeps running, we need a startup probe to check if the | ||
`cryptsetup` is done. If the Initializer quits after writing the secrets, we can | ||
skip the startup probe. The Initializer will decide whether to quit or to keep | ||
running based on the environment variable `CRYPTSETUP_DEVICE` which will be set | ||
if the corresponding annotation is set. By default, this argument is then set to | ||
`/dev/csi0` and the Initializer will mount the PV to this device. The `EmptyDir` | ||
volume specified by the `contrast.edgeless.systems/secure-pv-name` annotation | ||
will be mounted to `/state` to complete the setup. | ||
|
||
To summarize: if the `contrast.edgeless.systems/secure-pv-name` annotation is | ||
set, the following changes will be made to the YAML: | ||
- A PVC with the name `state` will be added to the resource with size specified | ||
by `contrast.edgeless.systems/secure-pv-size` or 1Gi by default. | ||
- An `EmptyDir` volume will be added to the resource with the specified name | ||
from the annotation. | ||
- The Initializer `securityContext` will be updated to `privileged` to allow | ||
mounting block devices. | ||
- The Initializer container will mount the `EmptyDir` volume to `/state` and the | ||
PV to `/dev/csi0`. | ||
- The Initializer environment variables will be updated to include | ||
`CRYPTSETUP_DEVICE=/dev/csi0`. | ||
- The Initializer will have a startup probe to check if the `cryptsetup` is | ||
done, new resource limits as well as a restart policy of `Always`. | ||
|
||
Skipping the `cryptsetup` injection can be done by skipping the Initializer | ||
injection altogether. In this case, if a user wants to manually configure the | ||
encrypted PV, all resources and volume mounts need to be created manually, | ||
including the environment variables for the Initializer. If the Initializer is | ||
skipped using the `contrast.edgeless.systems/skip-initializer` annotation or the | ||
`--skip-initializer` flag, the `contrast.edgeless.systems/secure-pv-name` | ||
annotation will be ignored. Skipping the `cryptsetup` injection by simply not | ||
providing a `contrast.edgeless.systems/secure-pv-name` annotation won't work, | ||
since the Initializer will be replaced on `contrast generate` and the | ||
`CRYPTSETUP_DEVICE` environment variable won't be set. | ||
|
||
With this change, there is no longer any need for the `cryptsetup` subcommand to | ||
be specified through the `cobra` library, as everything now happens in one | ||
container. The `cryptsetup` subcommand can be removed and replaced by internal | ||
decision making in the Initializer. |