apiVersion: v1
kind: Pod
metadata:
  name: encrypted-image-credentials
  # setup.sh fills in the namespace, the Region, the KMS key ARN and the wrapped layer
  # key at apply time.
  labels:
    app.kubernetes.io/name: encrypted-image-credentials
    app.kubernetes.io/managed-by: encrypted-image
    # Deliberately not app: encrypted-image. This pod is not the sandbox, so the
    # sandbox's egress policy does not govern it: it reaches AWS KMS the ordinary way,
    # which is the point. What stops it is the key policy, not the network.
  annotations:
    karpenter.sh/do-not-disrupt: "true"
spec:
  # No runtimeClassName: an ordinary pod. It stands for anyone who holds the pod's AWS
  # credentials without being the attested sandbox, which in confidential mode includes
  # the node itself: the parent instance can obtain the same Pod Identity credentials the
  # workload uses, either by reading them as they are delivered or by minting them from
  # the kubelet's own credentials and the node role (Amazon EKS User Guide, "Security
  # model and parent instance trust assumptions").
  #
  # It uses the SAME service account as the sandboxed pod, so EKS Pod Identity hands it
  # the SAME IAM role, and it asks AWS KMS to decrypt the SAME wrapped layer key read out
  # of the published image. The only thing it does not have is an attestation document.
  serviceAccountName: encrypted-image-pod
  automountServiceAccountToken: false
  enableServiceLinks: false
  terminationGracePeriodSeconds: 0
  securityContext:
    runAsUser: 65534
    runAsGroup: 65534
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  volumes:
    # The AWS CLI writes a cache under HOME, and the root filesystem is read-only.
    - name: home
      emptyDir: {}
  containers:
    - name: main
      # The AWS CLI image, because this pod has to make a real KMS request. The sandboxed
      # pod's own image carries no AWS or KMS code at all, which is one of the things the
      # page shows: the layer decryption is the guest's job, not the workload's.
      image: public.ecr.aws/aws-cli/aws-cli:2.31.19
      imagePullPolicy: IfNotPresent
      env:
        - name: AWS_REGION
          value: <AWS_REGION>
        - name: AWS_DEFAULT_REGION
          value: <AWS_REGION>
        - name: HOME
          value: /home/aws
        # Fail a call that cannot reach AWS quickly, so a retry below comes round again in
        # seconds rather than minutes. The answer this pod is after is an authorization
        # decision, and the CLI's long default retry budget only delays reaching it.
        - name: AWS_MAX_ATTEMPTS
          value: "2"
        - name: KMS_KEY_ARN
          value: <KMS_KEY_ARN>
        # The base64 ciphertext of the image's wrapped layer key, read out of the
        # published image's own layer annotation. Anyone who can read the registry
        # already holds it; the sample's claim is that it is useless without an
        # attestation document the key policy accepts.
        - name: WRAPPED_LAYER_KEY
          value: <WRAPPED_LAYER_KEY>
      # Writes the plaintext, if KMS ever returned any, to a file and deletes it without
      # reading it, so a layer key could not reach the logs even if the gate failed. What
      # the page reads is the exit status and the error.
      #
      # The request is retried, because a pod's datapath can take a few seconds to settle
      # after it starts and a connection that never reaches KMS is not an answer about
      # the key policy. The loop stops as soon as the answer is a real one: either an
      # authorization denial, or a success (which would mean the gate had failed).
      #
      # Both sed expressions are there so nothing in the output identifies the account or
      # the cluster: KMS names the full role session in its error, and an EKS Pod Identity
      # session name is built from the cluster and pod names.
      command:
        - /bin/sh
        - -c
        - >-
          redact() { sed -e 's/[0-9]\{12\}/<ACCOUNT_ID>/g' -e 's|\(assumed-role/[^/]*/\)[^ "]*|\1<session>|g'; };
          aws_fast() { aws --cli-connect-timeout 5 --cli-read-timeout 15 "$@"; };
          sleep 75;
          echo "role:    $(aws_fast sts get-caller-identity --query Arn --output text 2>/dev/null | redact)";
          echo "request: kms:Decrypt on the image's wrapped layer key, with no attestation document";
          printf '%s' "$WRAPPED_LAYER_KEY" | base64 -d > "$HOME/wrapped-layer-key.bin";
          rc=0;
          for attempt in $(seq 8); do
          rc=0;
          aws_fast kms decrypt --key-id "$KMS_KEY_ARN" --ciphertext-blob "fileb://$HOME/wrapped-layer-key.bin"
          --query Plaintext --output text > "$HOME/plaintext" 2> "$HOME/error" || rc=$?;
          rm -f "$HOME/plaintext";
          if [ "$rc" = 0 ]; then break; fi;
          if grep -Eiq 'AccessDenied|not authorized|explicit deny' "$HOME/error"; then break; fi;
          echo "retry:   attempt $attempt reached no decision, retrying";
          sleep 10;
          done;
          echo "exit:    $rc";
          redact < "$HOME/error";
          echo encrypted-image-credentials-done;
          exec sleep 3600
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL
      volumeMounts:
        - name: home
          mountPath: /home/aws
      resources:
        requests:
          cpu: 100m
          memory: 256Mi
