WIP: Rough draft for updated generic OCI sealing#226
Draft
cgwalters wants to merge 2 commits intocomposefs:mainfrom
Draft
WIP: Rough draft for updated generic OCI sealing#226cgwalters wants to merge 2 commits intocomposefs:mainfrom
cgwalters wants to merge 2 commits intocomposefs:mainfrom
Conversation
1ce192a to
063ff54
Compare
cgwalters
commented
Feb 12, 2026
crates/cfsctl/src/main.rs
Outdated
| composefs_oci::signing::FsVeritySigningKey::from_pem(&cert_pem, &key_pem)?; | ||
|
|
||
| // Build subject descriptor from the source image's manifest | ||
| let manifest_json = img.manifest().to_string()?; |
Collaborator
Author
There was a problem hiding this comment.
Hmm we actually need to operate on the raw original representation, can't rely on to_string() always giving us the same thing.
crates/cfsctl/src/main.rs
Outdated
| /// Image reference (tag name) | ||
| image: String, | ||
| /// Path to the OCI layout directory (must already exist) | ||
| oci_layout_path: PathBuf, |
Collaborator
Author
There was a problem hiding this comment.
I think we can use clap(value_parser) into an ocidir directly or so
| /// the container to be mounted with integrity protection. | ||
| /// | ||
| /// Returns a tuple of (sha256 content hash, fs-verity hash value) for the updated configuration. | ||
| pub fn seal<ObjectID: FsVerityHashValue>( |
Collaborator
Author
There was a problem hiding this comment.
Might be cleaner if we do a prep commit that removes the old sealing as we know we're not going to do it anymore.
| /// # Returns | ||
| /// | ||
| /// The number of referrer artifacts exported. | ||
| pub fn export_referrers_to_oci_layout<ObjectID: FsVerityHashValue>( |
Collaborator
Author
There was a problem hiding this comment.
Something like this could land as a prep commit
| use std::fs; | ||
| use std::io::Write; | ||
|
|
||
| let blobs_dir = oci_layout_path.join("blobs").join("sha256"); |
| format!("{seed:02x}").repeat(32) | ||
| } | ||
|
|
||
| fn sample_subject() -> Descriptor { |
Collaborator
Author
There was a problem hiding this comment.
Let's unify this stuff with shared infra to generate an ocidir with known content
361eeb7 to
2f93e4a
Compare
Collaborator
Author
|
This one will need to logically depend on #225 because that one has a lot of hardening for the EROFS parser |
The biggest goal here is support for Linux kernel-native fsverity signatures to be attached to layers, which enables integration with IPE. Add support for a fully separate OCI "composefs signature" artifact which can be attached to an image. Drop the -impl.md doc...it's not useful to try to write this stuff in markdown. The spec has some implementation considerations, but it's easier to look at implementation side from a code draft. Add standardized-erofs-meta.md as a placeholder document outlining the goal of standardizing composefs EROFS serialization across implementations (canonical model: tar -> dumpfile -> EROFS). Assisted-by: OpenCode (Claude Opus 4.5) Signed-off-by: Colin Walters <walters@verbum.org>
Implement end-to-end support for cryptographically signing composefs OCI images using PKCS#7/fsverity detached signatures, stored as OCI referrer artifacts following the 'composefs erofs-alongside' spec. Core signing infrastructure (composefs crate): - Add fsverity algorithm constants and ComposeFsAlgorithm type - Add formatted_digest module for kernel-compatible fsverity digest construction (the 12-byte header + raw hash used by the kernel's FS_IOC_ENABLE_VERITY ioctl) - Add kernel keyring support via composefs-ioctls keyring module (inject X.509 certs into .fs-verity keyring for kernel-level signature enforcement) OCI signing library (composefs-oci crate): - signing.rs: FsVeritySigningKey (sign) and FsVeritySignatureVerifier (verify) using openssl PKCS#7 with DETACHED|BINARY|NOATTR flags, compatible with Linux kernel fsverity builtin signature verification - signature.rs: OCI artifact manifest builder/parser for the 'application/vnd.composefs.erofs-alongside.v1' artifact type, storing per-layer and merged EROFS images alongside their PKCS#7 signatures as typed layers with composefs.* annotations - image.rs: compute_per_layer_digests() and compute_merged_digest() for deterministic EROFS image generation from OCI layer stacks - oci_image.rs: seal_image() to compute and embed the composefs fsverity digest into the OCI config, export/import to OCI layout directories (migrated to ocidir crate for atomic I/O), referrer index management CLI commands (cfsctl): - 'oci seal <image>' — compute composefs EROFS, embed fsverity digest - 'oci sign <image> --cert --key' — create signature artifact - 'oci verify <image> [--cert]' — verify signatures (digest-only without --cert, full PKCS#7 with --cert) - 'oci mount <name> <mountpoint> [--require-signature --trust-cert]' — verify signatures before kernel mount - 'oci pull ... --require-signature --trust-cert' — verify after pull - 'oci push <image> <dest> [--signatures]' — export to OCI layout - 'oci export-signatures <image> <dest>' — export just artifacts - 'oci inspect' — show referrer info in JSON output - 'keyring add-cert <pem>' — inject cert into kernel keyring The mount and pull --require-signature paths share a common verify_image_signatures() helper that recomputes expected EROFS digests and verifies each PKCS#7 signature blob against the trusted certificate. The mount command now also resolves tag names (via OciImage::open_ref) instead of requiring raw config digests, consistent with seal/sign/ verify. Integration tests: - signing.rs: 17 unprivileged tests covering sign, verify, wrong cert, export, seal+sign roundtrip, artifact structure, --require-signature on pull and mount - privileged.rs: 7 tests for real fsverity enforcement, kernel keyring injection, kernel signature acceptance/rejection - podman.rs: 3 tests building real container images via podman - cli.rs: updated for richer OCI test layout (4 entries) and new oci push/roundtrip tests - test-oci-sign-verify.sh: standalone shell-based integration tests Assisted-by: OpenCode (Claude claude-opus-4-6) Signed-off-by: Colin Walters <walters@verbum.org>
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.
This is just some rough draft raw material that builds on: