|
| 1 | +# Operating system image and node lifecycle |
| 2 | + |
| 3 | +In Trusted Execution Clusters, every node is attested to run a bootable container image that has been set as an approved image by an administrator. |
| 4 | +An example of a bootc-compatible OS is the CoreOS family, which is also what Trusted Execution Clusters is tested with. |
| 5 | +Automatically retrieving references to approved images via Cluster API is a planned feature. |
| 6 | + |
| 7 | +# Approving a bootable container image for reference value inclusion |
| 8 | + |
| 9 | +For disambiguation reasons, all images must be referenced with a SHA digest. |
| 10 | +With the `ApprovedImage` custom resource, images can be set to be approved. |
| 11 | +Their reference values are computed, or taken from the `org.coreos.pcrs` label if present. |
| 12 | + |
| 13 | +```sh |
| 14 | +$ kubectl apply -f - <<EOF |
| 15 | +apiVersion: trusted-execution-clusters.io/v1alpha1 |
| 16 | +kind: ApprovedImage |
| 17 | +metadata: |
| 18 | + name: coreos |
| 19 | + namespace: trusted-execution-clusters |
| 20 | +spec: |
| 21 | + image: quay.io/trusted-execution-clusters/fedora-coreos@sha256:e71dad00aa0e3d70540e726a0c66407e3004d96e045ab6c253186e327a2419e5 |
| 22 | +EOF |
| 23 | + |
| 24 | +approvedimage.trusted-execution-clusters.io/coreos created |
| 25 | +$ kubectl get jobs |
| 26 | +NAME STATUS COMPLETIONS DURATION AGE |
| 27 | +compute-pcrs-66c22217c4-quay-io-trusted-execution-clusters-fedo Running 0/1 19s 19s |
| 28 | +$ # Wait for completion, job is auto-deleted upon success |
| 29 | +$ kubectl describe approvedimage coreos |
| 30 | +Name: coreos |
| 31 | +... |
| 32 | +Spec: |
| 33 | + Image: quay.io/trusted-execution-clusters/fedora-coreos@sha256:e71dad00aa0e3d70540e726a0c66407e3004d96e045ab6c253186e327a2419e5 |
| 34 | +Status: |
| 35 | + Conditions: |
| 36 | + Last Transition Time: 2025-11-27T18:05:12Z |
| 37 | + Message: |
| 38 | + Observed Generation: 1 |
| 39 | + Reason: ImageCommitted |
| 40 | + Status: True |
| 41 | + Type: Committed |
| 42 | +Events: <none> |
| 43 | +$ kubectl describe configmap trustee-data |
| 44 | +... |
| 45 | +reference-values.json: |
| 46 | +---- |
| 47 | +[{"version":"0.1.0","name":"tpm_pcr14","expiration":"2026-11-27T18:05:14Z","value":["17cdefd9548f4383b67a37a901673bf3c8ded6f619d36c8007562de1d93c81cc"]},{"version":"0.1.0","name":"tpm_pcr4","expiration":"2026-11-27T18:05:14Z","value":["551bbd142a716c67cd78336593c2eb3b547b575e810ced4501d761082b5cd4a8"]},{"version":"0.1.0","name":"tpm_pcr7","expiration":"2026-11-27T18:05:14Z","value":["b3a56a06c03a65277d0a787fcabc1e293eaa5d6dd79398f2dda741f7b874c65d"]},{"version":"0.1.0","name":"tpm_svn","expiration":"2026-11-27T18:05:14Z","value":["1"]}] |
| 48 | +... |
| 49 | +``` |
| 50 | + |
| 51 | +Machines booting this image can now register and attest. |
| 52 | + |
| 53 | +**NB:** Updating nodes is not supported yet. Updates incur one intermediary stage of PCR values (assuming no further update on that boot) because kernel update is effective one boot _before_ shim & GRUB update. |
| 54 | + |
| 55 | +# Disallowing a bootable container image |
| 56 | + |
| 57 | +For the example above: |
| 58 | + |
| 59 | +```sh |
| 60 | +$ kubectl delete approvedimage coreos |
| 61 | +approvedimage.trusted-execution-clusters.io "coreos" deleted |
| 62 | +$ kubectl describe configmap trustee-data |
| 63 | +... |
| 64 | +reference-values.json: |
| 65 | +---- |
| 66 | +[{"version":"0.1.0","name":"tpm_svn","expiration":"2026-11-27T18:07:46Z","value":["1"]}] |
| 67 | +... |
| 68 | +``` |
| 69 | + |
| 70 | +Subsequent boots on this image will fail. |
| 71 | + |
| 72 | +Ensure that all ApprovedImage objects that reference this image are removed. |
| 73 | +If two ApprovedImages approve the same image and only one is deleted, the image is considered approved just the same. |
| 74 | + |
| 75 | +# Registration of machines |
| 76 | + |
| 77 | +New machines register via the [register-server](/register-server), which generates a `Machine` custom resource with a UUID and disk encryption key per machine. |
| 78 | +This key can then be provided ("brokered") through Trustee. |
| 79 | +Registering machines through direct API interaction is possible, but unsupported. |
| 80 | + |
| 81 | +After such a registration, a Machine might look like: |
| 82 | + |
| 83 | +```sh |
| 84 | +$ kubectl get machines |
| 85 | +NAME AGE |
| 86 | +machine-316809b1-ea29-448c-accb-78c5c6bf5206 88s |
| 87 | +$ kubectl describe machine machine-316809b1-ea29-448c-accb-78c5c6bf5206 |
| 88 | +Name: machine-316809b1-ea29-448c-accb-78c5c6bf5206 |
| 89 | +... |
| 90 | +Spec: |
| 91 | + Id: 316809b1-ea29-448c-accb-78c5c6bf5206 |
| 92 | + Registration Address: 10.244.82.19 |
| 93 | +Events: <none> |
| 94 | +$ kubectl get secrets |
| 95 | +NAME TYPE DATA AGE |
| 96 | +316809b1-ea29-448c-accb-78c5c6bf5206 Opaque 1 2m10s |
| 97 | +``` |
| 98 | + |
| 99 | +# Deletion of machines |
| 100 | + |
| 101 | +Machines can be deleted if no longer needed: |
| 102 | + |
| 103 | +```sh |
| 104 | +$ kubectl delete machine machine-316809b1-ea29-448c-accb-78c5c6bf5206 |
| 105 | +machine.trusted-execution-clusters.io "machine-316809b1-ea29-448c-accb-78c5c6bf5206" deleted |
| 106 | +$ kubectl get secrets |
| 107 | +No resources found in test-c54e805f namespace. |
| 108 | +``` |
| 109 | + |
| 110 | +The secret is owned by the Machine object and thus deleted when the Machine is deleted. |
| 111 | +This prevents the node from booting again unless it was configured to re-register by someone controlling the node. |
0 commit comments