-
Notifications
You must be signed in to change notification settings - Fork 135
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
[WIP] Add support for Statements #570
base: develop
Are you sure you want to change the base?
Conversation
142d15c
to
adc4a74
Compare
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.
Great start, @chasen-bettinger! I've left some comments but I think this is looking quite good. I'd like to scope this PR to adding support for the statement layer and tackle predicate implementations separately.
Edit: I also recommend switching to a feature branch instead of using develop
.
Hello! I just came across this issue, thanks @chasen-bettinger . Have you seen the protobuf definition for statement? Instead of implementing a separate Python class for Statement, our recommendation (from the attestation side) would be to build applications based on the protos. This way, all ITE-6 compliant in-toto implementations actually use that same pre-defined format. If you're interested, we would very much welcome a contribution related to using the protos in the Python implementation. |
@chasen-bettinger this should unblock you: https://pypi.org/project/in-toto-attestation/ |
in_toto/models/link.py
Outdated
self.environment = {} | ||
|
||
if hasattr(self, 'byproducts') == True: | ||
self.byproducts["return-value"] = int( |
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.
@adityasaky In order to successfully serialize this class into a canonical JSON, I've had to write in this hack. When the class is parsed from a protobuf to a JSON, the value becomes a float, which breaks downstream processes because that is against the rules of canonical JSON. In the current design, we cannot get around this limitation because it is a central part of the Signable
class and its signable_bytes
property.
As you may have already witnessed, either due to the architecture or my poor Python skills (most likely the latter), this class (and the Statement class) became quite ugly when trying to integrate the protobufs into the existing structure. As the code is written now, I believe there's not a way around using the Signable class as it is integral in generating and validating signatures. I fear a slight refactor might be in the near future, but I wanted your thoughts first.
Any thoughts on the best way to proceed?
cc: @marcelamelara
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.
If I'm not mistaken, the link predicate shouldn't be Signable
at all. The predicate will be embedded in a Statement which is what we'd actually be signing.
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 missed that the link was extending Signable
. Agree with Aditya that shouldn't be the case. The link proto should be converted into a struct, inserted into the Statement predicate
field, and the Statement will then be signed.
I also believe that Statement might not have to extend Signable
anymore either. The validation of the structure is now implemented in the Statement wrapper class provided by the in_toto_attestation
package, and we can similarly use protobuf APIs directly to expose the signable bytes for a Statement.
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 have more comments about how we'd architect this that I'll submit separately.
in_toto/models/link.py
Outdated
self.environment = {} | ||
|
||
if hasattr(self, 'byproducts') == True: | ||
self.byproducts["return-value"] = int( |
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.
If I'm not mistaken, the link predicate shouldn't be Signable
at all. The predicate will be embedded in a Statement which is what we'd actually be signing.
70b881e
to
f059705
Compare
- Added the Statement model - Incorporated the Statement model into the Envelope. - Skipped a test because I'm awaiting feedback on whether this is the right direction to take this issue (in-toto#562). The test is built on the previously-used 'link' model as the payload. Signed-off-by: Chasen Bettinger <bettingerchasen@gmail.com>
Signed-off-by: Chasen Bettinger <bettingerchasen@gmail.com>
Signed-off-by: Chasen Bettinger <bettingerchasen@gmail.com>
Signed-off-by: Chasen Bettinger <bettingerchasen@gmail.com>
e644a07
to
b15ddc2
Compare
Signed-off-by: Chasen Bettinger <bettingerchasen@gmail.com>
Signed-off-by: Chasen Bettinger <bettingerchasen@gmail.com>
Signed-off-by: Chasen Bettinger <bettingerchasen@gmail.com>
Signed-off-by: Chasen Bettinger <bettingerchasen@gmail.com>
Signed-off-by: Chasen Bettinger <bettingerchasen@gmail.com>
STATEMENT_TYPE = "https://in-toto.io/Statement/v1" | ||
|
||
|
||
# NOTE: 08/24/23 - This function is an intentional |
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.
@adityasaky @marcelamelara Review please
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 fear there is not much else you can do here, if you want Statement to be a Signable.
FYI: I had a very similar issue in in-toto-golang a while ago and tried the same fix you proposed in secure-systems-lab/securesystemslib#625 but did not use it for the reasons pointed out by @jku. The fix I did end up using there (case-handling json.Number
) won't work in Python. But maybe that's okay, because the fix is actually quite a hack.
Because of all these problems with canonical json, I think the best way going forward would be to just not support a canonical json representation for Statements, and use it with DSSE Envelopes only.
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.
Seems like others have said this before: #570 (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.
Yea, understood. I'm curious to learn the ramifications of adding a new method to the Envelope class within this library that doesn't require a Signable
instance to instantiate.
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'll correct these tests once the structure of the implementation details have settled. Was using this as my test bed for validating changes.
@@ -60,4 +60,4 @@ target/ | |||
|
|||
#Ipython Notebook | |||
.ipynb_checkpoints | |||
.travis-solo/ | |||
.travis-solo/ |
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.
Can you add this new line back in?
@@ -196,6 +196,13 @@ def parse_password_and_prompt_args(args): | |||
"help": ("generate metadata using dsse (experimental)."), | |||
} | |||
|
|||
STATEMENT_ARGS = ["--use-statement"] |
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'm worried statement
is ambiguous, could you update this to be attestation
instead?
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.
Ideally, --generate-attestation
.
@@ -588,7 +593,33 @@ def in_toto_run( | |||
|
|||
if use_dsse: | |||
LOG.info("Generating link metadata using DSSE...") | |||
link_metadata = Envelope.from_signable(link) | |||
|
|||
if use_statement == False: |
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.
Potential footgun: if I set use_statement
(or use_attestation
) to True, I shouldn't be expected to set use_dsse
to True as well. I see the CLI handles this but this is an issue with direct API use. I suggest we move use_attestation
out of the use_dsse
block and only support DSSE there. The use_dsse
conditional block should only be for legacy links, and something we phase out in a future version as we deprecate legacy links in favour of link predicates.
@@ -223,7 +226,8 @@ def __repr__(self): | |||
separators = (",", ":") if self.compact_json else (",", ": ") | |||
|
|||
return json.dumps( | |||
{"signatures": self.signatures, "signed": attr.asdict(self.signed)}, | |||
{"signatures": self.signatures, |
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.
editor shenanigans?
@@ -438,7 +442,8 @@ def _validate_signatures(self): | |||
) | |||
|
|||
for signature in self.signatures: | |||
securesystemslib.formats.ANY_SIGNATURE_SCHEMA.check_match(signature) | |||
securesystemslib.formats.ANY_SIGNATURE_SCHEMA.check_match( | |||
signature) |
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.
and here too?
Fixes issue #:
#562
Description of the changes being introduced by the pull request:
Some notes:
Some things I still don't understand:
predicate_types
and where do they come from?.link
files were being generated. I presumed based on the information on the SLSA website thatLinks
are a subset ofStatements
and that once in-toto supportedStatements
(andEnvelopes
WITHSignatures
andStatements
), the output would be anEnvelope
? I don't really understand the bigger picture just yet.predicate
hash should be nor where that comes from. This resource was most helpful in giving me breadcrumbs, but I'm still uncertain.Please verify and check that the pull request fulfills the following
requirements: