|
| 1 | +# Package Security |
| 2 | + |
| 3 | +Learn about the security features that the package manager implements. |
| 4 | + |
| 5 | +## Trust on First Use |
| 6 | + |
| 7 | +The package manager records **fingerprints** of downloaded package versions so that |
| 8 | +it can perform [trust-on-first-use](https://en.wikipedia.org/wiki/Trust_on_first_use) |
| 9 | +(TOFU). |
| 10 | +That is, when a package version is downloaded for the first time, the package manager trusts that |
| 11 | +it has downloaded the correct contents and requires subsequent downloads of the same |
| 12 | +package version to have the same fingerprint. |
| 13 | +If the fingerprint changes, it might be an indicator that the package has been |
| 14 | +compromised and the package manager either warns or returns an error. |
| 15 | + |
| 16 | +Depending on where a package version is downloaded from, a different value is |
| 17 | +used as its fingerprint: |
| 18 | + |
| 19 | +| Package Version Origin | Fingerprint | |
| 20 | +| ---------------------- | ----------- | |
| 21 | +| Git repository | Git hash of the revision | |
| 22 | +| Package registry | Checksum of the source archive | |
| 23 | + |
| 24 | +The package manager keeps version fingerprints for each package in a single file |
| 25 | +under the `~/.swiftpm/security/fingerprints` directory. |
| 26 | + - For a Git repository package, the fingerprint filename takes the form of `{PACKAGE_NAME}-{REPOSITORY_URL_HASH}.json` (such as `LinkedList-5ddbcf15.json`). |
| 27 | + - For a registry package, the fingerprint filename takes the form of `{PACKAGE_ID}.json` (such as `mona.LinkedList.json`). |
| 28 | + |
| 29 | +For packages retrieved from a registry, the package manager expects all registries to provide consistent fingerprints for packages they host. |
| 30 | +If registries have conflicting fingerprints, package manager reports that as an error. |
| 31 | +This can be tuned down to warning by setting the [build](<doc:SwiftBuild>) option `--resolver-fingerprint-checking` |
| 32 | +to `warn` (default is `strict`). |
0 commit comments