-
Notifications
You must be signed in to change notification settings - Fork 66
feat: Add DSSE (Dead Simple Signing Envelope) support #514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
d3051f1 to
967ca5a
Compare
This PR adds support for DSSE envelopes used in in-toto attestations: - **src/bundle/dsse.rs**: DSSE envelope implementation with Pre-Authentication Encoding (PAE) support. Provides DsseEnvelope wrapper around protobuf Envelope with convenient APIs for creating and manipulating DSSE envelopes. - **src/bundle/intoto.rs**: in-toto Statement support including StatementBuilder, Subject, and predicate handling. Supports creating in-toto attestations with multiple subjects and custom predicates. - **src/rekor/models/dsse.rs**: Rekor DSSE entry models for submitting DSSE envelopes to the transparency log. - **rust-toolchain**: Pin to Rust 1.90.0 for edition 2024 support Key Features: - Correct PAE computation per DSSE spec - Support for application/vnd.in-toto+json payload type - Builder pattern for creating statements - Multiple digest algorithms per subject - Comprehensive unit tests This PR lays the groundwork for Bundle v0.3 DSSE verification support and attestation signing capabilities. Signed-off-by: Wolf Vollprecht <[email protected]>
42ff244 to
517acd6
Compare
Signed-off-by: Wolf Vollprecht <[email protected]>
Signed-off-by: Wolf Vollprecht <[email protected]>
1573c30 to
2bf3b8e
Compare
Xynnn007
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @wolfv , nice work! I am also seeking to add support oci v1.1 & bundle v0.3 support in sigstore-rs to work with images signed by cosign v3. Some comments
| use serde::{Deserialize, Serialize}; | ||
|
|
||
| #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] | ||
| pub struct Dsse { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use #[serde(rename_all = "camelCase")] macro upon this struct to avoid each field-level serde macros. According to document https://serde.rs/attr-rename.html
| pub struct Spec { | ||
| #[serde(rename = "root", skip_serializing_if = "Option::is_none")] | ||
| pub root: Option<String>, | ||
| #[serde(rename = "proposedContent")] | ||
| pub proposed_content: ProposedContent, | ||
| #[serde(rename = "payloadHash", skip_serializing_if = "Option::is_none")] | ||
| pub payload_hash: Option<Hash>, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, we can use #[serde(rename_all = "camelCase")] macro upon this struct to avoid each field-level serde macros. According to document https://serde.rs/attr-rename.html
| #[serde(rename = "envelope", skip_serializing_if = "Option::is_none")] | ||
| pub envelope: Option<String>, | ||
| #[serde(rename = "verifiers")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like the two rename macro target is the same as field name, thus we might not need the rename macros?
| #[serde(rename = "algorithm")] | ||
| pub algorithm: String, | ||
| #[serde(rename = "value")] | ||
| pub value: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like the two rename macro target is the same as field name, thus we might not need the rename macros?
src/bundle/intoto.rs
Outdated
| //! that can be signed and wrapped in DSSE envelopes. | ||
| //! | ||
| //! Note: This implements the v0.1 specification, which is currently used by cosign and Rekor. | ||
| //! See: <https://github.com/in-toto/attestation/blob/main/spec/v0.1.0/statement.md> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is not available. It might be the new link https://github.com/in-toto/attestation/tree/main/spec/v0.1.0#statement?
| pub fn new( | ||
| name: impl Into<String>, | ||
| algorithm: impl Into<String>, | ||
| digest: impl Into<String>, | ||
| ) -> Self { | ||
| let mut digest_map = HashMap::new(); | ||
| digest_map.insert(algorithm.into(), digest.into()); | ||
| Self { | ||
| name: name.into(), | ||
| digest: digest_map, | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a little thought:
Could we make this new() to only receive name parameter? In this way it looks more "natural"
let subject = Subject::new("name")
.with_digest(...)
.with_digest(...);Not sure this makes sense to you
| /// Builds the statement. | ||
| /// | ||
| /// Returns an error if required fields are missing. | ||
| pub fn build(self) -> Result<Statement, &'static str> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add a new error enum here and replace the Result<Statement, &'static str> with a unified error/result type?
| let payload_json = serde_json::to_vec(statement)?; | ||
|
|
||
| Ok(Self(Envelope { | ||
| payload: payload_json, // Store RAW bytes, not base64! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the purpose here is to make calculating PAE more convenient, even though the standard documentation requires base64 encoding. From a code maintenance perspective, it seems better to store this variable in standard base64 encoding?
wdyt?
| //! | ||
| //! See: <https://github.com/secure-systems-lab/dsse/blob/v1.0.0/envelope.md> | ||
|
|
||
| use sigstore_protobuf_specs::io::intoto::{Envelope, Signature as DsseSignature}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might need to re-export the Envelope and DsseSignature like
pub use sigstore_protobuf_specs::io::intoto::{Envelope, Signature as DsseSignature};As the function signatures() and as_inner() returns the two structs, while we cannot expect the caller have imported the dependency sigstore_protobuf_specs
| }; | ||
| use std::fs; | ||
|
|
||
| #[test] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at the first glance, these test cases can be moved to under src/bundle/dsse.rs or src/bundle/mod.rs as unit tests, as they did not call codes of other parts of the project.
|
Hey @Xynnn007 thanks so much for your review. I'll try to address the comments swiftly. Just FYI I also started a separate project for a leaner sigstore implementation in Rust (no OCI handling and tiny crates here: https://github.com/wolfv/sigstore-rust - if you want to review / give your feedback on those / try them out that would be highly appreciated as well!). |
|
@wolfv Yes, will take a look!
Good! I will take a look |
This PR adds support for DSSE envelopes used in in-toto attestations. It's part of our efforts to upstream support for v0.3 bundles (see also #513). The code was mostly written by Claude using sigstore-python and sigstore-go as references.
src/bundle/dsse.rs: DSSE envelope implementation with Pre-Authentication Encoding (PAE) support. Provides DsseEnvelope wrapper around protobuf Envelope with convenient APIs for creating and manipulating DSSE envelopes.
src/bundle/intoto.rs: in-toto Statement support including StatementBuilder, Subject, and predicate handling. Supports creating in-toto attestations with multiple subjects and custom predicates.
src/rekor/models/dsse.rs: Rekor DSSE entry models for submitting DSSE envelopes to the transparency log.
Key Features:
This PR lays the groundwork for Bundle v0.3 DSSE verification support and attestation signing capabilities.