# [Draft] Verification extensibility This is a continuation of [[Draft] Notation Extensibility for Signing and Verification](https://hackmd.io/jhYbA4aNRFW7nmp7gPTIBA?view) doc. ### Requirements - The plugin's verification API MUST be signature envelope format agnostic and MUST work seamlessly with different signature envelope formats. - If signature needs plugin for verification then the signature MUST convey plugin name and version required for verification. - During signature verification, if the required plugin is unavailable then Notary v2 MUST fails the signature verification. :::info PR Begins - **This is in early brainstorming stage** ::: **Plugin installation and config** * Using the signature metadata, the signature MUST specify weather a plugin is required for a signature verification or not. <Link to sig specification doc>. ```json= // Descriptor { "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:73c803930ea3ba1e54bc25c2bdc53edd0284c62ed651fe7b00369da519a3c333", "size": 16724, "annotations": { "org.cncf.notary.signature.plugin.identifier": "${name}-${version}", "org.cncf.notary.signature.plugin.required": "true | false", ... } } ``` **Plugin metadata** ```json= { // List of one or more capabilities supported by plugin. // SIGNATURE_GENERATOR and SIGNATURE_ENVELOPE_GENERATOR are mutually exclusive // only one can be specified. // SIGNATURE_GENERATOR // SIGNATURE_ENVELOPE_GENERATOR // SIGNATURE_VERIFIER "capabilities" : [ ] } ``` *capabilities* - This is list of major features supported by a plugin. Each capability such as `SIGNATURE_ENVELOPE_GENERATOR` requires one of more commands to be implemented by the plugin. When new features are available for plugins to implement, an implementation may choose to not implement it, and therefore will not include the feature in capabililies. Notation will evaluate the capability required to satisfy a user’s request, and reject the request if the plugin does not support the required capability. ## Verification interface **Requirements** * The interface MUST NOT be tied to a specific signature envelope format. Notation will support plugins to be developed against the *Signature Verifier* interface. These interface target abstraction levels that satisfy most plugin integration scenarios. ### Signature Verifier This interface allows a plugin publisher to perform custom validations on the artifact's signature. The custom validations supplements the default notary v2 signature validations. The plugin must ve signature envelope format agnostic but should have access to all the . During signature verification, if the required plugin is unavailable then Notary v2 MUST fails the signature verification. This interface allows plugins to have full control over the generated signature envelope, and can append additional signed and unsigned metadata, including timestamp signatures. The plugin must be signature envelope format aware, and implement new formats when Notary adopts new formats. **Signing workflow using plugin** 1. Given a user request to sign `image`, with `key` 1. Pull the image manifest using `image` url, and construct a descriptor 1. Append any user provided metadata and Notary metadata as descriptor annotations. 1. Determine if the registered key uses a plugin 1. Execute the plugin with `discover` command 1. If plugin supports capability `SIGNATURE_ENVELOPE_GENERATOR` 1. Execute the plugin with `generate-envelope` command, set `request.key` to key definition (from `/notation/config.json`), `request.payload` to base64 encoded descriptor, `request.payloadType` to `application/vnd.oci.descriptor.v1+json` and `request.signatureEnvelopeType` to `application/vnd.cncf.notary.v2.jws.v1`. 1. `response.signatureEnvelope` contains the base64 encoded signature envelope, value of `response.signatureEnvelopeType` MUST match request.signatureEnvelopeType. 1. Generate a signature manifest for the given signature envelope, and append `response.annotations` to manifest annotations. 1. Else if plugin supports capability `SIGNATURE_GENERATOR` *(covered in previous section)* 1. Return an error **generate-envelope** *Request* ```JSON= { "contract-version" : <major-version.minor-version>, // Complete key definition from /notation/config.JSON /signingKeys/keys with matching key name "key" : <key definition>, "payload" : <Base64 encoded payload to be signed>, // The type of payload - currently a descriptor "payloadType" : "application/vnd.oci.descriptor.v1+json", // The expected response signature envelope "signatureEnvelopeType" : "application/vnd.cncf.notary.v2.jws.v1" } ``` *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 format supported by Notation, by passing an optional parameter. e.g. `notation sign $IMAGE --key {key-name} --signatureFormat {some-new-format}` *Response* ```JSON= { "signatureEnvelope": <Base64 encoded signature envelope>, "signatureEnvelopeType" : "application/vnd.cncf.notary.v2.jws.v1" // Annotations to be appended to Signature Manifest annotations "annotations" : { "key1" : "value1", "key2" : "value2" } } ``` ---- This interface allows a plugin publisher to perform custom validations on the artifact's signature. The custom validations supplements the default notary v2 signature validations. The plugin is signature envelope format agnostic. During signature verification, if the required plugin is unavailable then Notary v2 MUST fails the signature verification. ##### verify-signature** *Request* ```JSON= { // The version of verify-signature interface "version": "<major-version.minor-version>", // The complete key definition from /notation/config.JSON "key": "<keydefinition>", "signature": { // The signature envelope type - currently JWS "envelopeType": "application/jose+json" // The version of the signature envelope "version": "application/vnd.cncf.notary.v2.jws.v1", // The signature algoritm "algorithm": "<signature-algorithm>", // The signed playload "payload": "<Base64 encoded signed payload>", // The type of payload - currently a descriptor "payloadType": "application/vnd.oci.descriptor.v1+json", // The siged metadata "signedAttributes": { "notary": { "iat": <signing-time>, "exp": <signature-expiration-time> } }, // The list of signing certificate used for signature verification "x509SigningCcertificates": [], // The list of timestamping certificate used for timestamp verification "x509TimestampingCertificates": [] }, // The repository URI of the artifact "artifactUri": "", // The complete trust policy with trust store inlined used for siganture evaluation "trustPolicy": "" } ``` *signatureEnvelopeType* - defines the type of signature envelope expected from the plugin. As updated Notation clients are required to understand 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 format supported by Notation, by passing an optional parameter. e.g. `notation sign $IMAGE --key {key-name} --signatureFormat {some-new-format}` *Response* The ```JSON= { "warnings": [ "<line1>", "<line2>", "<line3>" ] } ``` Plugin exit codes: - zero - non-zero CLI exit codes: - 0 - 1 notary v2 verificaiton failed. - 2 plugin failed. :::info PR Ends ::: ### Helpful links - https://github.com/wp-cli/wp-cli/issues/3577 - https://tldp.org/LDP/abs/html/exitcodes.html ### Milind - define error resposne; warning? - `describe-key` should not be tied to signature generation