diff --git a/Documentation/Registry.md b/Documentation/Registry.md index 6e12a2ca0a4..06663684d81 100644 --- a/Documentation/Registry.md +++ b/Documentation/Registry.md @@ -21,11 +21,12 @@ - [4.4. Download source archive](#44-download-source-archive) - [4.4.1. Integrity verification](#441-integrity-verification) - [4.4.2. Download locations](#442-download-locations) + - [4.4.3. Signature validation](#443-signature-validation) - [4.5. Lookup package identifiers registered for a URL](#45-lookup-package-identifiers-registered-for-a-url) + - [4.5.1 URL to package identifier mappings](#451-url-to-package-identifier-mappings) - [4.6. Create a package release](#46-create-a-package-release) - [4.6.1. Source archive](#461-source-archive) - [4.6.2. Package release metadata](#462-package-release-metadata) - - [4.6.2.1. Reserved metadata keys](#4621-reserved-metadata-keys) - [4.6.3. Synchronous and asynchronous publication](#463-synchronous-and-asynchronous-publication) - [4.6.3.1. Synchronous publication](#4631-synchronous-publication) - [4.6.3.2. Asynchronous publication](#4632-asynchronous-publication) @@ -458,7 +459,11 @@ Link: ; rel="latest-version" { "name": "source-archive", "type": "application/zip", - "checksum": "a2ac54cf25fbc1ad0028f03f0aa4b96833b83bb05a14e510892bb27dea4dc812" + "checksum": "a2ac54cf25fbc1ad0028f03f0aa4b96833b83bb05a14e510892bb27dea4dc812", + "signing": { + "signatureBase64Encoded": "l1TdTeIuGdNsO1FQ0ptD64F5nSSOsQ5WzhM6/7KsHRuLHfTsggnyIWr0DxMcBj5F40zfplwntXAgS0ynlqvlFw==", + "signatureFormat": "cms-1.0.0" + } } ], "metadata": { ... } @@ -489,11 +494,19 @@ MAY correspond to the requested release. Each element in the `resources` array is a JSON object with the following keys: -| Key | Type | Description | -| ---------- | ------- | ------------------------------------------------------------------- | -| `name` | String | The name of the resource. | -| `type` | String | The content type of the resource. | -| `checksum` | String | A hexadecimal representation of the SHA256 digest for the resource. | +| Key | Type | Description | +| ---------- | ------- | -------------------------------------------------------------------------- | +| `name` | String | The name of the resource. | +| `type` | String | The content type of the resource. | +| `checksum` | String | A hexadecimal representation of the SHA256 digest for the resource. | +| `signing` | Object | Information about the signature. Required only if the resource is signed. | + +The `signing` JSON object contains these keys: + +| Key | Type | Description | +| ------------------------ | ------- | ------------------------------------------------- | +| `signatureBase64Encoded` | String | The resource's signature, base64 encoded. | +| `signatureFormat` | String | The signature format. (e.g., `cms-1.0.0`) | A resource object SHOULD have one of the following combinations of `name` and `type` values: @@ -507,41 +520,12 @@ with a given combination of `name` and `type` values. #### 4.2.2. Package release metadata standards -A server MAY include metadata in its package release response. -It is RECOMMENDED that package metadata be represented in [JSON-LD] -according to a structured data standard. -For example, -this response using the [Schema.org] [SoftwareSourceCode] vocabulary: - -```jsonc -{ - "id": "mona.LinkedList", - "version": "1.1.1", - "resources": [ ... ], - "metadata": { - "@context": ["http://schema.org/"], - "@type": "SoftwareSourceCode", - "name": "LinkedList", - "description": "One thing links to another.", - "keywords": ["data-structure", "collection"], - "version": "1.1.1", - "codeRepository": "https://github.com/mona/LinkedList", - "license": "https://www.apache.org/licenses/LICENSE-2.0", - "programmingLanguage": { - "@type": "ComputerLanguage", - "name": "Swift", - "url": "https://swift.org" - }, - "author": { - "@type": "Person", - "@id": "https://example.com/mona", - "givenName": "Mona", - "middleName": "Lisa", - "familyName": "Octocat" - } - } -} -``` +SE-391 defines the [JSON schema] for package release metadata that +gets submitted as part of the ["create a package release"](#endpoint-6) +request. A server MAY allow and/or populate additional metadata by +expanding the schema. The `metadata` key in the +["fetch information about a package release "](#endpoint-2) API response +will hold the user-provided as well as the server populated metadata. @@ -704,6 +688,8 @@ Content-Length: 2048 Content-Version: 1 Digest: sha-256=oqxUzyX7wa0AKPA/CqS5aDO4O7BaFOUQiSuyfepNyBI= Link: ; rel=duplicate; geo=jp; pri=10; type="application/zip" +X-Swift-Package-Signature-Format: cms-1.0.0 +X-Swift-Package-Signature: l1TdTeIuGdNsO1FQ0ptD64F5nSSOsQ5WzhM6/7KsHRuLHfTsggnyIWr0DxMcBj5F40zfplwntXAgS0ynlqvlFw== ``` A server MUST respond with a `Content-Length` header @@ -727,6 +713,10 @@ It is RECOMMENDED for clients and servers to support range requests as described by [RFC 7233] and caching as described by [RFC 7234]. +If a release is signed, a server MUST include +`X-Swift-Package-Signature-Format` and `X-Swift-Package-Signature` +headers in the response. + #### 4.4.1. Integrity verification A client MUST verify the integrity of a downloaded source archive using @@ -779,6 +769,14 @@ Content-Version: 1 Digest: sha-256=a2ac54cf25fbc1ad0028f03f0aa4b96833b83bb05a14e510892bb27dea4dc812 ``` +#### 4.4.3. Signature validation + +A client MUST validate the signature of a signed archive +according to the signature format and configuration. Signing +information can alternatively be found in the associated +`source-archive` resource in the response to `GET /{scope}/{name}/{version}`, +as described in [4.2.1](#421-package-release-resources). + ### 4.5. Lookup package identifiers registered for a URL @@ -825,6 +823,20 @@ nested at a top-level `identifiers` key. It is RECOMMENDED for clients and servers to support caching as described by [RFC 7234]. +#### 4.5.1 URL to package identifier mappings + +As part of the [package release metadata](#422-package-release-metadata-standards) +JSON object, the `repositoryURLs` array can be used to specify +URLs associated with a package identifier. This is one way +through which a server can obtain URL to package identifier +mappings for this API. + +A server MAY choose other mechanism(s) for package authors +to specify these mappings. + +A server SHOULD validate the package author's ownership claim +on the corresponding repository. + ### 4.6. Create a package release @@ -836,10 +848,12 @@ to publish a release of a package. A client MUST provide a body encoded as multipart form data with the following sections: -| Key | Content-Type | Description | Requirement Level | -| ----------------- | ------------------ | ----------------------------------------- | ----------------- | -| `source-archive` | `application/zip` | The source archive of the package. | REQUIRED | -| `metadata` | `application/json` | Additional information about the release. | OPTIONAL | +| Key | Content-Type | Description | Requirement Level | +| -------------------------- | -------------------------- | ----------------------------------------- | ----------------- | +| `source-archive` | `application/zip` | The source archive of the package. | REQUIRED | +| `source-archive-signature` | `application/octet-stream` | The signature of the source archive. | OPTIONAL | +| `metadata` | `application/json` | Additional information about the release. | OPTIONAL | +| `metadata-signature` | `application/octet-stream` | The signature of the metadata. | OPTIONAL | A client MUST set a `Content-Type` header with the value `multipart/form-data`. `boundary` can be any string. @@ -853,6 +867,9 @@ the total size of the body in bytes. A client SHOULD set the `Accept` header with the value `application/vnd.swift.registry.v1+json`. +A client MUST set a `X-Swift-Package-Signature-Format` header +with the signature format if the source archive is signed. + ```http PUT /mona/LinkedList/1.1.1 HTTP/1.1 Host: packages.example.com @@ -860,6 +877,7 @@ Accept: application/vnd.swift.registry.v1+json Content-Type: multipart/form-data;boundary="boundary" Content-Length: 336 Expect: 100-continue +X-Swift-Package-Signature-Format: cms-1.0.0 --boundary Content-Disposition: form-data; name="source-archive" @@ -869,13 +887,29 @@ Content-Transfer-Encoding: base64 gHUFBgAAAAAAAAAAAAAAAAAAAAAAAA== +--boundary +Content-Disposition: form-data; name="source-archive-signature" +Content-Type: application/octet-stream +Content-Length: 88 +Content-Transfer-Encoding: base64 + +l1TdTeIuGdNsO1FQ0ptD64F5nSSOsQ5WzhM6/7KsHRuLHfTsggnyIWr0DxMcBj5F40zfplwntXAgS0ynlqvlFw== + --boundary Content-Disposition: form-data; name="metadata" Content-Type: application/json Content-Transfer-Encoding: quoted-printable Content-Length: 3 -{ } +{ "repositoryURLs": [] } + +--boundary +Content-Disposition: form-data; name="metadata-signature" +Content-Type: application/octet-stream +Content-Length: 88 +Content-Transfer-Encoding: base64 + +M6TdTeIuGdNsO1FQ0ptD64F5nSSOsQ5WzhM6/7KsHRuLHfTsggnyIWr0DxMcBj5F40zfplwntXAgS0ynlqvlFw== ``` @@ -1001,46 +1035,31 @@ A client MAY include a multipart section named `metadata` containing additional information about the release. A client SHOULD set a `Content-Type` header with the value `application/json` and a `Content-Length` header with the size of the JSON document in bytes. -It is RECOMMENDED that package release metadata be represented in [JSON-LD] -according to a structured data standard, -as discussed in [4.2.1](#421-package-release-metadata-data-standards). +The package release metadata MUST be based on the [JSON schema], +as discussed in [4.2.2](#422-package-release-metadata-standards). ```http --boundary Content-Disposition: form-data; name="metadata" Content-Type: application/json -Content-Length: 620 +Content-Length: 226 Content-Transfer-Encoding: quoted-printable { - "@context": ["http://schema.org/"], - "@type": "SoftwareSourceCode", - "name": "LinkedList", "description": "One thing links to another.", - "keywords": ["data-structure", "collection"], - "version": "1.1.1", - "codeRepository": "https://github.com/mona/LinkedList", - "license": "https://www.apache.org/licenses/LICENSE-2.0", - "programmingLanguage": { - "@type": "ComputerLanguage", - "name": "Swift", - "url": "https://swift.org" - }, + "repositoryURLs": ["https://github.com/mona/LinkedList"], + "licenseURL": "https://www.apache.org/licenses/LICENSE-2.0", "author": { - "@type": "Person", - "@id": "https://github.com/mona", - "givenName": "Mona", - "middleName": "Lisa", - "familyName": "Octocat" + "name": "Mona Lisa Octocat" } } ``` -If a client doesn't provide a `metadata` section, -a server MAY populate the metadata for a release. -A client MAY request that a server not populate metadata automatically -by sending an empty JSON object (`{}`) as its request body. +A server MAY allow and/or populate additional metadata for a release. + +A server MAY make any properties in the [JSON schema] and additional +metadata it defines required. If a client provides an invalid JSON document, the server SHOULD respond with a status code of @@ -1056,15 +1075,7 @@ Content-Language: en { "detail": "invalid JSON provided for release metadata" } -``` - -##### 4.6.2.1. Reserved metadata keys - -These metadata keys have special meanings to the server and should be included if and only if their value satisifies their intended use: - -| Key | Description | Server Use | -| ----------------- | ---------------------------------------------------- | -------------------------------------- | -| `repositoryURLs` | An array of the package's source code repository URLs (e.g., `["https://github.com/mona/LinkedList", "ssh://git@github.com:mona/LinkedList.git"]`). | The mappings between package identifer and repository URL get recorded for the [lookup package identifiers by URL](#endpoint-5) endpoint. | +``` #### 4.6.3. Synchronous and asynchronous publication @@ -1734,3 +1745,4 @@ components: [XCFramework]: https://developer.apple.com/videos/play/wwdc2019/416/ "WWDC 2019 Session 416: Binary Frameworks in Swift" [SE-0272]: https://github.com/apple/swift-evolution/blob/master/proposals/0272-swiftpm-binary-dependencies.md "Package Manager Binary Dependencies" [Swift tools version]: https://github.com/apple/swift-package-manager/blob/9b9bed7eaf0f38eeccd0d8ca06ae08f6689d1c3f/Documentation/Usage.md#swift-tools-version-specification "Swift Tools Version Specification" +[JSON schema]: https://github.com/apple/swift-evolution/blob/main/proposals/0391-package-registry-publish.md#package-release-metadata-standards "JSON schema for package release metadata"