Verifying the contract

You can verify the contract by deploying a sample workload in the IBM Confidential Computing Containers.

This step must be performed by the Data Owner.

Assumptions

  • For demonstration purposes, the BusyBox workload is used to create and verify the contract.

Annotations

Annotations in the contract help the control how the confidential container runtime and hypervisor work. The Data Owner persona defines these values to customize the container's execution environment. The following annotations are supported:

  • io.katacontainers.config.hypervisor.default_vcpus: Specifies the default number of virtual CPUs (vCPUs) allocated to the confidential container.

    Example value: "3"

    This setting ensures that each container is provisioned with sufficient compute resources for secure workload execution.

    Note: For information about configuring CPU resources in your workload, see Configuring resources for workloads.
  • io.katacontainers.config.hypervisor.default_memory: Defines the default memory (in MB) allocated to the container.

    Example value: "9216"

    This helps guarantee that the container has adequate memory to run confidential workloads efficiently.

    Note: For information about configuring memory resources in your workload, see Configuring resources for workloads.
  • io.katacontainers.config.runtime.create_container_timeout: Sets the timeout duration (in seconds) for container creation.

    Example value: "900"

    This parameter ensures that container startup operations do not become unresponsive for extended periods. If the operations exceed the designated time limit, they will fail rather than hanging indefinitely.

  • io.katacontainers.config.hypervisor.cc_init_data: Provides initialization data required for confidential container setup.
    • InitData: Marks data as temporary and places it in a special memory section (.init.data) that is discarded after initialization. This helps reduce the memory footprint of the workload.

    Using these annotations ensures that sensitive or temporary data used for contract verification does not persist beyond the initialization phase, aligning with the security and efficiency goals of confidential computing.

Procedure

  1. Optional. For IBM CCCO Bare Metal deployments, if you are using encrypted persistent block volumes for your contract, perform the following steps:
    1. Set the PersistentVolumeClaim (PVC) name and device name variables:
      export STORAGE_PVC_NAME="sample-pvc-1"
      export DEVICE_NAME="pvb_storage"
      Note: For more information about setting up PVC, see Creating PersistentVolumeClaims for storage.
    2. Create the device path:
      export DEVICE_PATH="/dev/${DEVICE_NAME}"
      Note: The device path format /dev/<device_name> is used to reference the block device in the pod specification. This path is not directly accessible to the workload owner, as the volume is encrypted by IBM Confidential Computing Containers.
  2. Deploy a sample workload.
    • For the workload with initdata annotation, make sure to include the following annotation section in the workload.

      annotations:
        io.katacontainers.config.hypervisor.cc_init_data: ${initdata_annotation}

      The sample workload varies for different contracts. Based on the contract created, deploy the required workload from the following sections:

      • The sample workload that must be deployed to verify the basic contract is as follows:
        cat << EOF > busybox.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          labels:
            run: busybox
          name: busybox
          namespace: default
          annotations:
            io.katacontainers.config.hypervisor.default_vcpus : "3"
            io.katacontainers.config.hypervisor.default_memory: "9216"
            io.katacontainers.config.runtime.create_container_timeout: '900'
            io.katacontainers.config.hypervisor.cc_init_data: ${initdata_annotation}
        spec:
          containers:
          - image: quay.io/prometheus/busybox
            name: busybox
          restartPolicy: Never
          runtimeClassName: kata-cc
        EOF
      • The sample workload that must be deployed to verify the contract with the sealed secret is as follows:
        cat << EOF > busybox.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          labels:
            run: busybox
          name: busybox
          namespace: default
          annotations:
            io.katacontainers.config.hypervisor.default_vcpus : "3"
            io.katacontainers.config.hypervisor.default_memory: "9216"
            io.katacontainers.config.runtime.create_container_timeout: '900'
            io.katacontainers.config.hypervisor.cc_init_data: ${initdata_annotation}
        spec:
          containers:
          - image: quay.io/prometheus/busybox
            name: busybox
            volumeMounts:
            - mountPath: /tmp
              name: spoiler
          restartPolicy: Never
          runtimeClassName: kata-cc
          volumes:
          - name: spoiler
            secret:
              secretName: spoiler
        EOF
      • The sample workload that must be deployed to verify the contract with cosign verified container images is as follows:
        cat << EOF > busybox.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          name: busybox
          namespace: default
          labels:
            run: busybox
          annotations:
            io.katacontainers.config.hypervisor.default_vcpus : "3"
            io.katacontainers.config.hypervisor.default_memory: "9216"
            io.katacontainers.config.runtime.create_container_timeout: '900'
            io.katacontainers.config.hypervisor.cc_init_data: ${initdata_annotation}
        spec:
          runtimeClassName: kata-cc
          restartPolicy: Never
          containers:
          - name: busybox
            image: quay.io/<username>/busybox:latest
        EOF
      • The sample workload that must be deployed to verify the contract with volumes is as follows:
        cat << EOF > busybox.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          labels:
            run: busybox
          name: busybox
          namespace: default
          annotations:
            io.katacontainers.config.hypervisor.default_vcpus : "3"
            io.katacontainers.config.hypervisor.default_memory: "9216"
            io.katacontainers.config.runtime.create_container_timeout: '900'
            io.katacontainers.config.hypervisor.cc_init_data: ${initdata_annotation}
        spec:
          containers:
          - image: quay.io/prometheus/busybox
            name: busybox
            volumeDevices:
            - devicePath: ${DEVICE_PATH}
              name: block-pvc
          restartPolicy: Never
          runtimeClassName: kata-cc
          volumes:
          - name: block-pvc
            persistentVolumeClaim:
              claimName: ${STORAGE_PVC_NAME}
        EOF
      • The sample workload that must be deployed to verify the contract with multiple volumes is as follows:
        Note: Make sure to set device name and device path for all the devices if you are using multiple volumes.
        cat << EOF > busybox.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          labels:
            run: busybox
          name: busybox
          namespace: default
          annotations:
            io.katacontainers.config.hypervisor.default_vcpus : "3"
            io.katacontainers.config.hypervisor.default_memory: "9216"
            io.katacontainers.config.runtime.create_container_timeout: '900'
            io.katacontainers.config.hypervisor.cc_init_data: ${initdata_annotation}
        spec:
          containers:
          - image: quay.io/prometheus/busybox
            name: busybox
            volumeDevices:
            - devicePath: ${DEVICE_PATH1}
              name: block-pvc-1
            - devicePath: ${DEVICE_PATH2}
              name: block-pvc-2
          restartPolicy: Never
          runtimeClassName: kata-cc
          volumes:
          - name: block-pvc-1
            persistentVolumeClaim:
              claimName: ${STORAGE_PVC_NAME1}
          - name: block-pvc-2
            persistentVolumeClaim:
              claimName: ${STORAGE_PVC_NAME2}
        EOF
      • The sample workload that must be deployed to verify the contract with volumes and sealed secret is as follows:
        cat << EOF > busybox.yaml
        apiVersion: v1
        kind: Pod
        metadata:
          labels:
            run: busybox
          name: busybox
          namespace: default
          annotations:
            io.katacontainers.config.hypervisor.default_vcpus : "3"
            io.katacontainers.config.hypervisor.default_memory: "9216"
            io.katacontainers.config.runtime.create_container_timeout: '900'
            io.katacontainers.config.hypervisor.cc_init_data: ${initdata_annotation}
        spec:
          containers:
          - image: quay.io/prometheus/busybox
            name: busybox
            volumeMounts:
            - mountPath: /tmp
              name: spoiler
            volumeDevices:
            - devicePath: ${DEVICE_PATH}
              name: block-pvc
          restartPolicy: Never
          runtimeClassName: kata-cc
          volumes:
          - name: block-pvc
            persistentVolumeClaim:
              claimName: ${STORAGE_PVC_NAME}
          - name: spoiler
            secret:
              secretName: spoiler
        EOF
  3. Create the pod by running the following command:
    oc create -f busybox.yaml
  4. Check if BusyBox is running by running the following command:
    oc get pods | grep busybox
    Example output
    busybox   1/1     Running   0          101s
  5. Optional. For IBM CCCO Bare Metal deployments, if you are using encrypted persistent block volumes for your contract, perform the following verification steps:
    1. Verify the volume is mounted inside the container:
      oc exec busybox -- df -h

      The output must show the mounted volume at the mount point specified in the workload configuration (for example, /mnt/data1).

    2. Check the volume mount inside the container:
      Note: Make sure the ExecProcessRequest is set to true in the SamplePolicyPermissiveRules.rego to perform oc exec commands.
      Important: This configuration is recommended for development environments only. In production environments, execprocess must always be set to false for security reasons.
      oc exec busybox -- ls -la /mnt/data1
    3. Create a test file to verify write access:
      oc exec busybox -- touch /mnt/data1/test.txt
    4. Verify the file was created:
      oc exec busybox -- ls -la /mnt/data1/test.txt
    5. Delete the pod by running the following command:
      oc delete busybox -n default
    6. Create the pod by running the following command:
      oc create -f busybox.yaml
    7. Check if the test.txt exists by running the following command:
      oc exec busybox -- ls -la /mnt/data1/test.txt

      The file test.txt must be present without any errors.