SPM Registry Authentication#
SwifterPM (Tuist's internal SPM resolution layer) maintains two distinct authentication code paths with different credential lookup orders. Understanding which path applies β and what credentials each consults β is essential for diagnosing 401/404 failures during tuist install.
Two Auth Code Paths#
| Context | Handler | Keychain? | netrc? | Env vars |
|---|---|---|---|---|
| Registry packages (source archives) | RegistryAuthorization | β Yes | β Yes | SWIFTPM_REGISTRY_TOKEN, SWIFTPM_REGISTRY_LOGIN/SWIFTPM_REGISTRY_PASSWORD, SWIFTPM_NETRC_DATA |
Binary artifact downloads (.binaryTarget xcframeworks, GitHub release assets) | HTTPAuthorization | β No | β Yes | SWIFTPM_NETRC_DATA, GITHUB_TOKEN, GH_TOKEN |
The Keychain gap for binary artifacts is a known open issue. A Keychain credential for api.github.com is never consulted when downloading a .binaryTarget URL β only registry downloads use RegistryKeychain .
Credential Resolution Order#
Registry packages β RegistryAuthorization.header #
SWIFTPM_REGISTRY_TOKENenv var β Bearer tokenSWIFTPM_REGISTRY_LOGIN+SWIFTPM_REGISTRY_PASSWORDenv vars β Basic/Bearer (per registry config auth type)SWIFTPM_NETRC_DATAenv var (inline netrc content)- macOS Keychain β
kSecClassInternetPasswordlookup by host ~/.netrcfile
Binary artifact downloads β HTTPAuthorization.header #
SWIFTPM_NETRC_DATAenv var (inline netrc content)~/.netrcfileGITHUB_TOKEN/GH_TOKENenv var (GitHub/api.github.com hosts only) β Bearer tokengh auth tokenCLI fallback (GitHub hosts only)
Note: netrc deliberately beats the ambient GitHub token. In GitHub Actions, GITHUB_TOKEN is repo-scoped and returns HTTP 404 (not 403) for assets in a different private repo. A machine api.github.com netrc entry with broader scope should take precedence β this was fixed in PR #11528.
CI / Headless Configuration#
For registry packages on CI, tuist registry login writes credentials into the SPM registry configuration. It accepts both project tokens (TUIST_TOKEN) and OIDC account JWTs β the OIDC path was added in PR #9769.
For binary artifacts on CI, the recommended approaches (in order of preference):
-
SWIFTPM_NETRC_DATAβ set inline netrc content as an environment variable (safe for secrets managers):SWIFTPM_NETRC_DATA="machine api.github.com login x-access-token password <token>" -
~/.netrcβ write a file at$HOME/.netrc:machine api.github.com login x-access-token password <github-app-token-scoped-to-private-repo> -
GITHUB_TOKEN/GH_TOKENβ only works if the token has access to the repo hosting the asset. -
ghCLI βgh auth loginbefore runningtuist install.
Keychain credentials are not supported for binary artifact downloads .
Registry Configuration Loading#
RegistryConfig.load merges three sources in order:
- Global:
~/.swiftpm/configuration/registries.json - Project:
.swiftpm/configuration/registries.json --config-pathoverride (passed viaregistryConfigurationPathinPackageResolver)
The authentication section in registries.json controls whether a registry uses basic or token (bearer) auth . If the section is absent, swifterpm infers bearer when the netrc/Keychain login field equals "token" .
Key Source Files#
| File | Purpose |
|---|---|
swifterpm/Sources/swifterpm/Support.swift | HTTPAuthorization β binary artifact download auth |
swifterpm/Sources/swifterpm/Registry.swift | RegistryAuthorization, RegistryKeychain, RegistryNetrc |
swifterpm/Sources/swifterpm/Resolve.swift | Passes --config-path / --default-registry-url to swift package resolve |
cli/Sources/TuistRegistryCommand/Services/RegistryLoginCommandService.swift | tuist registry login β stores credentials for CI use |