Skip to content

Commit

Permalink
tests: add test for sealed secrets
Browse files Browse the repository at this point in the history
The sealed secret test depends on the KBS to provide
the unsealed value of a vault secret.

This secret is provisioned to an environment variable
and to filestystem of the workload container.

Signed-off-by: Tobin Feldman-Fitzthum <tobin@ibm.com>
  • Loading branch information
fitzthum committed May 25, 2024
1 parent f3660d4 commit aecc63e
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 0 deletions.
99 changes: 99 additions & 0 deletions tests/integration/kubernetes/k8s-sealed-secret.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env bats
# Copyright 2024 IBM Corporation
# Copyright 2024 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
# Test for Sealed Secret feature of CoCo
#

load "${BATS_TEST_DIRNAME}/lib.sh"
load "${BATS_TEST_DIRNAME}/confidential_common.sh"
load "${BATS_TEST_DIRNAME}/confidential_kbs.sh"

export KBS="${KBS:-false}"
export KATA_HYPERVISOR="${KATA_HYPERVISOR:-qemu}"
export AA_KBC="${AA_KBC:-cc_kbc}"

setup() {
[ "${KATA_HYPERVISOR}" = "qemu-tdx" ] && skip "Test not ready yet for ${KATA_HYPERVISOR}"
is_confidential_runtime_class || skip "Test not supported for ${KATA_HYPERVISOR}."

if [ "${KBS}" = "false" ]; then
skip "Test skipped as KBS not setup"
fi

setup_common
get_pod_config_dir

export K8S_TEST_YAML="${pod_config_dir}/pod-sealed-secret.yaml"
# Schedule on a known node so that later it can print the system's logs for
# debugging.
set_node "$K8S_TEST_YAML" "$node"

kbs_set_resource "default" "sealed-secret" "test" "unsealed_secret"
local CC_KBS_ADDR
export CC_KBS_ADDR=$(kbs_k8s_svc_http_addr)
kernel_params_annotation="io.katacontainers.config.hypervisor.kernel_params"
kernel_params_value=""

# For now we set aa_kbc_params via kernel cmdline
if [ "${AA_KBC}" = "cc_kbc" ]; then
kernel_params_value+=" agent.aa_kbc_params=cc_kbc::${CC_KBS_ADDR}"
fi
set_metadata_annotation "${K8S_TEST_YAML}" \
"${kernel_params_annotation}" \
"${kernel_params_value}"

# Setup k8s secret
kubectl delete secret sealed-secret --ignore-not-found

# Sealed secret format is defined at: https://github.com/confidential-containers/guest-components/blob/main/confidential-data-hub/docs/SEALED_SECRET.md#vault
# sealed.BASE64URL(UTF8(JWS Protected Header)) || '.
# || BASE64URL(JWS Payload) || '.'
# || BASE64URL(JWS Signature)
# test payload:
# {
# "version": "0.1.0",
# "type": "vault",
# "name": "kbs:///default/sealed-secret/test",
# "provider": "kbs",
# "provider_settings": {},
# "annotations": {}
# }
kubectl create secret generic sealed-secret --from-literal='password=sealed.fakejwsheader.ewogICAgInZlcnNpb24iOiAiMC4xLjAiLAogICAgInR5cGUiOiAidmF1bHQiLAogICAgIm5hbWUiOiAia2JzOi8vL2RlZmF1bHQvc2VhbGVkLXNlY3JldC90ZXN0IiwKICAgICJwcm92aWRlciI6ICJrYnMiLAogICAgInByb3ZpZGVyX3NldHRpbmdzIjoge30sCiAgICAiYW5ub3RhdGlvbnMiOiB7fQp9Cg==.fakesignature'
}

@test "Unseal Secrets with CDH" {
kbs_set_allow_all_resources
kubectl apply -f "${K8S_TEST_YAML}"

# Retrieve pod name, wait for it to come up, retrieve pod ip
export pod_name=$(kubectl get pod -o wide | grep "secret-test-pod-cc" | awk '{print $1;}')

# Check pod creation
kubectl wait --for=condition=Ready --timeout="$timeout" pod "${pod_name}"

kubectl logs secret-test-pod-cc
kubectl logs secret-test-pod-cc | grep -q "unsealed environment as expected"
kubectl logs secret-test-pod-cc | grep -q "unsealed volume as expected"
}

teardown() {
[ "${KATA_HYPERVISOR}" = "qemu-tdx" ] && skip "Test not ready yet for ${KATA_HYPERVISOR}"
is_confidential_runtime_class || skip "Test not supported for ${KATA_HYPERVISOR}."

if [ "${KBS}" = "false" ]; then
skip "Test skipped as KBS not setup"
fi

[ -n "${pod_name:-}" ] && kubectl describe "pod/${pod_name}" || true
[ -n "${pod_config_dir:-}" ] && kubectl delete -f "${K8S_TEST_YAML}" || true

if [ -n "${node_start_time}:-}" ]; then
echo "DEBUG: system logs of node '$node' since test start time ($node_start_time)"
print_node_journal "$node" "kata" --since "$node_start_time" || true
fi

kubectl delete secret sealed-secret --ignore-not-found
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright (c) 2023 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod-cc
spec:
runtimeClassName: kata
containers:
- name: busybox
image: quay.io/prometheus/busybox:latest
imagePullPolicy: Always
command:
- sh
- -c
- |
env
if [ "$SECRET_PASSWORD" == "unsealed_secret" ]; then
echo "unsealed environment as expected"
fi
if [ -f /tmp/secret-volume/password ]; then
content=$(cat /tmp/secret-volume/password)
if [ "$content" == "unsealed_secret" ]; then
echo "unsealed volume as expected";
fi
fi
sleep 1000
# Expose secret data Containers through environment.
env:
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: sealed-secret
key: password
volumeMounts:
# name must match the volume name below
- name: secret-volume
mountPath: /tmp/secret-volume
# Expose secret data Containers through a volume.
volumes:
- name: secret-volume
secret:
secretName: sealed-secret

0 comments on commit aecc63e

Please sign in to comment.