Skip to content
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

doc: fix broken links, wrong artifactType and outdated ORAS usage #216

Merged
merged 2 commits into from
Dec 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 22 additions & 22 deletions specs/plugin-extensibility.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Notation Extensibility for Signing and Verification

Keys and associated certificates used for signing artifacts using Notary could be available to users through varied solutions that provide secure key generation, storage and cryptographic operations. Some are well established with standards like [PIV](https://csrc.nist.gov/projects/piv/piv-standards-and-supporting-documentation) and [PKCS #11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html) implemented by hardware tokens, smart cards. More recent options which use varied authentication and API protocols are remote key management services and signing services by third party vendors and cloud service providers. Notation will support a few built-in integrations with standard providers, and will provide plugin interfaces for users, and vendors to implement their own integrations with the solutions they use. This allows a plugin publisher to implement, test, release and patch their solutions independent of Notation’s development and release cycle. This document provides specification for the plugin model, and interfaces to implement. This specification aims to work both for [existing](../signature-specification.md) and future signature formats adopted by Notary.
Keys and associated certificates used for signing artifacts using Notary could be available to users through varied solutions that provide secure key generation, storage and cryptographic operations. Some are well established with standards like [PIV](https://csrc.nist.gov/projects/piv/piv-standards-and-supporting-documentation) and [PKCS #11](https://docs.oasis-open.org/pkcs11/pkcs11-base/v3.0/os/pkcs11-base-v3.0-os.html) implemented by hardware tokens, smart cards. More recent options which use varied authentication and API protocols are remote key management services and signing services by third party vendors and cloud service providers. Notation will support a few built-in integrations with standard providers, and will provide plugin interfaces for users, and vendors to implement their own integrations with the solutions they use. This allows a plugin publisher to implement, test, release and patch their solutions independent of Notation’s development and release cycle. This document provides specification for the plugin model, and interfaces to implement. This specification aims to work both for [existing](./signature-specification.md) and future signature formats adopted by Notary.

## Terminology

Expand Down Expand Up @@ -92,11 +92,11 @@ Plugins may require additional configuration to work correctly, that could be se

For the previous example, plugin config can be set using command line arguments as part of registering a key with the `notation key add` command. E.g.

* `notation key add --name "mysigningkey" --id "keyid" --plugin "com.example.nv2plugin" --pluginConfig key1=value1,"key 2"="value 2"`
* `notation key add "mysigningkey" --id "keyid" --plugin "com.example.nv2plugin" --plugin-config key1=value1 --plugin-config "key 2"="value 2"`

Plugin config can be also set/overriden during signing with the `notation sign` command. Following example overrides value for `key 2` already set in `config.json` by previous command.

* `notation sign $IMAGE --key "mysigningkey" --pluginConfig "key 2"=newValue2`
* `notation sign $IMAGE --key "mysigningkey" --plugin-config "key 2"=newValue2`

### Plugin contract

Expand Down Expand Up @@ -200,18 +200,18 @@ This interface targets plugins that integrate with providers of basic cryptograp
5. Execute the plugin with `get-plugin-metadata` command
1. If plugin supports capability `SIGNATURE_GENERATOR.RAW`
1. Execute the plugin with `describe-key` command, set `request.keyId` and the optional `request.pluginConfig` to corresponding values associated with signing key `keyName` in `config.json`.
2. Generate the payload to be signed for [JWS](../signature-specification.md#supported-signature-envelopes) envelope format.
1. Create the JWS protected headers collection and set `alg` to value corresponding to `describe-key.response.keySpec` as per [signature algorithm selection](../signature-specification.md#algorithm-selection).
2. Create the Notary v2 Payload (JWS Payload) as defined [here](../signature-specification.md#payload).
2. Generate the payload to be signed for [JWS](./signature-specification.md#supported-signature-envelopes) envelope format.
1. Create the JWS protected headers collection and set `alg` to value corresponding to `describe-key.response.keySpec` as per [signature algorithm selection](./signature-specification.md#algorithm-selection).
2. Create the Notary v2 Payload (JWS Payload) as defined [here](./signature-specification.md#payload).
3. The *payload to sign* is then created as - `ASCII(BASE64URL(UTF8(ProtectedHeaders)) ‘.’ BASE64URL(JWSPayload))`
3. Execute the plugin with `generate-signature` command.
1. Set `request.keyId` and the optional `request.pluginConfig` to corresponding values associated with signing key `keyName` in `config.json`.
2. Set `request.payload` as base64 encoded *payload to sign* (the JWS *payload to sign* is double encoded, this is a shortcoming of using plugin contract with JSON encoding).
3. Set `keySpec` to value returned by `describe-key` command in `response.keySpec`, and `hashAlgorithm` to hash algorithm corresponding to the key spec, as per [signature algorithm selection](../signature-specification.md#algorithm-selection). The algorithm specified in `hashAlgorithm` MUST be used by the plugin to hash the payload (`request.payload`) as part of signature generation.
3. Set `keySpec` to value returned by `describe-key` command in `response.keySpec`, and `hashAlgorithm` to hash algorithm corresponding to the key spec, as per [signature algorithm selection](./signature-specification.md#algorithm-selection). The algorithm specified in `hashAlgorithm` MUST be used by the plugin to hash the payload (`request.payload`) as part of signature generation.
4. Validate the generated signature, return an error if any of the checks fails.
1. Check if `response.signingAlgorithm` is one of [supported signing algorithms](../signature-specification.md#algorithm-selection).
1. Check if `response.signingAlgorithm` is one of [supported signing algorithms](./signature-specification.md#algorithm-selection).
2. Check that the plugin did not modify `request.payload` before generating the signature, and the signature is valid for the given payload. Verify the hash of the `request.payload` against `response.signature`, using the public key of signing certificate (leaf certificate) in `response.certificateChain` along with the `response.signingAlgorithm`. This step does not include certificate chain validation (certificate chain leads to a trusted root configured in Notation's Trust Store), or revocation check.
3. Check that the `response.certificateChain` conforms to [Certificate Requirements](../signature-specification.md#certificate-requirements).
3. Check that the `response.certificateChain` conforms to [Certificate Requirements](./signature-specification.md#certificate-requirements).
5. Assemble the JWS Signature envelope using `response.signature`, `response.signingAlgorithm` and `response.certificateChain`. Notation may also generate and include timestamp signature in this step.
6. Generate a signature manifest for the given signature envelope.
2. Else if, plugin supports capability `SIGNATURE_GENERATOR.ENVELOPE` *(covered in next section)*
Expand Down Expand Up @@ -250,7 +250,7 @@ This command is used to get metadata for a given key.
}
```

*keySpec* : One of following [supported key types](../signature-specification.md#algorithm-selection) - `RSA-2048`, `RSA-3072`, `RSA-4096`, `EC-256`, `EC-384`, `EC-521`.
*keySpec* : One of following [supported key types](./signature-specification.md#algorithm-selection) - `RSA-2048`, `RSA-3072`, `RSA-4096`, `EC-256`, `EC-384`, `EC-521`.

NOTE: This command can also be used as part of `notation key describe {key-name}` which will include the following output

Expand Down Expand Up @@ -293,7 +293,7 @@ This command is used to generate the raw signature for a given payload.

*pluginConfig* : Optional field for plugin configuration. For details, see [Plugin Configuration section](#plugin-configuration).

*keySpec* : Required field that has one of following [supported key types](../signature-specification.md#algorithm-selection) - `RSA-2048`, `RSA-3072`, `RSA-4096`, `EC-256`, `EC-384`, `EC-521`. Specifies the key type and size for the key.
*keySpec* : Required field that has one of following [supported key types](./signature-specification.md#algorithm-selection) - `RSA-2048`, `RSA-3072`, `RSA-4096`, `EC-256`, `EC-384`, `EC-521`. Specifies the key type and size for the key.

*hashAlgorithm* : Required field that specifies Hash algorithm corresponding to the signature algorithm determined by `keySpec` for the key.

Expand All @@ -313,7 +313,7 @@ All response attributes are required.
}
```

*signingAlgorithm* : One of following [supported signing algorithms](../signature-specification.md#algorithm-selection), Notation uses this validate the signature, and to set the appropriate attribute in signature envelope (e.g. JWS `alg`). Supported values are
*signingAlgorithm* : One of following [supported signing algorithms](./signature-specification.md#algorithm-selection), Notation uses this validate the signature, and to set the appropriate attribute in signature envelope (e.g. JWS `alg`). Supported values are

* `RSASSA-PSS-SHA-256`: RSASSA-PSS with SHA-256
* `RSASSA-PSS-SHA-384`: RSASSA-PSS with SHA-384
Expand Down Expand Up @@ -345,12 +345,12 @@ This interface targets plugins that in addition to signature generation want to
1. Determine if the registered key uses a plugin
1. Execute the plugin with `get-plugin-metadata` command
1. If plugin supports capability `SIGNATURE_GENERATOR.ENVELOPE`
1. Execute the plugin with `generate-envelope` command. Set `request.keyId` and the optional `request.pluginConfig` to corresponding values associated with signing key `keyName` in `config.json`. Set `request.payload` to base64 encoded [Notary v2 Payload](../signature-specification.md#payload), `request.payloadType` to `application/vnd.cncf.notary.payload.v1+json` and `request.signatureEnvelopeType` to a pre-defined type (`application/jose+json` for JWS).
1. Execute the plugin with `generate-envelope` command. Set `request.keyId` and the optional `request.pluginConfig` to corresponding values associated with signing key `keyName` in `config.json`. Set `request.payload` to base64 encoded [Notary v2 Payload](./signature-specification.md#payload), `request.payloadType` to `application/vnd.cncf.notary.payload.v1+json` and `request.signatureEnvelopeType` to a pre-defined type (`application/jose+json` for JWS).
2. `response.signatureEnvelope` contains the base64 encoded signature envelope, value of `response.signatureEnvelopeType` MUST match `request.signatureEnvelopeType`.
3. Validate the generated signature, return an error if of the checks fails.
1. Check if `response.signatureEnvelopeType` is a supported envelope type and `response.signatureEnvelope`'s format matches `response.signatureEnvelopeType`.
2. Check if the signing algorithm in the signature envelope is one of [supported signing algorithms](../signature-specification.md#algorithm-selection).
3. Check that the [`targetArtifact` descriptor](../signature-specification.md#payload) in JWSPayload in `response.signatureEnvelope` matches `request.payload`. Plugins MAY append additional annotations but MUST NOT replace/override existing descriptor attributes and annotations.
2. Check if the signing algorithm in the signature envelope is one of [supported signing algorithms](./signature-specification.md#algorithm-selection).
3. Check that the [`targetArtifact` descriptor](./signature-specification.md#payload) in JWSPayload in `response.signatureEnvelope` matches `request.payload`. Plugins MAY append additional annotations but MUST NOT replace/override existing descriptor attributes and annotations.
4. Check that `response.signatureEnvelope` can be verified using the public key and signing algorithm specified in the signing certificate, which is embedded as part of certificate chain in `response.signatureEnvelope` . This step does not include certificate chain validation (certificate chain leads to a trusted root configure in Notation), or revocation check.
5. Check that the certificate chain in `response.signatureEnvelope` confirm to [Certificate Requirements].
4. Generate a signature manifest for the given signature envelope, and append `response.annotations` to manifest annotations.
Expand Down Expand Up @@ -395,7 +395,7 @@ All request attributes are required.
*expiryDurationInSeconds* : Optional field which contains signature expiry duration(in seconds) as integer number.

*signatureEnvelopeType* - defines the type of signature envelope expected from the plugin. As Notation clients need to be updated in order to parse and verify new signature formats, the default signature format can only be changed with new major version releases of Notation. Users however can opt into using an updated signature envelope format supported by Notation, by passing an optional parameter.
e.g. `notation sign $IMAGE --key {key-name} --envelope-type {some-new-type}`
e.g. `notation sign $IMAGE --key {key-name} --signature-format {some-new-type}`

*Response*
All response attributes are required.
Expand Down Expand Up @@ -429,13 +429,13 @@ All response attributes are required.
### Requirements

* The interface MUST NOT be tied to a specific signature envelope format.
* The interface MUST NOT allow a plugin to customize the complete [signature verification workflow](../trust-store-trust-policy-specification.md#signature-verification). Certain steps like identifying the applicable trust policy for the artifact, signature envelope schema validation, integrity checks, certificate chain validation against trust store will be performed by Notation, and cannot be customized by a plugin.
* The interface MUST NOT allow a plugin to customize the complete [signature verification workflow](./trust-store-trust-policy.md#signature-verification). Certain steps like identifying the applicable trust policy for the artifact, signature envelope schema validation, integrity checks, certificate chain validation against trust store will be performed by Notation, and cannot be customized by a plugin.
* The interface MUST allow plugins to customize verification logic for specific supported steps
* Trusted Identity validation
* Revocation check validation
* The interface MAY be extended in future to support additional steps which can be customized through a plugin.
* The interface MUST be agnostic of sequencing of steps in signature verification workflow as implemented in Notation or other implementations.
* The interface MUST allow processing of [extended attributes](../signature-specification.md#extended-attributes) that are not part of Notary v2 [standard attributes](../signature-specification.md#standard-attributes).
* The interface MUST allow processing of [extended attributes](./signature-specification.md#extended-attributes) that are not part of Notary v2 [standard attributes](./signature-specification.md#standard-attributes).

### Guidelines for Verification plugin publishers

Expand All @@ -459,11 +459,11 @@ This allows Notary v2 implementations to perform the same logic themselves, if t
3. Fail signature verification if these validations fail
3. Validate if plugin capabilities contains any `SIGNATURE_VERIFIER` capabilities
1. Fail signature verification if a matching plugin with `SIGNATURE_VERIFIER` capability cannot be found. Include *Verification Plugin Name* attribute as a hint in error response.
2. Complete steps *Identify applicable trust policy* and *Proceed based on signature verification level* from [signature verification workflow](../trust-store-trust-policy-specification.md#steps).
3. Complete steps *Validate Integrity, Validate Expiry* and *Validate Trust Store* from [signature verification workflow](../trust-store-trust-policy-specification.md#steps).
2. Complete steps *Identify applicable trust policy* and *Proceed based on signature verification level* from [signature verification workflow](./trust-store-trust-policy.md#steps).
3. Complete steps *Validate Integrity, Validate Expiry* and *Validate Trust Store* from [signature verification workflow](./trust-store-trust-policy.md#steps).
4. Based on the signature verification level, each validation may be enforced, logged or skipped.
5. Populate `verify-signature` request. NOTE: The processing order of remaining known attributes does not matter as long as they are processed before the end of signature verification workflow.
1. Set `request.signature.criticalAttributes` to the set of [standard Notary v2 attributes](../signature-specification.md#standard-attributes) that are marked critical, from the signature envelope.
1. Set `request.signature.criticalAttributes` to the set of [standard Notary v2 attributes](./signature-specification.md#standard-attributes) that are marked critical, from the signature envelope.
2. Set `request.signature.criticalAttributes.extendedAttributes` to extended attributes that Notation does not recognize. Notation only supports JSON primitive types for critical extended attributes. If a signature producer required complex types, it MUST set the value to a primitive type by encoding it (e.g. Base64), and MUST be decoded by the plugin which processed the attribute.
3. Set `request.signature.unprocessedAttributes` to set of critical attribute names that are marked critical, but unknown to Notation, and therefore cannot be processed by Notation.
4. Set `request.signature.certificateChain` to ordered array of certificates from signing envelope.
Expand All @@ -475,7 +475,7 @@ This allows Notary v2 implementations to perform the same logic themselves, if t
1. If `verificationResult.success` is true, proceed to next element.
2. Else if `verificationResult.success` is `false`, check if the failure should be enforced or logged based on value of `signatureVerification` level in Trust Policy. Proceed to next element if failure is logged, else fail signature verification with `verificationResult.reason`.
3. Validate values in `response.processedAttributes` match the set of values in `request.signature.unprocessedAttributes`. If they don't, fail signature verification, as the plugin did not process a critical attribute that is unknown to the caller.
7. Perform any remaining steps in [signature verification workflow](../trust-store-trust-policy-specification.md#signature-verification) which are not covered by plugin's verification capabilities. These steps MUST process any remaining critical attributes. Fail signature verification if any critical attributes are unprocessed at the end of this step.
7. Perform any remaining steps in [signature verification workflow](./trust-store-trust-policy.md#signature-verification) which are not covered by plugin's verification capabilities. These steps MUST process any remaining critical attributes. Fail signature verification if any critical attributes are unprocessed at the end of this step.

#### *verify-signature* command

Expand Down
2 changes: 1 addition & 1 deletion specs/signature-envelope-jws.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Signature Manifest Example

```jsonc
{
"mediaType": "application/vnd.cncf.oras.artifact.manifest.v1+json",
"mediaType": "application/vnd.oci.artifact.manifest.v1+json",
"artifactType": "application/vnd.cncf.notary.signature",
"blobs": [
{
Expand Down