From 7601d4b31d8634de9bfc82ea4dac191d277a3b28 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Tue, 9 Jan 2024 16:07:33 -0500 Subject: [PATCH 01/13] Adding proposed release attestation Signed-off-by: Zach Steindler --- spec/predicates/README.md | 2 + spec/predicates/release.md | 95 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 spec/predicates/release.md diff --git a/spec/predicates/README.md b/spec/predicates/README.md index 6c8d963b..b1977d48 100644 --- a/spec/predicates/README.md +++ b/spec/predicates/README.md @@ -24,11 +24,13 @@ our [vetting process], and may be of general interest: - [SPDX]: SPDX-formatted BOM for software artifacts. - [CycloneDX]: CycloneDX BOM for software artifacts. - [Vulnerability]: Defines the metadata to share the results of vulnerability scanning on software artifacts. +- [Release]: Details an artifact that is part of a given release version. - [Test Result]: A generic schema to express results of any type of tests. [CycloneDX]: https://cyclonedx.org/ [Link]: link.md [New Predicate Guidelines]: ../../docs/new_predicate_guidelines.md +[Release]: release.md [Runtime Traces]: runtime-trace.md [SCAI Report]: scai.md [Vulnerability]: vuln.md diff --git a/spec/predicates/release.md b/spec/predicates/release.md new file mode 100644 index 00000000..a4c0cf64 --- /dev/null +++ b/spec/predicates/release.md @@ -0,0 +1,95 @@ +# Predicate type: Release + +Type URI: https://in-toto.io/attestation/release + +Version 0.1 + +## Purpose + +To authoritatively link from a specific release name and version string in a registry, to the artifact names and hashes that make up that release. + +## Use Cases + +When receiving a new release version, package registries can publish a release attestation covering the artifact names and hashes that make up that release. This allows consumers of that release version to ensure the artifacts they are consuming have not been tampered with. + +If these release attestations are optionally published to a transparency log, package authors (or other interested parties) can monitor when a new version of a package is released. + +These use cases are not hypothetical; both of them are the case today for npm's [build provenance feature], which includes a [publish attestation]. Note that while npm calls this a publish attestation, calling it a release attestation better reflects that it's coming from the package registry. Publishing often refers to an author sending content to the registry, as in [PyPI's trusted publishers feature]. + +## Prerequisites + +This predicate depends on the [in-toto attestation framework], as well as the [purl-spec] for identifying packaging ecosystems. + +Perhaps surprisingly, this predicate does not depend on [SLSA Provenance], but they are better together. In an ecosystem where some (but not all) packages have SLSA Provenance and you query by artifact hash, you can't tell the difference between an artifact that has been tampered with and one that does not yet have SLSA provenance. If the ecosystem has release attestations, you can give authoritative answers to what artifacts make up a given release version, and what hashes those artifacts should have. + +## Model + +This predicate is for the final stages of the software supply chain, where consumers are looking for attestations that the software has not been tampered with during distribution. + +## Schema + +### Fields + +- **purl, required** string (ResourceURI) + - A purl uniquely identifying a specific release name and version from a package registry. + +### Parsing Rules + +The purl field MUST be parsed using the [purl-spec]. It MUST include a version (which is OPTIONAL in the [purl-spec]). + +## Example + +```json +{ + "_type": "https://in-toto.io/Statement/v1", + "subject": [ + { + "name": "@scope/my-package", + "digest": { + "sha256": "deadbeef0123456789..." + } + } + ], + "predicateType": "https://in-toto.io/attestation/release/v0.1", + "predicate": { + "purl": "pkg:npm/@scope/my-package@1.2.3", + } +} +``` + +If a release has multiple artifacts that might be consumed separately, the attestation SHOULD have a subject per artifact: + +```json +{ + "_type": "https://in-toto.io/Statement/v1", + "subject": [ + { + "name": "urllib3-2.1.0.tar.gz", + "digest": { + "sha256": "df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" + } + }, + { + "name": "urllib3-2.1.0-py3-none-any.whl", + "digest": { + "sha256": "55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", + } + } + ], + "predicateType": "https://in-toto.io/attestation/release/v0.1", + "predicate": { + "purl": "pkg:pypi/urllib3@2.1.0" + } +} +``` + +## Changelog and Migrations + +As this is the initial version, no changes or migrations to previous versions. This proposal is a subset of the information in the existing npm [publish attestation], so npm could easily migrate to this specification. + +[build provenance feature]: https://github.blog/2023-04-19-introducing-npm-package-provenance/ +[publish attestation]: https://github.com/npm/attestation/tree/main/specs/publish/v0.1 +[PyPI's trusted publishers feature]: https://github.com/npm/attestation/tree/main/specs/publish/v0.1 +[in-toto attestation framework]: ../README.md +[purl-spec]: https://github.com/package-url/purl-spec +[SLSA Provenance]: https://slsa.dev/provenance From 3819a067f789423b08fbec043877d4d4cf181333 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Fri, 19 Jan 2024 11:52:09 -0500 Subject: [PATCH 02/13] Make name field explicitly a filename as it would appear on disk Signed-off-by: Zach Steindler --- spec/predicates/release.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/spec/predicates/release.md b/spec/predicates/release.md index a4c0cf64..23cd4bae 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -30,6 +30,9 @@ This predicate is for the final stages of the software supply chain, where consu ### Fields +- **name, required** string + - The filename of the artifact as it would appear on disk. + - **purl, required** string (ResourceURI) - A purl uniquely identifying a specific release name and version from a package registry. @@ -44,15 +47,15 @@ The purl field MUST be parsed using the [purl-spec]. It MUST include a version ( "_type": "https://in-toto.io/Statement/v1", "subject": [ { - "name": "@scope/my-package", + "name": "http-7.2.16.tgz "digest": { - "sha256": "deadbeef0123456789..." + "sha256": "4faeb1b21ad0612c1553752dffe2ec006020ef3914b0e9ff7315ca77121b79a5" } } ], "predicateType": "https://in-toto.io/attestation/release/v0.1", "predicate": { - "purl": "pkg:npm/@scope/my-package@1.2.3", + "purl": "pkg:npm/@angular/http@7.2.16", } } ``` From fbe86332a33f19792a4a70ea9399e4a3d0c98abb Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Fri, 19 Jan 2024 11:53:26 -0500 Subject: [PATCH 03/13] fix typo Signed-off-by: Zach Steindler --- spec/predicates/release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/predicates/release.md b/spec/predicates/release.md index 23cd4bae..6bc8eceb 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -47,7 +47,7 @@ The purl field MUST be parsed using the [purl-spec]. It MUST include a version ( "_type": "https://in-toto.io/Statement/v1", "subject": [ { - "name": "http-7.2.16.tgz + "name": "http-7.2.16.tgz", "digest": { "sha256": "4faeb1b21ad0612c1553752dffe2ec006020ef3914b0e9ff7315ca77121b79a5" } From 91bfd9f7b0a681deb9a2db2435035c0ed2f414f5 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Fri, 19 Jan 2024 15:46:46 -0500 Subject: [PATCH 04/13] Clarify immutability, subject, and purl parsing Signed-off-by: Zach Steindler --- spec/predicates/release.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/predicates/release.md b/spec/predicates/release.md index 6bc8eceb..a56bb7d5 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -26,19 +26,23 @@ Perhaps surprisingly, this predicate does not depend on [SLSA Provenance], but t This predicate is for the final stages of the software supply chain, where consumers are looking for attestations that the software has not been tampered with during distribution. +If a registry supports immutable releases, there MUST be one release attestation for a given `predicate.purl`. + +Even if the registry does not support immutable releases, the attestation subject SHOULD include all the artifacts associated with the release; otherwise it will be unclear if an artifact was later removed from a release. + ## Schema ### Fields -- **name, required** string +- **`subject.name`** string - The filename of the artifact as it would appear on disk. -- **purl, required** string (ResourceURI) +- **`predicate.purl`, required** string (ResourceURI) - A purl uniquely identifying a specific release name and version from a package registry. ### Parsing Rules -The purl field MUST be parsed using the [purl-spec]. It MUST include a version (which is OPTIONAL in the [purl-spec]). +The purl field MUST be parsed using the [purl-spec]. It MUST include a purl `version` (which is OPTIONAL in the [purl-spec]). It SHOULD NOT include purl `qualifiers` or `subpath`, unless the `type` requires them to uniquely identify a release (as a counter-example `type:oci` would include `qualifiers`). ## Example From ba2068e375c8912da33874a3d399060a1825bd24 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Mon, 22 Jan 2024 09:56:00 -0500 Subject: [PATCH 05/13] Soften registry requirements, add security clarification, and add releaseId Signed-off-by: Zach Steindler --- spec/predicates/release.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/spec/predicates/release.md b/spec/predicates/release.md index a56bb7d5..93ba5fe4 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -10,10 +10,12 @@ To authoritatively link from a specific release name and version string in a reg ## Use Cases -When receiving a new release version, package registries can publish a release attestation covering the artifact names and hashes that make up that release. This allows consumers of that release version to ensure the artifacts they are consuming have not been tampered with. +When receiving a new release version, package registries can publish a release attestation covering the artifact names and hashes that make up that release. This allows consumers of that release version to ensure the artifacts they are consuming have not been modified, no matter how many network links or intermediate caches were used to acquire the artifact. If these release attestations are optionally published to a transparency log, package authors (or other interested parties) can monitor when a new version of a package is released. +The release attestation provides integrity for the release artifacts, but it does not provide availability as it does not require the registry to serve an attested release artifact. + These use cases are not hypothetical; both of them are the case today for npm's [build provenance feature], which includes a [publish attestation]. Note that while npm calls this a publish attestation, calling it a release attestation better reflects that it's coming from the package registry. Publishing often refers to an author sending content to the registry, as in [PyPI's trusted publishers feature]. ## Prerequisites @@ -26,9 +28,11 @@ Perhaps surprisingly, this predicate does not depend on [SLSA Provenance], but t This predicate is for the final stages of the software supply chain, where consumers are looking for attestations that the software has not been tampered with during distribution. -If a registry supports immutable releases, there MUST be one release attestation for a given `predicate.purl`. +If a previously attested release is later determined to be untrustworthy, a registry MAY stop serving the artifacts associated with that release. + +If a registry supports immutable releases, there SHOULD be one release attestation for a given `predicate.purl`. -Even if the registry does not support immutable releases, the attestation subject SHOULD include all the artifacts associated with the release; otherwise it will be unclear if an artifact was later removed from a release. +Even if the registry does not support immutable releases, the attestation subject SHOULD include all the artifacts associated with the release at that time; otherwise it will be unclear if an artifact was later removed from a release. For example, if a release version has an initial release attestation with artifact A, and then later has a release attestation with only artifact B, that SHOULD be interpreted as the release version now only containing artifact B. ## Schema @@ -40,6 +44,9 @@ Even if the registry does not support immutable releases, the attestation subjec - **`predicate.purl`, required** string (ResourceURI) - A purl uniquely identifying a specific release name and version from a package registry. +- **`predicate.releaseId`** string + - Stable identifier for a release; this should remain unchanged between release versions (e.g. it's associated with urllib3, not urllib3 v2.1.0). This will allow users to confirm that a release has moved to a new name, and prevent confusion if the old name is re-used. This could be an automatically incrementing database key or a randomly generated UUID. + ### Parsing Rules The purl field MUST be parsed using the [purl-spec]. It MUST include a purl `version` (which is OPTIONAL in the [purl-spec]). It SHOULD NOT include purl `qualifiers` or `subpath`, unless the `type` requires them to uniquely identify a release (as a counter-example `type:oci` would include `qualifiers`). @@ -60,6 +67,7 @@ The purl field MUST be parsed using the [purl-spec]. It MUST include a purl `ver "predicateType": "https://in-toto.io/attestation/release/v0.1", "predicate": { "purl": "pkg:npm/@angular/http@7.2.16", + "releaseId": 1234567890 } } ``` From 87499fd1689987525d9766397bf8d649caf9ecfe Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Tue, 23 Jan 2024 16:13:44 -0500 Subject: [PATCH 06/13] Adding proto definition, clarifying language, adding links, reflowing text Signed-off-by: Zach Steindler --- .../predicates/release/v1/release.proto | 11 ++ spec/predicates/release.md | 123 +++++++++++++----- 2 files changed, 101 insertions(+), 33 deletions(-) create mode 100644 protos/in_toto_attestation/predicates/release/v1/release.proto diff --git a/protos/in_toto_attestation/predicates/release/v1/release.proto b/protos/in_toto_attestation/predicates/release/v1/release.proto new file mode 100644 index 00000000..144c60fc --- /dev/null +++ b/protos/in_toto_attestation/predicates/release/v1/release.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package in_toto_attestation.predicates.release.v1; + +option go_package = "github.com/in-toto/attestation/go/predicates/release/v1"; +option java_package = "io.github.intoto.attestation.predicates.release.v1"; + +message Release { + string purl = 1; + optional string release_id = 2; +} diff --git a/spec/predicates/release.md b/spec/predicates/release.md index 93ba5fe4..389324d0 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -2,54 +2,105 @@ Type URI: https://in-toto.io/attestation/release -Version 0.1 +Version 1 ## Purpose -To authoritatively link from a specific release name and version string in a registry, to the artifact names and hashes that make up that release. +To authoritatively link from a specific release name and version string in a +package registry, to the artifact names and hashes that make up that release. ## Use Cases -When receiving a new release version, package registries can publish a release attestation covering the artifact names and hashes that make up that release. This allows consumers of that release version to ensure the artifacts they are consuming have not been modified, no matter how many network links or intermediate caches were used to acquire the artifact. - -If these release attestations are optionally published to a transparency log, package authors (or other interested parties) can monitor when a new version of a package is released. - -The release attestation provides integrity for the release artifacts, but it does not provide availability as it does not require the registry to serve an attested release artifact. - -These use cases are not hypothetical; both of them are the case today for npm's [build provenance feature], which includes a [publish attestation]. Note that while npm calls this a publish attestation, calling it a release attestation better reflects that it's coming from the package registry. Publishing often refers to an author sending content to the registry, as in [PyPI's trusted publishers feature]. +When receiving a new release version, package registries can publish a release +attestation covering the artifact names and hashes that make up that release. +This allows consumers of that release version to ensure the artifacts they are +consuming have not been modified, no matter how many network links or +intermediate caches were used to acquire the artifact. + +If these release attestations are optionally published to a transparency log, +package authors (or other interested parties) can monitor when a new version of +a package is released. + +The release attestation provides integrity for the release artifacts, but it +does not provide availability as it does not require the registry to serve an +attested release artifact that is later determined to be untrustworthy. + +These use cases are not hypothetical; both of them are the case today for npm's +[build provenance feature], which includes a [publish attestation]. Note that +while npm calls this a publish attestation, calling it a release attestation +better reflects that it's coming from the package registry. Publishing often +refers to an author sending content to the registry, as in +[PyPI's trusted publishers feature]. + +Perhaps surprisingly, this predicate does not depend on [SLSA Provenance], but +they are better together. In an ecosystem where some (but not all) packages +have SLSA Provenance and you query by artifact hash, you can't tell the +difference between an artifact that has been tampered with and one that does +not yet have SLSA provenance. If the ecosystem has release attestations, you +can give authoritative answers to what artifacts make up a given release +version, and what hashes those artifacts should have. ## Prerequisites -This predicate depends on the [in-toto attestation framework], as well as the [purl-spec] for identifying packaging ecosystems. - -Perhaps surprisingly, this predicate does not depend on [SLSA Provenance], but they are better together. In an ecosystem where some (but not all) packages have SLSA Provenance and you query by artifact hash, you can't tell the difference between an artifact that has been tampered with and one that does not yet have SLSA provenance. If the ecosystem has release attestations, you can give authoritative answers to what artifacts make up a given release version, and what hashes those artifacts should have. +This predicate depends on the [in-toto Attestation Framework], as well as the +[purl-spec] for identifying packaging ecosystems. ## Model -This predicate is for the final stages of the software supply chain, where consumers are looking for attestations that the software has not been tampered with during distribution. +This predicate is for the final stages of the software supply chain, where +consumers are looking for attestations that the software has not been tampered +with during distribution. -If a previously attested release is later determined to be untrustworthy, a registry MAY stop serving the artifacts associated with that release. +If a registry supports immutable releases, there SHOULD be one release +attestation for a given `predicate.purl`. -If a registry supports immutable releases, there SHOULD be one release attestation for a given `predicate.purl`. - -Even if the registry does not support immutable releases, the attestation subject SHOULD include all the artifacts associated with the release at that time; otherwise it will be unclear if an artifact was later removed from a release. For example, if a release version has an initial release attestation with artifact A, and then later has a release attestation with only artifact B, that SHOULD be interpreted as the release version now only containing artifact B. +Even if the registry does not support immutable releases, the attestation +subject SHOULD include all the artifacts associated with the release at that +time; otherwise it will be unclear if an artifact was later removed from a +release. For example, if a release version has an initial release attestation +with artifact A, and then later has a release attestation with only artifact B, +that SHOULD be interpreted as the release version now only containing artifact +B. ## Schema +```json +{ + // Standard attestation fields: + "_type": "https://in-toto.io/Statement/v1", + "subject": [{ ... }], + + // Predicate: + "predicateType": "https://in-toto.io/attestation/release/v1", + "predicate": { + "purl": , + "releaseId": "..." + } +} +``` + ### Fields - **`subject.name`** string - The filename of the artifact as it would appear on disk. -- **`predicate.purl`, required** string (ResourceURI) - - A purl uniquely identifying a specific release name and version from a package registry. +- **`predicate.purl`, required** string ([ResourceURI]) + - A purl uniquely identifying a specific release name and version from a + package registry. - **`predicate.releaseId`** string - - Stable identifier for a release; this should remain unchanged between release versions (e.g. it's associated with urllib3, not urllib3 v2.1.0). This will allow users to confirm that a release has moved to a new name, and prevent confusion if the old name is re-used. This could be an automatically incrementing database key or a randomly generated UUID. + - Stable identifier for a release; this should remain unchanged between + release versions (e.g. it's associated with urllib3, not urllib3 v2.1.0). + This will allow users to confirm that a release has moved to a new name, + and prevent confusion if the old name is re-used. This could be an + automatically incrementing database key or a randomly generated UUID. ### Parsing Rules -The purl field MUST be parsed using the [purl-spec]. It MUST include a purl `version` (which is OPTIONAL in the [purl-spec]). It SHOULD NOT include purl `qualifiers` or `subpath`, unless the `type` requires them to uniquely identify a release (as a counter-example `type:oci` would include `qualifiers`). +The purl field MUST be parsed using the [purl-spec]. It MUST include a purl +`version` (which is OPTIONAL in the [purl-spec]). It SHOULD NOT include purl +`qualifiers` or `subpath`, unless the `type` requires them to uniquely identify +a release (as a counter-example `type:oci` would include `qualifiers`). ## Example @@ -60,11 +111,11 @@ The purl field MUST be parsed using the [purl-spec]. It MUST include a purl `ver { "name": "http-7.2.16.tgz", "digest": { - "sha256": "4faeb1b21ad0612c1553752dffe2ec006020ef3914b0e9ff7315ca77121b79a5" + "sha256": "4faeb1b2..." } } ], - "predicateType": "https://in-toto.io/attestation/release/v0.1", + "predicateType": "https://in-toto.io/attestation/release/v1", "predicate": { "purl": "pkg:npm/@angular/http@7.2.16", "releaseId": 1234567890 @@ -72,7 +123,8 @@ The purl field MUST be parsed using the [purl-spec]. It MUST include a purl `ver } ``` -If a release has multiple artifacts that might be consumed separately, the attestation SHOULD have a subject per artifact: +If a release has multiple artifacts that might be consumed separately, the +attestation SHOULD have a subject per artifact: ```json { @@ -81,17 +133,17 @@ If a release has multiple artifacts that might be consumed separately, the attes { "name": "urllib3-2.1.0.tar.gz", "digest": { - "sha256": "df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54" + "sha256": "df7aa8af..." } }, { "name": "urllib3-2.1.0-py3-none-any.whl", "digest": { - "sha256": "55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3", + "sha256": "55901e91...", } } ], - "predicateType": "https://in-toto.io/attestation/release/v0.1", + "predicateType": "https://in-toto.io/attestation/release/v1", "predicate": { "purl": "pkg:pypi/urllib3@2.1.0" } @@ -100,11 +152,16 @@ If a release has multiple artifacts that might be consumed separately, the attes ## Changelog and Migrations -As this is the initial version, no changes or migrations to previous versions. This proposal is a subset of the information in the existing npm [publish attestation], so npm could easily migrate to this specification. +As this is the initial version, no changes or migrations to previous versions. +This proposal is a subset of the information in the existing npm +[publish attestation], so npm could easily migrate to this specification. -[build provenance feature]: https://github.blog/2023-04-19-introducing-npm-package-provenance/ -[publish attestation]: https://github.com/npm/attestation/tree/main/specs/publish/v0.1 -[PyPI's trusted publishers feature]: https://github.com/npm/attestation/tree/main/specs/publish/v0.1 -[in-toto attestation framework]: ../README.md -[purl-spec]: https://github.com/package-url/purl-spec +[build provenance feature]: +https://github.blog/2023-04-19-introducing-npm-package-provenance/ +[publish attestation]: +https://github.com/npm/attestation/tree/main/specs/publish/v0.1 +[PyPI's trusted publishers feature]: https://docs.pypi.org/trusted-publishers/ [SLSA Provenance]: https://slsa.dev/provenance +[in-toto Attestation Framework]: ../README.md +[purl-spec]: https://github.com/package-url/purl-spec +[ResourceURI]: ../v1/field_types.md#resourceuri From 4fc169d537997b4f46d85c80670a3e20c9824d26 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Tue, 23 Jan 2024 16:15:56 -0500 Subject: [PATCH 07/13] Adjusting spec to use jsonc Signed-off-by: Zach Steindler --- spec/predicates/release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/predicates/release.md b/spec/predicates/release.md index 389324d0..b2b0e4d5 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -64,7 +64,7 @@ B. ## Schema -```json +```jsonc { // Standard attestation fields: "_type": "https://in-toto.io/Statement/v1", From d180f182e4101325f5e7f484eeb817075a5a4d76 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Thu, 25 Jan 2024 11:01:20 -0500 Subject: [PATCH 08/13] Reformat Fields for linter; put version back at v0.1 Signed-off-by: Zach Steindler --- .../release/{v1 => v0}/release.proto | 6 ++-- spec/predicates/release.md | 33 ++++++++++--------- 2 files changed, 21 insertions(+), 18 deletions(-) rename protos/in_toto_attestation/predicates/release/{v1 => v0}/release.proto (74%) diff --git a/protos/in_toto_attestation/predicates/release/v1/release.proto b/protos/in_toto_attestation/predicates/release/v0/release.proto similarity index 74% rename from protos/in_toto_attestation/predicates/release/v1/release.proto rename to protos/in_toto_attestation/predicates/release/v0/release.proto index 144c60fc..54c98bd4 100644 --- a/protos/in_toto_attestation/predicates/release/v1/release.proto +++ b/protos/in_toto_attestation/predicates/release/v0/release.proto @@ -1,9 +1,9 @@ syntax = "proto3"; -package in_toto_attestation.predicates.release.v1; +package in_toto_attestation.predicates.release.v0; -option go_package = "github.com/in-toto/attestation/go/predicates/release/v1"; -option java_package = "io.github.intoto.attestation.predicates.release.v1"; +option go_package = "github.com/in-toto/attestation/go/predicates/release/v0"; +option java_package = "io.github.intoto.attestation.predicates.release.v0"; message Release { string purl = 1; diff --git a/spec/predicates/release.md b/spec/predicates/release.md index b2b0e4d5..7f637708 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -2,7 +2,7 @@ Type URI: https://in-toto.io/attestation/release -Version 1 +Version 0.1 ## Purpose @@ -71,7 +71,7 @@ B. "subject": [{ ... }], // Predicate: - "predicateType": "https://in-toto.io/attestation/release/v1", + "predicateType": "https://in-toto.io/attestation/release/v0.1", "predicate": { "purl": , "releaseId": "..." @@ -81,19 +81,22 @@ B. ### Fields -- **`subject.name`** string - - The filename of the artifact as it would appear on disk. +**`subject.name`** string -- **`predicate.purl`, required** string ([ResourceURI]) - - A purl uniquely identifying a specific release name and version from a - package registry. +The filename of the artifact as it would appear on disk. -- **`predicate.releaseId`** string - - Stable identifier for a release; this should remain unchanged between - release versions (e.g. it's associated with urllib3, not urllib3 v2.1.0). - This will allow users to confirm that a release has moved to a new name, - and prevent confusion if the old name is re-used. This could be an - automatically incrementing database key or a randomly generated UUID. +**`predicate.purl`, required** string ([ResourceURI]) + +A purl uniquely identifying a specific release name and version from a package +registry. + +**`predicate.releaseId`** string + +Stable identifier for a release; this should remain unchanged between release +versions (e.g. it's associated with urllib3, not urllib3 v2.1.0). This will +allow users to confirm that a release has moved to a new name, and prevent +confusion if the old name is re-used. This could be an automatically +incrementing database key or a randomly generated UUID. ### Parsing Rules @@ -115,7 +118,7 @@ a release (as a counter-example `type:oci` would include `qualifiers`). } } ], - "predicateType": "https://in-toto.io/attestation/release/v1", + "predicateType": "https://in-toto.io/attestation/release/v0.1", "predicate": { "purl": "pkg:npm/@angular/http@7.2.16", "releaseId": 1234567890 @@ -143,7 +146,7 @@ attestation SHOULD have a subject per artifact: } } ], - "predicateType": "https://in-toto.io/attestation/release/v1", + "predicateType": "https://in-toto.io/attestation/release/v0.1", "predicate": { "purl": "pkg:pypi/urllib3@2.1.0" } From b77b19cd681142d1fe26faf681b9f2ddccf339bb Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Thu, 25 Jan 2024 14:31:38 -0500 Subject: [PATCH 09/13] Add migration example Signed-off-by: Zach Steindler --- spec/predicates/release.md | 49 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/spec/predicates/release.md b/spec/predicates/release.md index 7f637708..d320ff48 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -156,8 +156,53 @@ attestation SHOULD have a subject per artifact: ## Changelog and Migrations As this is the initial version, no changes or migrations to previous versions. -This proposal is a subset of the information in the existing npm -[publish attestation], so npm could easily migrate to this specification. +The required predicates in this specification are a subset of the information +in the existing npm [publish attestation], so npm could easily migrate to this +specification. + +For example, here is an existing npm publish attestation: + +```json +{ + "_type": "https://in-toto.io/Statement/v0.1", + "subject": [ + { + "name": "pkg:npm/semver@7.5.4", + "digest": { + "sha512": "d5b09211..." + } + ], + "predicateType": + "https://github.com/npm/attestation/tree/main/specs/publish/v0.1", + "predicate": { + "name": "semver", + "version": "7.5.4", + "registry": "https://registry.npmjs.org" + } +} +``` + +And this is what it would look like as a release attestation: + +```jsonc +{ + "_type": "https://in-toto.io/Statement/v0.1", + "subject": [ + { + // The subject.name value is from the publish attestation subject.name: + // take the purl name and version to construct "-.tgz" + "name": "semver-7.5.4.tgz", + "digest": { + "sha512": "d5b09211..." + } + ], + "predicateType": "https://in-toto.io/attestation/release/v0.1", + "predicate": { + // The predicate.purl value is from the publish attestation subject.name + "purl": "pkg:npm/semver@7.5.4" + } +} +``` [build provenance feature]: https://github.blog/2023-04-19-introducing-npm-package-provenance/ From 1e625077d70e42fbf22f54113b93bf1b198d3ab4 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Thu, 25 Jan 2024 14:33:05 -0500 Subject: [PATCH 10/13] fix formatting Signed-off-by: Zach Steindler --- spec/predicates/release.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/predicates/release.md b/spec/predicates/release.md index d320ff48..1139727b 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -171,6 +171,7 @@ For example, here is an existing npm publish attestation: "digest": { "sha512": "d5b09211..." } + } ], "predicateType": "https://github.com/npm/attestation/tree/main/specs/publish/v0.1", @@ -195,6 +196,7 @@ And this is what it would look like as a release attestation: "digest": { "sha512": "d5b09211..." } + } ], "predicateType": "https://in-toto.io/attestation/release/v0.1", "predicate": { From 4731908b14823a562f169a9af069cd056874e427 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Fri, 26 Jan 2024 09:18:28 -0500 Subject: [PATCH 11/13] fix typos Signed-off-by: Zach Steindler --- spec/predicates/release.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/predicates/release.md b/spec/predicates/release.md index 1139727b..f9687c04 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -156,7 +156,7 @@ attestation SHOULD have a subject per artifact: ## Changelog and Migrations As this is the initial version, no changes or migrations to previous versions. -The required predicates in this specification are a subset of the information +The required fields in this specification are a subset of the information in the existing npm [publish attestation], so npm could easily migrate to this specification. @@ -164,7 +164,7 @@ For example, here is an existing npm publish attestation: ```json { - "_type": "https://in-toto.io/Statement/v0.1", + "_type": "https://in-toto.io/Statement/v1", "subject": [ { "name": "pkg:npm/semver@7.5.4", @@ -187,7 +187,7 @@ And this is what it would look like as a release attestation: ```jsonc { - "_type": "https://in-toto.io/Statement/v0.1", + "_type": "https://in-toto.io/Statement/v1", "subject": [ { // The subject.name value is from the publish attestation subject.name: From c4ac317b2d19a23ee7ffdbada97473c040c64fb1 Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Mon, 5 Feb 2024 14:41:17 -0500 Subject: [PATCH 12/13] Clarify UUID generation; add container image example Signed-off-by: Zach Steindler --- spec/predicates/release.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/spec/predicates/release.md b/spec/predicates/release.md index f9687c04..7c3b11a0 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -96,7 +96,8 @@ Stable identifier for a release; this should remain unchanged between release versions (e.g. it's associated with urllib3, not urllib3 v2.1.0). This will allow users to confirm that a release has moved to a new name, and prevent confusion if the old name is re-used. This could be an automatically -incrementing database key or a randomly generated UUID. +incrementing database key, or a UUID that is initially randomly generated and +then durably associated with the release name. ### Parsing Rules @@ -105,7 +106,7 @@ The purl field MUST be parsed using the [purl-spec]. It MUST include a purl `qualifiers` or `subpath`, unless the `type` requires them to uniquely identify a release (as a counter-example `type:oci` would include `qualifiers`). -## Example +## Examples ```json { @@ -153,6 +154,26 @@ attestation SHOULD have a subject per artifact: } ``` +Here's what a release with a container images looks like: + +```json +{ + "_type": "https://in-toto.io/Statement/v1", + "subject": [ + { + "name": "registry.example.com/my-project/my-image", + "digest": { + "sha256": "fedcba09..." + } + } + ], + "predicateType": "https://in-toto.io/attestation/release/v0.1", + "predicate": { + "purl": "pkg:oci/my-image@sha256%3Afedcba09?repository_url=registry.example.com/my-project/my-image&tag=v1.2.3" + } +} +``` + ## Changelog and Migrations As this is the initial version, no changes or migrations to previous versions. From 1b2157416385a1c868d41791bbd824398b7e841f Mon Sep 17 00:00:00 2001 From: Zach Steindler Date: Mon, 5 Feb 2024 15:09:31 -0500 Subject: [PATCH 13/13] Update spec/predicates/release.md Co-authored-by: Marcela Melara Signed-off-by: Zach Steindler --- spec/predicates/release.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/predicates/release.md b/spec/predicates/release.md index 7c3b11a0..38e35903 100644 --- a/spec/predicates/release.md +++ b/spec/predicates/release.md @@ -154,7 +154,7 @@ attestation SHOULD have a subject per artifact: } ``` -Here's what a release with a container images looks like: +Here's what a release with a container image looks like: ```json {