Skip to content

Commit 50d482c

Browse files
committed
docs: add reference for the manifest
1 parent db01f9b commit 50d482c

File tree

11 files changed

+287
-160
lines changed

11 files changed

+287
-160
lines changed

docs/docs/architecture/attestation/overview.md

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,20 @@ This guarantees that the CVM launches in a well-defined state and enforces only
3939

4040
The Coordinator runs inside a CVM and verifies attestation reports from other pods. It:
4141

42-
- Checks launch measurements and initdata hashes against a trusted **manifest**
42+
- Checks attestation reports, including the initdata hash, against a trusted [manifest](../components/manifest.md)
4343
- Issues service mesh certificates to verified pods
44-
- Functions as the verifier for the full deployment
45-
46-
<!-- TODO(burgerdev): below manifest information should go into a dedicated page -->
47-
48-
The **manifest** is a JSON configuration that defines the trusted state of the deployment. It includes:
49-
50-
- **ReferenceValues**: Expected CVM launch measurements
51-
- **Policies**: Hashes of permitted initdata documents
52-
- **WorkloadOwnerKeyDigests**: Public key digests used to authorize future manifest updates
53-
- **SeedshareOwnerPubKeys**: Used for securely recovering workload secrets and restoring trust
5444

5545
Only pods whose attestation evidence matches the manifest are accepted into the trusted service mesh.
46+
The Coordinator is verifier for all workloads of a Contrast deployment and issues certificates as attestation result, is therefore the certificate authority for a deployment.
5647

5748
The Contrast Coordinator itself also runs as a confidential pod and is attested using the Contrast CLI.
5849
The CLI includes embedded reference values for the Coordinator, allowing it to verify the Coordinator's identity and integrity during attestation.
5950
Because these reference values are part of the CLI build, the CLI effectively serves as the root of trust for the deployment.
6051
Verifying the CLI’s integrity and authenticity is therefore essential.
6152

53+
The verification of the Coordinator by the CLI enables trust in the Coordinator to verify other workloads based on the manifest.
54+
The workloads are then _attested transitively_ through the Coordinator.
55+
6256
### Relying party: Operator and data owner
6357

6458
The Contrast CLI is used by operators or data owners to verify the deployment and establish trust. It:

docs/docs/architecture/components/coordinator.md

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,6 @@ As your app needs to scale, the Coordinator transparently verifies new instances
1212
To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment.
1313
A third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity.
1414

15-
## The Manifest
16-
17-
The manifest is the configuration file for the Coordinator, defining your confidential deployment.
18-
It's automatically generated from your deployment by the Contrast CLI.
19-
It currently consists of the following parts:
20-
21-
<!-- TODO(burgerdev): explain manifest on separate page. -->
22-
23-
- _Policies_: The identities of your Pods, represented by the hashes of their respective initdata documents.
24-
- _Reference Values_: The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods.
25-
- _WorkloadOwnerKeyDigest_: The workload owner's public key digest. Used for authenticating subsequent manifest updates.
26-
- _SeedshareOwnerKeys_: public keys of seed share owners. Used to authenticate user recovery and permission to handle the secret seed.
27-
28-
Setting a manifest where the `WorkloadOwnerKeyDigest` has been removed will render the deployment [immutable](../../howto/immutable-deployments.md).
29-
Doing the same for the `SeedshareOwnerKeys` field makes Coordinator recovery and workload secret recovery impossible.
30-
3115
## Manifest history
3216

3317
The Coordinator uses Kubernetes `ConfigMap`s to store the manifest history and associated initdata documents.
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
# The manifest
2+
3+
The manifest is the configuration file for the Coordinator, defining your confidential deployment.
4+
It's automatically generated from your deployment by the Contrast CLI and uses JSON format (`manifest.json`).
5+
6+
## `Policies`
7+
8+
The identities of your Pods, represented by the hashes of their respective initdata documents.
9+
10+
### `Policies.*.SANs` {#policies-sans}
11+
12+
The Coordinator will add the Subject Alternative Names (SANs) to the workload certificate for the workload with the respective policy hash after verification.
13+
Allowed values are:
14+
15+
- IP addresses
16+
- URIs
17+
- DNS names
18+
19+
By default, the Contrast CLI will add two SANs for each workload on generate: The pod name as DNS name under which the pod can be reached inside the cluster, and a wildcard DNS name `*` to allow the certificate to be used with any other hostname (for example an external load balancer).
20+
As DNS is untrusted in the context of Contrast, issuing a wildcard certificate won't weaken the security of your workload.
21+
22+
To enable IP-based certificate verification, insert the desired IP address into the list of SANs.
23+
The change could look like this:
24+
25+
```diff
26+
"Policies": {
27+
...
28+
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": {
29+
"SANs": [
30+
"web",
31+
- "*"
32+
+ "*",
33+
+ "203.0.113.34"
34+
],
35+
},
36+
```
37+
38+
Some authentication and authorization schemes rely on URI SANs in X.509 certificates.
39+
For example, [SPIFFE IDs] are URIs and are often found as certificate SANs.
40+
The change to add such an URI SAN to the manifest could look like this:
41+
42+
```diff
43+
"Policies": {
44+
...
45+
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": {
46+
"SANs": [
47+
"web",
48+
- "*"
49+
+ "*",
50+
+ "spiffe://acme.com/billing/payments"
51+
],
52+
},
53+
```
54+
55+
[SPIFFE IDs]: https://spiffe.io/docs/latest/spiffe-about/spiffe-concepts/#spiffe-id
56+
57+
### `Policies.*.WorkloadSecretID` {#policies-workload-secret-id}
58+
59+
The `WorkloadSecretID` is used in addition to the secret seed to derive the workload secret.
60+
It's a non-interpreted string and defaults to the qualified Kubernetes resource name of the pod.
61+
As long as the `WorkloadSecretID` remains unchanged, the derived workload secret will remain stable across manifest updates and Coordinator recovery.
62+
63+
See [Workload secrets](../secrets.md#workload-secrets) for more information.
64+
65+
### `Policies.*.Role`
66+
67+
Contrast role assigned to the workload.
68+
The only supported value is `coordinator`, which identifies the Coordinator within the manifest.
69+
Workloads don't set this field.
70+
71+
## `ReferenceValues`
72+
73+
The remote attestation reference values for the confidential micro-VM that's the runtime environment of your Pods.
74+
The reference values cover both the platform configuration as well as the guest TCB.
75+
They're independent from the workload executed inside the Contrast pod VM and only differ between platforms or Contrast versions.
76+
77+
The reference values are grouped by confidential computing technology, there is a `snp` and a `tdx` section.
78+
Each of those sections contains a list of reference value sets.
79+
The Coordinator will accept a workload if its attestation report matches _any_ of the listed reverence value sets exactly.
80+
81+
### `ReferenceValues.snp.*.ProductName` {#snp-product-name}
82+
83+
The product name of your platform.
84+
`Milan` and `Genoa` are supported by Contrast.
85+
86+
### `ReferenceValues.snp.*.TrustedMeasurement` {#snp-trusted-measurement}
87+
88+
The `TrustedMeasurement` is a hash over the initial memory contents and state of the confidential VM.
89+
It covers the guest firmware, the initrd and kernel as well as the kernel command line.
90+
The kernel command line contains the dm-verity hash of the root filesystem, which contains all Contrast components that run inside the guest.
91+
92+
It's the (launch) `MEASUREMENT` from the SNP `ATTESTATION_REPORT`, according to Table 23 in the [SEV ABI Spec].
93+
94+
### `ReferenceValues.snp.*.MinimumTCB` {#snp-minimum-tcb}
95+
96+
The `MinimumTCB` defines the minimum secure version numbers (SVNs) for the platform components.
97+
The Contrast Coordinator compares these value against both the `COMMITTED_TCB` and `LAUNCH_TCB`,
98+
where the `LAUNCH_TCB` is the TCB that was committed when the VM was first launched,
99+
and the `COMMITTED_TCB` is the TCB that's currently committed on the platform.
100+
Provisional firmware isn't considered, as it can be rolled back by a malicious platform operator at any time.
101+
102+
AMD doesn't provide an accessible way to acquire the latest TCB values for your platform.
103+
Visit the [AMD SEV developer portal](https://www.amd.com/en/developer/sev.html) and download the latest firmware package for your processor family.
104+
Unpack and inspect the contained release notes, which state the SNP firmware SVN (called `SPL` (security patch level) in that document).
105+
Contact your hardware vendor or BIOS firmware provider for information about the other TCB components
106+
107+
To check the current TCB level of your platform, use [`snphost`]:
108+
109+
```sh
110+
snphost show tcb
111+
```
112+
```console
113+
Reported TCB: TCB Version:
114+
Microcode: 72
115+
SNP: 23
116+
TEE: 0
117+
Boot Loader: 9
118+
FMC: None
119+
Platform TCB: TCB Version:
120+
Microcode: 72
121+
SNP: 23
122+
TEE: 0
123+
Boot Loader: 9
124+
FMC: None
125+
```
126+
127+
The values listed as `Reported TCB` to should be greater or equal to the `MinimumTCB` values in `manifest.json`.
128+
The `Platform TCB` can be higher than the `Reported TCB`, in this case, the platform has provisional firmware enrolled.
129+
Contrast relies on the committed TCB values, as provisional firmware can be rolled back anytime by the platform operator.
130+
131+
:::warning
132+
133+
The TCB values observed on the target platform using `snphost` might not be trustworthy.
134+
Your channel to the system or the system itself might be compromised.
135+
The deployed firmware could be outdated and vulnerable.
136+
137+
:::
138+
139+
#### `ReferenceValues.snp.*.MinimumTCB.BootloaderVersion`
140+
141+
SVN of the bootloader of the secure processor.
142+
See [SEV ABI Spec], Section 2.2.
143+
144+
#### `ReferenceValues.snp.*.MinimumTCB.TEEVersion`
145+
146+
SVN of the OS of the secure processor.
147+
See [SEV ABI Spec], Section 2.2.
148+
149+
#### `ReferenceValues.snp.*.MinimumTCB.SNPVersion`
150+
151+
SVN of the SNP firmware.
152+
See [SEV ABI Spec], Section 2.2.
153+
154+
#### `ReferenceValues.snp.*.MinimumTCB.MicrocodeVersion`
155+
156+
SVN of the CPU microcode.
157+
See [SEV ABI Spec], Section 2.2.
158+
159+
#### `ReferenceValues.snp.*.MinimumTCB.FMCVersion`
160+
161+
Always `None` for Milan and Genoa platforms.
162+
163+
### `ReferenceValues.snp.*.GuestPolicy` {#snp-guest-policy}
164+
165+
This is the guest policy according to Section 4.3 of the [SEV ABI Spec].
166+
It's enforced during the launch of the confidential VM.
167+
168+
The guest policy is currently static in Contrast, values can't be changed.
169+
170+
#### `ReferenceValues.snp.*.GuestPolicy.ABIMinor`
171+
#### `ReferenceValues.snp.*.GuestPolicy.ABIMajor`
172+
#### `ReferenceValues.snp.*.GuestPolicy.SMT`
173+
#### `ReferenceValues.snp.*.GuestPolicy.MigrateMA`
174+
#### `ReferenceValues.snp.*.GuestPolicy.Debug`
175+
#### `ReferenceValues.snp.*.GuestPolicy.SingleSocket`
176+
#### `ReferenceValues.snp.*.GuestPolicy.CXLAllowed`
177+
#### `ReferenceValues.snp.*.GuestPolicy.MemAES256XTS`
178+
#### `ReferenceValues.snp.*.GuestPolicy.RAPLDis`
179+
#### `ReferenceValues.snp.*.GuestPolicy.CipherTextHidingDRAM`
180+
#### `ReferenceValues.snp.*.GuestPolicy.PageSwapDisable`
181+
182+
### `ReferenceValues.snp.*.PlatformInfo` {#snp-platform-info}
183+
184+
The `PLATFORM_INFO` structure according to Table 24 in the [SEV ABI Spec].
185+
186+
This has some overlap with the `GuestPolicy`, but is checked as part of the attestation report.
187+
188+
#### `ReferenceValues.snp.*.PlatformInfo.SMTEnabled`
189+
#### `ReferenceValues.snp.*.PlatformInfo.TSMEEnabled`
190+
#### `ReferenceValues.snp.*.PlatformInfo.ECCEnabled`
191+
#### `ReferenceValues.snp.*.PlatformInfo.RAPLDisabled`
192+
#### `ReferenceValues.snp.*.PlatformInfo.CiphertextHidingDRAMEnabled`
193+
#### `ReferenceValues.snp.*.PlatformInfo.AliasCheckComplete`
194+
#### `ReferenceValues.snp.*.PlatformInfo.TIOEnabled`
195+
196+
### `ReferenceValues.tdx.*.MrTd` {#tdx-mr-td}
197+
198+
### `ReferenceValues.tdx.*.MrSeam` {#tdx-mr-seam}
199+
200+
`MrSeam` is the SHA384 hash of the TDX module.
201+
You should retrieve the TDX module via a trustworthy channel from Intel, for example by downloading the TDX module from [Intel's GitHub repository] and hashing the module on a trusted machine.
202+
You can also reproduce the release artifact by following the build instructions linked in the release notes.
203+
204+
You can check the hash of the in-use TDX module by executing
205+
206+
```sh
207+
sha384sum /boot/efi/EFI/TDX/TDX-SEAM.so | cut -d' ' -f1
208+
```
209+
210+
:::warning
211+
212+
The TDX module hash (`MrSeam`) observed on the target platform might not be trustworthy.
213+
Your channel to the system or the system itself might be compromised.
214+
Make sure to retrieve or reproduce the value on a trusted machine.
215+
216+
:::
217+
218+
[Intel's GitHub repository]: https://github.com/intel/confidential-computing.tdx.tdx-module/releases
219+
220+
### `ReferenceValues.tdx.*.Rtmrs[4]` {#tdx-rtmrs}
221+
222+
### `ReferenceValues.tdx.*.TdAttributes` {#tdx-td-attributes}
223+
224+
### `ReferenceValues.tdx.*.Xfam` {#tdx-xfam}
225+
226+
227+
## `WorkloadOwnerKeyDigests` {#workload-owner-key-digests}
228+
229+
A list of workload owner public key digests.
230+
Used for authenticating subsequent manifest updates.
231+
232+
By default, the list contains the digest of the key that was passed to the Contrast CLI on `contrast generate` via the `--add-workload-owner-key` flag.
233+
If the flag wasn't used, the workload owner key was generated and stored in the workspace as `workload-owner.pem`.
234+
235+
The Coordinator uses this list to authenticate manifest updates submitted via `contrast set`.
236+
If multiple workload owner keys are specified, any of the corresponding private keys can be used to set a new manifest.
237+
238+
If the manifest is generated with the `--disable-updates` flag, the `WorkloadOwnerKeyDigests` list is empty.
239+
In this case, updates to the manifest are disabled and the [deployment is immutable](../../howto/immutable-deployments.md).
240+
241+
## `SeedshareOwnerKeys` {#seedshare-owner-keys}
242+
243+
Public keys of seed share owners.
244+
Used to authenticate user recovery and permission to handle the secret seed.
245+
246+
Setting a manifest where the `WorkloadOwnerKeyDigests` has been removed will render the deployment [immutable](../../howto/immutable-deployments.md).
247+
Doing the same for the `SeedshareOwnerKeys` field makes Coordinator recovery and workload secret recovery impossible.
248+
249+
[`snphost`]: https://github.com/virtee/snphost
250+
[SEV ABI Spec]: https://www.amd.com/content/dam/amd/en/documents/developer/56860.pdf

docs/docs/architecture/secrets.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ The secret seed and the seed share owner key are highly sensitive.
1717

1818
:::
1919

20-
## Workload Secrets
20+
## Workload secrets
2121

2222
The Coordinator provides each workload a secret seed during attestation.
2323
This secret can be used by the workload to derive additional secrets for example to encrypt persistent data.
@@ -95,7 +95,7 @@ In addition to the workload secrets provisioned by the initializer, Contrast wor
9595
The corresponding HTTP API is compatible with a subset of the [transit secrets API](https://openbao.org/api-docs/secret/transit/) used by [HashiCorp Vault](https://www.hashicorp.com/en/products/vault), and is served on Coordinator port 8200.
9696
Its primary use case is [auto-unsealing of Vault deployments](../howto/vault.md), which can in turn provide fine-grained secrets management to Contrast workloads.
9797

98-
Workloads can only access the encryption key with the same name as their `workloadSecretID`.
98+
Workloads can only access the encryption key with the same name as their `WorkloadSecretID`.
9999
For example, if the workload secret ID in the manifest is `my-secret-id`, they can use the endpoints `/v1/transit/encrypt/my-secret-id` and `/v1/transit/decrypt/my-secret-id`.
100100
Like the workload secret, the encryption key is stable across manifest updates and subject to the same limitations.
101101

docs/docs/getting-started/deployment.md

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,6 @@ Using `openssl`, the certificate of the service can be validated with the `mesh-
464464
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
465465
```
466466

467-
<!-- TODO(burgerdev): this should be split into an explanatory section in a manifest.md (yet to be written) and a how-to. -->
468-
469467
## Optional: Updating the certificate SAN and the manifest
470468

471469
By default, mesh certificates are issued with a wildcard DNS Subject Alternative Name (SAN).
@@ -494,32 +492,10 @@ Add the `frontendIP` to the list of SANs:
494492
+ "*",
495493
+ "203.0.113.34"
496494
],
497-
"WorkloadSecretID": "web"
498-
},
499-
```
500-
501-
### Adding a URI SAN to the manifest
502-
503-
Some authentication and authorization schemes rely on URI SANs in X.509 certificates.
504-
For example, [SPIFFE IDs] are URIs and are often found as certificate SANs.
505-
The Contrast Coordinator automatically identifies URI SANs in the manifest and adds them to the workload certificates.
506-
Add the URI to the list of SANs in the relevant manifest entry:
507-
508-
```diff
509-
"Policies": {
510-
...
511-
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": {
512-
"SANs": [
513-
"web",
514-
- "*"
515-
+ "*",
516-
+ "spiffe://acme.com/billing/payments"
517-
],
518-
"WorkloadSecretID": "web"
519495
},
520496
```
521497

522-
[SPIFFE IDs]: https://spiffe.io/docs/latest/spiffe-about/spiffe-concepts/#spiffe-id
498+
To find out more about the `SANs` field in the manifest, see [SANs section in the manifest reference](../architecture/components/manifest.md#policies-sans).
523499

524500
### Updating the manifest on the coordinator
525501

docs/docs/howto/vault.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ For the Vault application, this process is entirely transparent, and the device
5858
The LUKS encryption of the block device is primarily a convenience feature, enabling persistent storage at the filesystem level on confidential virtual machines.
5959
The primary and security-relevant encryption mechanism remains Vault’s own sealing process, which provides cryptographic protection of secrets even if the underlying storage is compromised.
6060

61-
Because the `workload-secret-seed` is derived from the associated `workloadSecretID`, any change to the `workloadSecretID` after the block device has been initialized will result in a different key, making the mounted block device undecryptable.
62-
Therefore, it's critical to ensure that the `workloadSecretID` is correctly aligned with the intended endpoint specified in Vault’s unsealing configuration before the first `contrast set` is executed.
63-
In this example, the `workloadSecretID` is set to `vault_unsealing` with an annotation:
61+
Because the `workload-secret-seed` is derived from the [associated `WorkloadSecretID`](../architecture/components/manifest.md#policies-workload-secret-id), any change to the `WorkloadSecretID` after the block device has been initialized will result in a different key, making the mounted block device undecryptable.
62+
Therefore, it's critical to ensure that the `WorkloadSecretID` is correctly aligned with the intended endpoint specified in Vault’s unsealing configuration before the first `contrast set` is executed.
63+
In this example, the `WorkloadSecretID` is set to `vault_unsealing` with an annotation:
6464

6565
```yaml
6666
spec:
@@ -109,6 +109,7 @@ kubectl get service vault -o=jsonpath='{.status.loadBalancer.ingress[0].ip}'
109109

110110
If you added SANs in the previous step, these will also be included in the certificate.
111111
In that case, you can configure your DNS service to resolve the additional SAN to the load balancer IP.
112+
See the section on [SANs in the manifest reference](../architecture/components/manifest.md#policies-sans) for more information.
112113

113114
Alternatively, configure the system from which you access Vault to resolve `vault` to the load balancer IP.
114115
On Linux, you can modify `/etc/hosts` for this.

0 commit comments

Comments
 (0)