Using LPM with Swift
SPM integration via SE-0292 — login, install, publish.
LPM speaks the SE-0292 Swift Package Registry API, so Swift Package Manager (SPM) can resolve LPM-hosted Swift packages natively. This guide walks through the full setup: installing a Swift package, and (for authors) publishing one.
Prerequisites
- LPM installed — see Installation.
- Swift toolchain installed.
- An lpm.dev account, logged in (
lpm login).
One-time SPM integration
lpm swift-registryThis runs an idempotent, fail-loud setup:
- Logs SPM into the LPM registry (writes the
swift package-registryconfig). - Downloads LPM's CMS signing certificate and writes it to
~/.swiftpm/security/trusted-root-certs/lpm.der. - Writes a
lpmdev-scope override into~/.swiftpm/configuration/registries.json(signing.onUntrustedCertificate = "silentAllow") so SPM accepts the self-signed cert without requiring a public-CA chain.
Failures (network, non-2xx from the cert endpoint, truncated body, mkdir/write errors) abort with a clear error rather than silently completing with broken signing — a one-shot lpm install <swift-pkg> cannot finish "successfully" with the trust path half-set-up. Re-run with --force to refresh the cert (cert rotation, suspicion of corruption, etc.).
See Trust model on the concepts page for what the signing posture actually attests to today (detached integrity + HTTPS authenticity) and what it does not (trusted signer identity, per-author attribution).
Installing a Swift package
Use lpm install for Swift packages — it edits Package.swift and triggers swift package resolve:
lpm install @lpm.dev/owner.swift-pkg
lpm install @lpm.dev/owner.swift-pkg@1.2.0 # specific versionBehind the scenes, Package.swift's dependencies: and targets: arrays get updated with the new package. Cross-target wiring is handled.
lpm addalso supports Swift packages today (with--targetfor SPM-target wiring), butlpm installis the right command for SPM dependencies —lpm addis source-delivery, while Swift packages want registry-resolved deps.
Publishing a Swift package
The flow is the same as any other LPM package, plus two Swift-specific requirements:
- Your project must declare
ecosystem: "swift"inlpm.config.json. - The repo must have a valid
Package.swiftat the root.
lpm publishThe publish pipeline:
- Packs the repo into a tarball.
- Generates a
.zipsource archive with the SE-0292-required{pkgName}-{version}/top-level wrapper. - Computes the SHA-256 checksum that SPM expects.
- Generates a CMS-1.0.0 detached signature (ECDSA P-256 / SHA-256) with the LPM signing cert.
- Uploads tarball + zip + signature to lpm.dev.
After publish, SPM clients on any machine that's run lpm swift-registry can resolve the package by its LPM identity.
Identity mapping
LPM packages are named @lpm.dev/owner.pkg-name. SE-0292 scopes can't contain dots, so LPM maps them when surfacing to SPM:
| LPM name | SPM identity |
|---|---|
@lpm.dev/owner.pkg-name | lpmdev.owner_pkg-name |
The _ between owner and package name is the unambiguous separator: LPM forbids _ in both owner and package name (DB-level), so the boundary is always clear even when either half contains hyphens. You don't need to deal with the SPM identity by hand — lpm install and lpm swift-registry handle the translation.
Verifying signatures
LPM serves the CMS signing cert at https://lpm.dev/api/swift-registry/certificate (DER). lpm swift-registry writes the cert and the matching registries.json scope override; SPM then verifies the CMS detached signature on every install.
Signatures are surfaced in three places per release:
- The release metadata JSON (base64 CMS).
- The
DigestHTTP response header on tarball download. - A comment block in the
Package.swiftmanifest response.
If the cert rotates, re-run lpm swift-registry --force. Failed --force re-downloads are fatal — the CLI will not silently fall back to the stale cert.
For the trust-model rationale (why the cert is self-signed, why SPM uses a silentAllow scope override rather than a trust-store entry, what the signature actually attests to), see Trust model.
Common pitfalls
lpm addfor Swift is the legacy path. Uselpm install—addis source-delivery, not what you want for a runtime SPM dep.Package.swiftmust use the SE-0292 identity (lpmdev.owner_pkg-name), not the LPM-native form.lpm installwrites it correctly; if you hand-edit, mind the format — the_separates owner from package name.- Re-run
lpm swift-registry --forceafter cert rotation. A stale local trust store will refuse new signatures. A failing--forceis fatal — the CLI does not silently keep the stale cert.
See also
lpm install— runtime dependency installer (works for Swift)lpm swift-registry— SPM setup command- SE-0292 — the upstream protocol spec