Leveraging Remote Attestation to protect the Pod sensitive configuration
The primary way to protect a Pod’s sensitive data is by using encrypted configurations (see Providing secrets to the AWS Nitro Enclave for further details).
The Anjuna Kubernetes Toolset for AWS EKS tools supports two methods to provide an encrypted configuration to a Confidential Container that runs in EKS.
One method supports S3 Encrypted Configurations out of the box. Therefore, any pre-built EIF that uses an S3 Encrypted Configuration can be used as a Pod image without further modifications.
A second method supports providing a Local Encrypted Configuration to the enclave running in the Pod. This allows different launches of the same enclave, based on the same EIF, to use different secrets. Some examples include the following:
-
If different users of the Pod have different secrets that they want to pass to it
-
If the same EIF should be used for different execution environments (such as Dev, Test, and Prod)
By changing the specific encrypted Configuration
provided to the enclave, different secrets may be injected.
This requires that the Local Encrypted Configuration be available to the launcher Pod,
and for the launcher Pod to know where it is.
With this information,
the launcher Pod will provide the Local Encrypted Configuration to the enclave,
as if running it with
the --encrypted-config
flag.
Configuring the Pod to use a Local Encrypted Configuration
To tell the launcher Pod where the Local Encrypted Configuration is,
use the nitro.k8s.anjuna.io/encryptedConfigLocation
annotation. For example:
apiVersion: v1
kind: Pod
metadata:
name: secret-enabled-pod
labels:
name: secret-enabled-pod
nitro.k8s.anjuna.io/managed: "yes"
annotations:
nitro.k8s.anjuna.io/encryptedConfigLocation: "/path/on/the/pod/filesystem"
<snip>...
This path must be an absolute filesystem path, and point to the specific Local Encrypted Configuration that should be provided to the enclave. |
Providing the Local Encrypted Configuration to the Pod
The Local Encrypted Configuration must be present on the Pod’s file system, for it to be served to the enclave. There are many ways of doing so. Following are some suggestions:
-
Create a Kubernetes Secret or ConfigMap containing the Encrypted Configuration.
-
Create a Persistent Volume containing the Encrypted Configuration, and expose it to the Pod using a Persistent Volume Claim.
-
Upload the Encrypted Configuration to some file store (such as S3), and add an init container that will download it and pass it to the launcher Pod.
It is very likely that the preferred approach will involve a volume mount
that needs to be passed to the launcher Pod.
By default,
the Anjuna Kubernetes Toolset for AWS EKS transforms any volume mount to a basic
enclave mount, which will be available inside the enclave.
This is undesirable in this case,
as the volume mount is designated to the launcher Pod,
and not the enclave itself.
To avoid this behavior,
set the volume name to start with anjuna-system
, e.g. anjuna-system-encrypted-conf
.
Example
Below is an example of how to provide and use a Local Encrypted Configuration in Anjuna Kubernetes Toolset for AWS EKS. This example uses a Kubernetes Secret to provide the Local Encrypted Config to the launcher Pod, but as mentioned, any other solution that provides the file to the launcher will work. This example relies on the example in Providing secrets to the AWS Nitro Enclave, specifically the example for Local Encrypted Configurations.
Before continuing, follow the examples to Create a Local Encrypted Configuration, Build an enclave that would use it, and Authorize the Enclave to access it.
This should produce two files: an EIF, and an Encrypted Configuration.
Declare the following environment variables:
$ export EIF_PATH=<path to EIF>
$ export ENCRYPTED_CONFIG_PATH=<path to Local Encrypted Configuration>
$ export EIF_S3_DIRECTORY=<s3://... s3 directory where the EIF can be uploaded to>
First upload the EIF to the S3 directory:
$ aws s3 cp ${EIF_PATH} ${EIF_S3_DIRECTORY}/example.eif
Second, create a Kubernetes Secret from the Local Encrypted Config:
$ kubectl create secret generic example-encrypted-conf --from-file=encrypted.conf=${ENCRYPTED_CONFIG_PATH}
Finally, deploy the Pod using the deployment:
$ cat > pod_deployment.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: encrypted-conf-env-pod
labels:
name: encrypted-conf-env-pod
nitro.k8s.anjuna.io/managed: "yes"
annotations:
nitro.k8s.anjuna.io/imageLocation: "${EIF_S3_DIRECTORY}/example.eif"
nitro.k8s.anjuna.io/encryptedConfigLocation: "/anjuna/files/confs/encrypted.conf"
spec:
containers:
- name: encrypted-conf-env
image: DOES-NOT-MATTER
imagePullPolicy: Always
resources:
limits:
memory: "2048Mi"
cpu: "2"
volumeMounts:
- name: anjuna-system-encrypted-conf
mountPath: "/anjuna/files/confs"
readOnly: true
volumes:
- name: anjuna-system-encrypted-conf
secret:
secretName: example-encrypted-conf
EOF
kubectl apply -f pod_deployment.yaml
Notice that the volume name has the required anjuna-system
prefix.
You can see that the Pod was launched correctly, and that the enclave received the configuration by running:
$ kubectl logs encrypted-conf-env-pod
To tear down this example, run:
$ kubectl delete -f pod_deployment.yaml
$ kubectl delete secret example-encrypted-conf
$ aws s3 rm ${EIF_S3_DIRECTORY}/example.eif