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.

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