-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Port Documentation/PackageRegistry
directory contents into DocC
#8745
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
base: main
Are you sure you want to change the base?
Changes from all commits
10d9fc0
b2e00f1
7b2575d
3243972
15b7e74
eaf3429
c434003
c1b9af0
b0d0f12
5296e28
f55fc06
d215e94
7092272
00d372d
6683333
cb78c30
41789ce
644a28c
0349b3b
07cd5a4
46b7d84
6f20f53
162e07a
b9b188e
4fdfecd
44694a8
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 | ||||
---|---|---|---|---|---|---|
|
@@ -8,18 +8,11 @@ Learn to create, publish and use Swift package collections. | |||||
|
||||||
## Overview | ||||||
|
||||||
Package collections, introduced by [SE-0291](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0291-package-collections.md), are | ||||||
curated lists of packages and associated metadata that can be imported | ||||||
by SwiftPM to make discovery of existing packages easier. | ||||||
They are authored as static JSON documents | ||||||
and can be published to the web or distributed to local file systems. | ||||||
|
||||||
Educators and community influencers can publish | ||||||
package collections to go along with course materials or blog posts, removing the friction of using | ||||||
packages for the first time and the cognitive overload of deciding which packages are useful for | ||||||
a particular task. | ||||||
Enterprises may use collections to narrow the decision space for their internal | ||||||
engineering teams, focusing them on a trusted set of vetted packages. | ||||||
Package collections, introduced by [SE-0291](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0291-package-collections.md), are curated lists of packages and associated metadata that package manager can import to make discovery of existing packages easier. | ||||||
|
||||||
Educators and community influencers can publish package collections to go along with course materials or blog posts, making it easier for their readers to use packages for the first time, or choosing which packages to use for a particular task. | ||||||
Enterprises may use collections to provide a trusted set of packages, or a collection of packages consistently used by a team. | ||||||
Author a package collection as a static JSON document and publish it to the web or distribute it on a local file system. | ||||||
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.
Suggested change
|
||||||
|
||||||
### Using the package-collection CLI | ||||||
|
||||||
|
@@ -46,8 +39,9 @@ intended for package collection publishers: | |||||
- [`package-collection-validate`](https://github.com/apple/swift-package-collection-generator/tree/main/Sources/PackageCollectionValidator): Perform basic validations on a package collection | ||||||
- [`package-collection-diff`](https://github.com/apple/swift-package-collection-generator/tree/main/Sources/PackageCollectionDiff): Compare two package collections to see if their contents are different | ||||||
|
||||||
All package collections must adhere to the [collection data format](<doc:Input-Format>) for SwiftPM to be able to consume them. The recommended way | ||||||
to create package collections is to use [`package-collection-generate`](https://github.com/apple/swift-package-collection-generator/tree/main/Sources/PackageCollectionGenerator). For custom implementations, the data models are available through the [`PackageCollectionsModel` module](https://github.com/swiftlang/swift-package-manager/tree/main/Sources/PackageCollectionsModel). | ||||||
All package collections must adhere to the [collection data format](<doc:Input-Format>) for SwiftPM to be able to consume them. | ||||||
The recommended way to create package collections is to use [`package-collection-generate`](https://github.com/apple/swift-package-collection-generator/tree/main/Sources/PackageCollectionGenerator). | ||||||
For custom implementations, the data models are available through the [`PackageCollectionsModel` module](https://github.com/swiftlang/swift-package-manager/tree/main/Sources/PackageCollectionsModel). | ||||||
heckj marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
#### Input Format | ||||||
|
||||||
|
@@ -68,7 +62,7 @@ To begin, define the top-level metadata about the collection: | |||||
Each item in the `packages` array is a package object with the following properties: | ||||||
|
||||||
* `url`: The URL of the package. Currently only Git repository URLs are supported. URL should be HTTPS and may contain `.git` suffix. | ||||||
* `identity`: The [identity](https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#36-package-identification) <!-- TODO bp: to replace this link once PackageRegsitry/ is ported. --> of the package if published to registry. **Optional.** | ||||||
* `identity`: The [identity](<doc:RegistryServerSpecification#3.6.-Package-identification>) of the package if published to registry. **Optional.** | ||||||
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.
Suggested change
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. Ah, this must've slipped by me when I was doing a merge with main. Thanks for the keen eye! |
||||||
* `summary`: A description of the package. **Optional.** | ||||||
* `keywords`: An array of keywords that the package is associated with. **Optional.** | ||||||
* `readmeURL`: The URL of the package's README. **Optional.** | ||||||
|
@@ -77,8 +71,6 @@ Each item in the `packages` array is a package object with the following propert | |||||
* `name`: License name. [SPDX identifier](https://spdx.org/licenses/) (e.g., `Apache-2.0`, `MIT`, etc.) preferred. Omit if unknown. **Optional.** | ||||||
* `versions`: An array of version objects representing the most recent and/or relevant releases of the package. | ||||||
|
||||||
When a package is [added to a collection](<doc:PackageCollectionAdd>), the package object will appear in the collection's `packages` array with the properties described above. | ||||||
|
||||||
### Add versions to a package | ||||||
|
||||||
A version object has metadata extracted from `Package.swift` and optionally additional metadata from other sources: | ||||||
|
@@ -144,7 +136,7 @@ A version object has metadata extracted from `Package.swift` and optionally addi | |||||
* `name`: License name. [SPDX identifier](https://spdx.org/licenses/) (e.g., `Apache-2.0`, `MIT`, etc.) preferred. Omit if unknown. **Optional.** | ||||||
* `author`: The package version's author. **Optional.** | ||||||
* `name`: The author of the package version. | ||||||
* `signer`: The signer of the package version. **Optional.** Refer to [documentation](https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/PackageRegistryUsage.md#package-signing) <!-- TODO bp: to replace this link once PackageRegistry/ is ported. --> on package signing for details. | ||||||
* `signer`: The signer of the package version. **Optional.** Refer to the [documentation](<doc:PackageSecurity#Package-signing>) on package signing for details. | ||||||
* `type`: The signer type. Currently the only valid value is `ADP` (Apple Developer Program). | ||||||
* `commonName`: The common name of the signing certificate's subject. | ||||||
* `organizationalUnitName`: The organizational unit name of the signing certificate's subject. | ||||||
|
@@ -153,24 +145,22 @@ A version object has metadata extracted from `Package.swift` and optionally addi | |||||
|
||||||
### Version-specific manifests | ||||||
|
||||||
Package collection generators should include data from the "default" manifest `Package.swift` as well as [version-specific manifest(s)](https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/Usage.md#version-specific-manifest-selection) <!-- TODO bp: to replace this link once Usage.md is ported. -->. | ||||||
Package collection generators should include data from the "default" manifest `Package.swift` as well as [version-specific manifest(s)](<doc:SwiftVersionSpecificPackaging#Version-specific-Manifest-Selection>) | ||||||
|
||||||
The keys of the `manifests` map are Swift tools (semantic) versions: | ||||||
* For `Package.swift`, the tools version specified in `Package.swift` should be used. | ||||||
* For version-specific manifests, the tools version specified in the filename should be used. For example, for `[email protected]` it would be `4.2`. The tools version in the manifest must match that in the filename. | ||||||
|
||||||
### Version-specific tags | ||||||
|
||||||
[Version-specific tags](https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/Usage.md#version-specific-tag-selection) <!-- TODO bp: to replace this link once Usage.md is ported. --> are not | ||||||
supported by package collections. | ||||||
[Version-specific tags](<doc:SwiftVersionSpecificPackaging#Version-specific-tags-when-resolving-remote-dependencies>) are not supported by package collections. | ||||||
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.
Suggested change
|
||||||
|
||||||
### Configuration File | ||||||
|
||||||
Configuration that pertains to package collections are stored in the file `~/.swiftpm/config/collections.json`. | ||||||
It keeps track of user's list of configured collections | ||||||
and preferences such as those set by the `--trust-unsigned` and `--skip-signature-check` flags in the [`package-collection add` command](<doc:PackageCollectionAdd>). | ||||||
It keeps track of user's list of configured collections and preferences such as those set by the `--trust-unsigned` and `--skip-signature-check` flags in the [`package-collection add` command](<doc:PackageCollectionAdd>). | ||||||
|
||||||
> Note: This file is managed through SwiftPM commands and users are not expected to edit it by hand. | ||||||
> Note: This file is managed through Swift Package Manager commands and users are not expected to edit it by hand. | ||||||
|
||||||
## Example | ||||||
|
||||||
|
@@ -300,72 +290,24 @@ and preferences such as those set by the `--trust-unsigned` and `--skip-signatur | |||||
} | ||||||
``` | ||||||
|
||||||
## Protecting package collections | ||||||
|
||||||
## Signing and protecting package collections | ||||||
### Signing a collection | ||||||
|
||||||
Package collections can be signed to establish authenticity and protect their integrity. | ||||||
[Sign package collections](<doc:PackageSecurity#Signed-package-collections>) to establish authenticity and protect their integrity. | ||||||
Doing this is optional. | ||||||
Users will be prompted for confirmation before they can add an [unsigned collection](<doc:PackageCollectionAdd#Unsigned-package-collections>). | ||||||
The signing certificate you use to sign a package collection must meet a list of [requirements](<doc:PackageSecurity#Requirements-on-signing-certificate>). If these requirements are not met, the package manager returns an error. | ||||||
|
||||||
[`package-collection-sign`](https://github.com/apple/swift-package-collection-generator/tree/main/Sources/PackageCollectionSigner) helps publishers sign their package | ||||||
collections. To generate a signature one must provide: | ||||||
- The package collection file to be signed | ||||||
- A code signing certificate (DER-encoded) | ||||||
- The certificate's private key (PEM-encoded) | ||||||
- The certificate's chain in its entirety | ||||||
For more details on the security features Package manager implements, see <doc:PackageSecurity>. | ||||||
|
||||||
A signed package collection has an extra `signature` object: | ||||||
|
||||||
```json | ||||||
{ | ||||||
..., | ||||||
"signature": { | ||||||
"signature": "<SIGNATURE>", | ||||||
"certificate": { | ||||||
"subject": { | ||||||
"commonName": "Jane Doe", | ||||||
... | ||||||
}, | ||||||
"issuer": { | ||||||
"commonName": "Sample CA", | ||||||
... | ||||||
} | ||||||
} | ||||||
} | ||||||
} | ||||||
``` | ||||||
|
||||||
- The signature string (represented by `"<SIGNATURE>"`) is used to verify the contents of the collection file haven't been tampered with since it was signed when SwiftPM user [adds the collection](<doc:PackageCollectionAdd#Signed-package-collections>) to their configured list of collections. It includes the certificate's public key and chain. | ||||||
- `certificate` contains details extracted from the signing certificate. `subject.commonName` should be consistent with the name of the publisher so that it's recognizable by users. The root of the certificate must be [installed and trusted on users' machines](<doc:PackageCollectionAdd#Trusted-root-certificates>). | ||||||
|
||||||
### Requirements on signing certificate | ||||||
|
||||||
Certificates used for signing package collections must meet the following requirements, which are checked and enforced during signature generation (publishers) and verification (SwiftPM users): | ||||||
- The timestamp at which signing/verification is done must fall within the signing certificate's validity period. | ||||||
- The certificate's "Extended Key Usage" extension must include "Code Signing". | ||||||
- The certificate must use either 256-bit EC (recommended for enhanced security) or 2048-bit RSA key. | ||||||
- The certificate must not be revoked. The certificate authority must support OCSP, which means the certificate must have the "Certificate Authority Information Access" extension that includes OCSP as a method, specifying the responder's URL. | ||||||
- The certificate chain is valid and root certificate must be trusted. | ||||||
|
||||||
Non-expired, non-revoked Swift Package Collection certificates from [developer.apple.com](https://developer.apple.com) satisfy all of the criteria above. | ||||||
|
||||||
#### Trusted root certificates | ||||||
|
||||||
With the `package-collection-sign` tool, the root certificate provided as input for signing a collection is automatically trusted. When SwiftPM user tries to add the collection, however, | ||||||
the root certificate must either be preinstalled with the OS (Apple platforms only) or found in the `~/.swiftpm/config/trust-root-certs` directory (all platforms) or shipped with | ||||||
the [certificate-pinning configuration](<doc:#Protecting-package-collections>), otherwise the [signature check](<doc:PackageCollectionAdd#Signed-package-collections>) will fail. | ||||||
Collection publishers should make the DER-encoded | ||||||
root certificate(s) that they use downloadable so that users can adjust their setup if needed. | ||||||
|
||||||
|
||||||
## Protecting package collections | ||||||
### Security risks | ||||||
|
||||||
[Signing](<doc:PackageCollectionAdd#Unsigned-package-collections>) can provide some degree of protection on package collections and reduce the risks of their contents being modified by malicious actors, but it doesn't | ||||||
prevent the following attack vectors: | ||||||
- **Signature stripping**: This involves attackers removing signature from a signed collection, causing it to be downloaded as an [unsigned collection](<doc:PackageCollectionAdd#Unsigned-package-collections>) and bypassing signature check. In this case, publishers should make it known that the collection is signed, and SwiftPM users should abort the `add` operation when the "unsigned" warning appears on a supposedly signed collection. | ||||||
While signing can provide some degree of protection on package collections and reduce the risks of their contents being modified by malicious actors, it doesn't prevent the following attack vectors: | ||||||
- **Signature stripping**: This involves attackers removing signature from a signed collection, causing it to be downloaded as an unsigned collection and bypassing signature check. In this case, publishers should make it known that the collection is signed, and SwiftPM users should abort the `add` operation when the "unsigned" warning appears on a supposedly signed collection. | ||||||
- **Signature replacement**: Attackers may modify a collection then re-sign it using a different certificate, either pretend to be the same entity or as some other entity, and SwiftPM will accept it as long as the [signature is valid](<doc:PackageCollectionAdd#Signed-package-collections>). | ||||||
|
||||||
To defend against these attacks, SwiftPM has certificate-pinning configuration that allows collection publishers to: | ||||||
To defend against these attacks, package manager has certificate-pinning configuration that allows collection publishers to: | ||||||
- Require signature check on their collections — this defends against "signature stripping". | ||||||
- Restrict what certificate can be used for signing — this defends against "signature replacement". | ||||||
|
||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -32,12 +32,9 @@ Added "Sample Package Collection" to your package collections. | |||||
|
||||||
### Signed package collections | ||||||
|
||||||
Package collection publishers may [sign a collection to protect its contents](<doc:PackageCollections#Signing-and-protecting-package-collections>) from being tampered with. | ||||||
If a collection is signed, SwiftPM will check that the | ||||||
signature is valid before importing it and return an error if any of these fails: | ||||||
- The file's contents, signature excluded, must match what was used to generate the signature. | ||||||
In other words, this checks to see if the collection has been altered since it was signed. | ||||||
- The signing certificate must meet all the [requirements](<doc:PackageCollections#Requirements-on-signing-certificate>). | ||||||
Publishers of a package collection may [sign a collection to protect its contents](<doc:PackageCollections#Protecting-package-collections>). | ||||||
Package manager will check if a signed collection's signature is valid before importing it. | ||||||
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.
Suggested change
|
||||||
If the validation check fails, the package manager returns an error: | ||||||
|
||||||
```bash | ||||||
$ swift package-collection add https://www.example.com/bad-packages.json | ||||||
|
@@ -50,8 +47,8 @@ Users may continue adding the collection despite the error or preemptively skip | |||||
$ swift package-collection add https://www.example.com/packages.json --skip-signature-check | ||||||
``` | ||||||
For package collections hosted on the web, publishers may ask SwiftPM to [enforce the signature requirement](<doc:PackageCollections#Protecting-package-collections>). If a package collection is | ||||||
expected to be signed but it isn't, user will see the following error message: | ||||||
For package collections hosted on the web, publishers may ask package manager to [enforce the signature requirement](<doc:PackageSecurity#Trusted-root-certificates>). | ||||||
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.
Suggested change
|
||||||
If a package collection is expected to be signed but it isn't, users will see the following error message: | ||||||
|
||||||
```bash | ||||||
$ swift package-collection add https://www.example.com/bad-packages.json | ||||||
|
@@ -60,24 +57,19 @@ The collection is missing required signature, which means it might have been com | |||||
|
||||||
Users should NOT add the package collection in this case. | ||||||
|
||||||
##### Trusted root certificates | ||||||
|
||||||
Since generating a collection signature requires a certificate, part of the signature check involves validating the certificate and its chain and making sure that the root certificate is trusted. | ||||||
For more details on signature validation, see <doc:PackageSecurity#Signed-package-collections>. | ||||||
|
||||||
On Apple platforms, all root certificates that come preinstalled with the OS are automatically trusted. Users may include additional certificates to trust by placing | ||||||
them in the `~/.swiftpm/config/trust-root-certs` directory. | ||||||
##### Trusted root certificates | ||||||
|
||||||
On non-Apple platforms, there are no trusted root certificates by default other than those shipped with the [certificate-pinning configuration](<doc:PackageCollections#Protecting-package-collections>). Only those | ||||||
found in `~/.swiftpm/config/trust-root-certs` are trusted. This means that the signature check will always fail unless the `trust-root-certs` directory is set up: | ||||||
Package manager [validates the certificate](<doc:PackageSecurity#Trusted-root-certificates>) of a signed collection as a part of its signature validation to make sure that the root certificate is trusted. | ||||||
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.
Suggested change
|
||||||
|
||||||
```bash | ||||||
$ swift package-collection add https://www.example.com/packages.json | ||||||
The collection's signature cannot be verified due to missing configuration. | ||||||
``` | ||||||
Users can explicitly specify they trust a publisher and any collections they publish, by obtaining that publisher's root certificate and saving it to `~/.swiftpm/config/trust-root-certs`. The | ||||||
root certificates must be DER-encoded. Since SwiftPM trusts all certificate chains under a root, depending on what roots are installed, some publishers may already be trusted implicitly and | ||||||
users don't need to explicitly specify each one. | ||||||
root certificates must be DER-encoded. Since package manager trusts all certificate chains under a root, depending on what roots are installed, some publishers may already be trusted implicitly and users don't need to explicitly specify each one. | ||||||
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.
Suggested change
|
||||||
#### Unsigned package collections | ||||||
|
@@ -88,7 +80,7 @@ $ swift package-collection add https://www.example.com/packages.json | |||||
The collection is not signed. If you would still like to add it please rerun 'add' with '--trust-unsigned'. | ||||||
``` | ||||||
To continue user must confirm their trust by passing the `--trust-unsigned` flag: | ||||||
To continue, users must confirm their trust by passing the `--trust-unsigned` flag: | ||||||
```bash | ||||||
$ swift package-collection add https://www.example.com/packages.json --trust-unsigned | ||||||
|
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.