Repository navigation
Conversation
PCR 8 is extended with the EC2 IMDS user data and then with the OS settings. Both carry values that describe where a host is deployed rather than what it runs: `settings.aws.region`, which early-boot-config sets on every AWS host, and the registry in host and bootstrap container sources. Measuring them gives an identical fleet a different PCR 8 value in every region or account. In both extensions, exclude `settings.aws.region` and measure every `settings.host-containers.*.source` and `settings.bootstrap-containers.*.source` without its registry: `<registry>/repo[:tag][@digest]` becomes `repo[:tag][@digest]`, where the first path component is a registry if it contains `.` or `:` or is `localhost` (the Docker/containerd rule). Repository, tag, and digest are kept, so a digest-pinned source still identifies the image. Stored settings are not modified. The settings extension now fetches apiclient's JSON, transforms it, and canonicalizes with the same formatter and trailing newline. User data is parsed as early-boot-config reads it into plain TOML tables, transformed the same way, and measured as canonical JSON under a new `ec2-imds-user-data:v2:` framing. Parsed trees are held in a wrapper that zeroizes strings on drop, and removed or replaced values are zeroized as they go; as before, this is best effort. docs/ENCRYPTED_STORAGE.md documents the new measurement and recommends pinning custom container sources by digest, since neither the region nor the registry is attested. Signed-off-by: Gavin Inglis <giinglis@amazon.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of changes:
PCR 8 is extended with the EC2 IMDS user data and then with the OS settings. Two kinds of values in them describe where a host is deployed rather than what it runs, so measuring them gives an otherwise identical fleet a different PCR 8 value in every region or account, and anyone verifying PCR 8 has to carry one expected value per location:
settings.aws.region, which early-boot-config sets from theinstance identity document on every AWS host; and
settings.host-containers.*.source,settings.bootstrap-containers.*.source)In both extensions of PCR8, exclude
settings.aws.regionand remove the registry from every host and bootstrap container source before hashing:<registry>/repo[:tag][@digest]is measured asrepo[:tag][@digest], where the first path component is a registry when it contains a.or:or islocalhost(the rule Docker and containerd use). The repository, tag, and digest are kept, so a digest-pinned source still identifies the image content. The settings extension keeps excludingsettings.updates.seedandsettings.network.hostnameas before. Stored settings are not modified; only the measured bytes are.For the user-data extension, the user data is parsed the same way early-boot-config reads it (optional gzip,
then TOML) into plain tables and values, the region and the registries are removed, and the canonical JSON of
the whole document is measured under a new
ec2-imds-user-data:v2:framing. For the settings extension, rottweiler now fetches apiclient's standard JSON (its canonical output is not valid JSON), removes the region and the registries, and serializes with the same canonical formatter and trailing newline apiclient uses.Settings and user data can carry secrets, so the parsed trees are held in a wrapper that zeroizes every string and key on drop, removed and replaced values are zeroized as they go, the decoded user-data text is kept in a
Zeroizing<String>, and TOML values are moved rather than copied into the JSON tree. As with the previous raw-bytes measurement this is best effort: copies the TOML and JSON parsers make internally, and stale heap blocks left by reallocation, are not covered.The threat model in docs/ENCRYPTED_STORAGE.md now states that neither the region nor the registry is attested by PCR 8 and recommends pinning custom host and bootstrap container sources by digest.
Testing done:
I copied
bottlerocket-admin:v0.21.6andbottlerocket-bootstrap:v0.3.6withcrane copyfrompublic.ecr.awsinto ECR repos of the same name in my own account, in us-east-1 and us-east-2.
A Per-region URIs written into user data:
B Custom host container
pcr8test+ custom bootstrap containerpcr8boot(bootstrap runs a script fromuser-datathat writes/local/pcr8-bootstrap-ran:--user-data fileb://X.toml.gz)…/bottlerocket-admin:v0.21.6@sha256:c7f3e9c8…Collected results via
sheltie:cat /sys/class/tpm/tpm0/pcr-sha256/8apiclient get settings --exclude settings.updates.seed --exclude settings.network.hostnamesystemctl is-active host-containers@pcr8testapiclient get settings.bootstrap-containers.pcr8boot.modeResults
CAB68C0558589E8869EB5A9D22E1BBC9D849BDBB1EA37BD5D01C8E6B2A34A15CCAB68C0558589E8869EB5A9D22E1BBC9D849BDBB1EA37BD5D01C8E6B2A34A15CDB2BDEE52252274BD707B293EB98DC68ADE58BF6CB09510DD7CD1507A7720171DB2BDEE5…DB2BDEE5…DB2BDEE5…25672E3FADD1ECCA0E94F3D105F9CAE9E2A6A505B6AA14E2B24296815AC259B3bottlerocket-admin:v0.21.6@sha256:c7f3…); pinned pull workedMeasured user-data extension for A (identical in both regions):
ec2-imds-user-data:v2:{"settings":{"bootstrap-containers":{"bootstrap":{"essential":false,"mode":"once","source":"bottlerocket-bootstrap:v0.3.6"}},"host-containers":{"admin":{"enabled":true,"source":"bottlerocket-admin:v0.21.6"}}}}On all five B instances: host-containers@pcr8test active; bootstrap-containers@pcr8boot succeeded and /local/pcr8-bootstrap-ran was written; the digest-pinned pull resolved and ran.
Terms of contribution:
By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.