-
Notifications
You must be signed in to change notification settings - Fork 92
spec: add spec for sign/verify an arbitrary file using Notation #765
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
Changes from all commits
855f9fe
477f0bb
4c377a9
1d00480
6da89d6
a3c09cc
88fbb41
3520ec4
4d6e434
0c5c86a
0395b6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,9 @@ | |
|
|
||
| Use `notation sign` to sign artifacts. | ||
|
|
||
| Signs an OCI artifact stored in the registry. Always sign artifact using digest(`@sha256:...`) rather than a tag(`:v1`) because tags are mutable and a tag reference can point to a different artifact than the one signed. If a tag is used, notation resolves the tag to the `digest` before signing. | ||
| ### Sign an OCI artifact stored in registry | ||
|
|
||
| Always sign artifact using digest(`@sha256:...`) rather than a tag(`:v1`) because tags are mutable and a tag reference can point to a different artifact than the one signed. If a tag is used, notation resolves the tag to the `digest` before signing. | ||
|
|
||
| Upon successful signing, the generated signature is pushed to the registry and associated with the signed OCI artifact. The output message is printed out as following: | ||
|
|
||
|
|
@@ -19,6 +21,16 @@ Warning: Always sign the artifact using digest(`@sha256:...`) rather than a tag( | |
| Successfully signed <registry>/<repository>@<digest> | ||
| ``` | ||
|
|
||
| ### Sign an arbitrary file stored in file system | ||
|
|
||
| The file content, i.e. the file blob, is signed. | ||
|
|
||
| Upon successful signing, the generated signature is stored to user specified signature path in file system. The output message is printed out as following: | ||
|
|
||
| ```text | ||
| Successfully signed <target_file> and created signature at <signature_file> | ||
| ``` | ||
|
|
||
| ## Outline | ||
|
|
||
| ```text | ||
|
|
@@ -31,6 +43,7 @@ Flags: | |
| --allow-referrers-api [Experimental] use the Referrers API to store signatures in the registry, if not supported (returns 404), fallback to the Referrers tag schema | ||
| -d, --debug debug mode | ||
| -e, --expiry duration optional expiry that provides a "best by use" time for the artifact. The duration is specified in minutes(m) and/or hours(h). For example: 12h, 30m, 3h20m | ||
| --file enable signing file content, if set, the reference argument is the file path in the file system (required if --signature is set) | ||
| -h, --help help for sign | ||
| --id string key id (required if --plugin is set). This is mutually exclusive with the --key flag | ||
| --insecure-registry use HTTP protocol while connecting to registries. Should be used only for testing | ||
|
|
@@ -39,6 +52,7 @@ Flags: | |
| -p, --password string password for registry operations (default to $NOTATION_PASSWORD if not specified) | ||
| --plugin string signing plugin name. This is mutually exclusive with the --key flag | ||
| --plugin-config stringArray {key}={value} pairs that are passed as it is to a plugin, refer plugin's documentation to set appropriate values. | ||
| --signature string output path of generated signature when signing a file, can only be used when --file is set | ||
| --signature-format string signature envelope format, options: "jws", "cose" (default "jws") | ||
| -u, --username string username for registry operations (default to $NOTATION_USERNAME if not specified) | ||
| -m, --user-metadata stringArray {key}={value} pairs that are added to the signature payload | ||
|
|
@@ -153,6 +167,31 @@ Warning: Always sign the artifact using digest(`@sha256:...`) rather than a tag( | |
| Successfully signed localhost:5000/net-monitor@sha256:b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 | ||
| ``` | ||
|
|
||
| ### Sign an arbitrary file located in file system | ||
|
|
||
| Notation supports signing files located in file systems. | ||
| ```shell | ||
| # Prerequisites: | ||
| # A default signing key is configured using CLI "notation key" | ||
|
|
||
| # Use flag "--file" to enable signing a file | ||
| # The generated signature is saved at the same dir as the target file with name | ||
This conversation was marked as resolved.
Show resolved
Hide resolved
|
||
| # <target_file>.sig | ||
| notation sign --file <target_file_path> | ||
|
|
||
| # Use flag "--file" to enable signing a file | ||
| # Use flag "--signature" to specify path where the generated signature is stored | ||
| notation sign --file --signature <signature_path> <target_file_path> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What will happen if I form command like And should we use
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This command will succeed.
It was actually called
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Signing a file might gave wrong impression that we are actually singing the file content along with its attributes but in reality we would only signing file content. Also, if we add support for passing data as stdin we will have to create a new flag, same goes for passing data as parameter
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @priteshbandi Correct me if I'm wrong, you would like a single flag to sign arbitrary things, by things I mean it can be a file, it can be data from stdin, etc. |
||
| ``` | ||
| Examples of successful signing: | ||
| ```console | ||
| $ notation sign --file myFile.txt | ||
| Successfully signed myFile.txt and created signature at myFile.txt.sig | ||
|
|
||
| $ notation sign --file --signature mySignature.sig myFile | ||
| Successfully signed myFile and created signature at mySignature.sig | ||
| ``` | ||
|
|
||
| ### [Experimental] Sign container images stored in OCI layout directory | ||
|
|
||
| Container images can be stored in OCI image Layout defined in spec [OCI image layout][oci-image-layout]. It is a directory structure that contains files and folders. The OCI image layout could be a tarball or a directory in the filesystem. For example, a file named `hello-world.tar` or a directory named `hello-world`. Notation only supports signing images stored in OCI layout directory for now. Users can reference an image in the layout using either tags, or the exact digest. For example, use `hello-world:v1` or `hello-world@sha256xxx` to reference the image in OCI layout directory named `hello-world`. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,8 @@ | |
|
|
||
| ## Description | ||
|
|
||
| ### Verify an OCI artifact stored in registry | ||
|
|
||
| Use `notation verify` command to verify signatures associated with the artifact. Signature verification succeeds if verification succeeds for at least one of the signatures associated with the artifact. Upon successful verification, the output message is printed out as follows: | ||
|
|
||
| ```text | ||
|
|
@@ -26,6 +28,22 @@ KEY VALUE | |
| <key> <value> | ||
| ``` | ||
|
|
||
| ### Verify an arbitrary file stored in file system | ||
|
|
||
| Verify the file content (blob) against signatures stored in file system. Upon successful verification, the output message is printed out as follows: | ||
|
|
||
| ```text | ||
| Successfully verified <target_file> with signature <signature_file> | ||
| ``` | ||
|
|
||
| ### Verify an arbitrary file stored in registry | ||
|
|
||
| Verify the file content (blob) against signatures stored in registry. Upon successful verification, the output message is printed out as follows: | ||
|
|
||
| ```text | ||
| Successfully verified signature for <registry>/<repository>@<digest> | ||
| ``` | ||
|
|
||
| ## Outline | ||
|
|
||
| ```text | ||
|
|
@@ -37,14 +55,16 @@ Usage: | |
| Flags: | ||
| --allow-referrers-api [Experimental] use the Referrers API to verify signatures, if not supported (returns 404), fallback to the Referrers tag schema | ||
| -d, --debug debug mode | ||
| --file enable verifying a file, if set, the reference argument is the file path or full URI reference of the file artifact in registry (required if --signature is set) | ||
| -h, --help help for verify | ||
| --insecure-registry use HTTP protocol while connecting to registries. Should be used only for testing | ||
| --max-signatures int maximum number of signatures to evaluate or examine (default 100) | ||
| --oci-layout [Experimental] verify the artifact stored as OCI image layout | ||
| -p, --password string password for registry operations (default to $NOTATION_PASSWORD if not specified) | ||
| --plugin-config stringArray {key}={value} pairs that are passed as it is to a plugin, if the verification is associated with a verification plugin, refer plugin documentation to set appropriate values | ||
| --scope string [Experimental] set trust policy scope for artifact verification, required and can only be used when flag "--oci-layout" is set | ||
| --scope string [Experimental] set trust policy scope for artifact verification, required when flag "--oci-layout" is set, can only be used when "--oci-layout" or "--file" is set | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How will scope work for verifying arbitrary data? I am assuming there would be some trust-policy spec changes?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @priteshbandi This is an existing flag. It was initially introduced for verifying artifact as
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes but Also as per https://github.com/notaryproject/specifications/blob/main/specs/trust-store-trust-policy.md#registry-scopes-constraints
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @priteshbandi Agree. Yes, we should have a spec change in the https://github.com/notaryproject/specifications repo as well, especially for the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @priteshbandi I will add the related spec changes into the specification's repo. Here's the issue created by @yizha1 on the spec changes: notaryproject/specifications#275
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will also require updates to descriptor which is being signing.
Signing process look like this?
Here we are calculating digest twice instead of once (ideal). Should we worry about this? Thinking more we will probably need this to support user defined metadata. For verification
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @priteshbandi Answering them below:
To be more precise, this is the update to the signature
Good point. We should allow users to pick their own media type. We could do this by:
Currently, I'm using opencontainers/go-digest to compute the digest. The algorithm is SHA256, which is the primary storage digest (https://pkg.go.dev/github.com/opencontainers/go-digest#Canonical).
Yes, since the actual content is signed, the size corresponds to the size of the actual content.
I don't think we should worry about this? Because even for the current Notation, we create the OCI descriptor out of the target OCI artifact, then sign/verify the descriptor.
Yes, it reuses what we have in the current Notation workflow. The changes for sign and verify are actually small in our code base.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
IMO, for future extensibility and robustness, we should control the media type.
IMO, we can decide for sane default but allow user to control hashing algo. Depending upon usecase and compliance need user might want to use different hashing algos.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @priteshbandi Since this PR is closed, could you move the discussions to #767? |
||
| -u, --username string username for registry operations (default to $NOTATION_USERNAME if not specified) | ||
| --signature string path of signature when verifying a file, required and used if and only if the target file is stored in file system | ||
| -m, --user-metadata stringArray user defined {key}={value} pairs that must be present in the signature for successful verification if provided | ||
| -v, --verbose verbose mode | ||
| ``` | ||
|
|
@@ -173,6 +193,50 @@ Warning: Always verify the artifact using digest(@sha256:...) rather than a tag | |
| Successfully verified signature for localhost:5000/net-monitor@sha256:b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 | ||
| ``` | ||
|
|
||
| ### Verify an arbitrary file located in OCI-compliant registry | ||
|
|
||
| A user wants to verify a file stored as an OCI artifact in an OCI-compliant registry. | ||
| ```shell | ||
| # Prerequisites: Signatures are stored in the registry referencing the file artifact | ||
|
|
||
| # Use flag "--file" to enable verifying a file | ||
| notation verify --file localhost:5000/myFile@sha256:b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 | ||
| ``` | ||
|
|
||
| An example of output messages for a successful verification: | ||
|
|
||
| ```text | ||
| Successfully verified signature for localhost:5000/myFile@sha256:b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 | ||
| ``` | ||
|
|
||
| ### Verify an arbitrary file located in file system | ||
|
|
||
| A verifier wants to verify a file against its signatures located in file system. | ||
|
|
||
| Trust policy to be used follows the rule below: | ||
| 1. User MAY pass in a trust policy scope via `--scope` flag. The value MUST follow Notation's trust policy [spec](https://github.com/notaryproject/specifications/blob/main/specs/trust-store-trust-policy.md#registry-scopes-constraints). If the user specified trust policy does not exist in Notation's `trustpolicy.json` (use command `notation policy show` to check existence), then | ||
| the [global trust policy](https://github.com/notaryproject/specifications/blob/main/specs/trust-store-trust-policy.md#registry-scopes-constraints) is used. | ||
| 2. If user ignores the `--scope` flag, then the [global trust policy](https://github.com/notaryproject/specifications/blob/main/specs/trust-store-trust-policy.md#registry-scopes-constraints) is used as default. | ||
| ```shell | ||
| # Prerequisites: Both target and signature files are stored in file system | ||
|
|
||
| # Use flag "--file" to enable verifying a file | ||
| # Use flag "--signature" to speicfy path where the signature is stored | ||
| # The global trust policy is used by default | ||
| notation verify --file --signature mySignature.sig myFile.txt | ||
|
|
||
| export NOTATION_EXPERIMENTAL=1 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we want this to be experimental?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having a flag marked as experimental doesn't mean that this new functionality needs to be experimental. We can still have signing local OCI artifact as experimental and still support signing arbitrary data as new feature(not experimental).
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @priteshbandi Yes, you are right, I'm not marking this new feature as experimental. Only the flag
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So does that mean initially we will only support wildcard trust policy?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @priteshbandi I think we should also support user specified trust policy. And we need to make the corresponding changes in the spec of the specifications repo. |
||
| # Use flag "--file" to enable verifying a file | ||
| # Use flag "--signature" to speicfy path where the signature is stored | ||
| # Trust policy with scope "example/myPolicy" is used, if it does not exist, the global trust policy is used | ||
| notation verify --file --signature mySignature.sig --scope example/myPolicy myFile.txt | ||
| ``` | ||
| An example of output messages for a successful verification: | ||
|
|
||
| ```text | ||
| Successfully verified ./myFile.txt with signature ./mySignature.sig | ||
| ``` | ||
|
|
||
| ### [Experimental] Verify container images in OCI layout directory | ||
|
|
||
| Users should configure trust policy properly before verifying artifacts in OCI layout directory. According to trust policy specification, `registryScopes` property of trust policy configuration determines which trust policy is applicable for the given artifact. For example, an image stored in a remote registry is referenced by "localhost:5000/net-monitor:v1". In order to verify the image, the value of `registryScopes` should contain "localhost:5000/net-monitor", which is the repository URL of the image. However, the reference to the image stored in OCI layout directory doesn't contain repository URL information. Users can set `registryScopes` to the URL that the image is supposed to be stored in the registry, and then use flag `--scope` for `notation verify` command to determine which trust policy is used for verification. Here is an example of trust policy configured for image `hello-world:v1`: | ||
|
|
||
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 probably need to reword this sentence or remove it.