Sign Your Repository
SOW has two independent signing paths:
| Path | Output | Client control |
|---|---|---|
| RPM metadata | repodata/repomd.xml.asc |
repo_gpgcheck=1 |
| APT metadata | InRelease and Release.gpg |
Signed-By |
| RPM package body | embedded RPM signature | gpgcheck=1 |
APT trusts package hashes through the signed Release; SOW does not re-sign DEB package
bodies. Start with metadata signing. Add RPM package signing only when you own the signing
policy for those package bytes.
1. Create a dedicated key
The commands below create an unencrypted example key. Use a protected key and a
passphrase reference for production; see the configuration reference.
Keep the secret key outside the Workspace’s public Repository tree and outside every web
root. If a dedicated service account runs SOW, make that account—not the interactive
user—the directory owner. Distribute only repo-signing.pub to clients.
2. Configure metadata signing
In /srv/sow/sow.yml, add the relevant blocks under the Repository. Omit the ecosystem
you do not use:
Validate the key reference, rebuild, and run the publication gate:
For a protected key, add passphrase: env://SOW_METADATA_PASSPHRASE or a bounded file
reference next to key. SOW never writes key or passphrase material into configuration,
SQLite, JSON, or logs.
3. Verify metadata manually
Use the exact paths for your Dists and architectures:
sow check verifies the configured signing identity as part of its deeper consistency
checks. Manual verification is still useful when establishing a client trust root.
4. Optional: sign RPM package bodies
Add rpm.packages only if clients require embedded package signatures:
Replace the placeholder with the 40-hex fingerprint printed in $FPR. For this operation:
rpmandgpgmust be installed;- the matching secret key must be available in the ambient GPG environment used by
rpm; fillpreserves packages already signed by the configured ortrusted_keysidentities;alwaysre-signs everything not already signed by the configured identity;neverleaves input bytes unchanged.
SOW invokes rpm --addsign or rpm --resign on a private staged copy, not on the input
file. These rules apply to newly imported packages: build never re-signs an
existing immutable object. Before enabling fill or changing its key, check that
every existing RPM is signed by the configured key or a trusted identity.
Checking only for an empty signature_key is insufficient: an existing third-party
signature may also be untrusted. Add the appropriate public key to trusted_keys
when that trust is intended; otherwise prepare correctly signed packages outside the
repository and import them with a new package version and filename, or rebuild a fresh
repository from the original packages. Keep the old policy until that preparation is
complete. A policy rejection leaves the existing Desired projection intact.
After confirming existing package compatibility, revalidate and rebuild:
Inspect a resulting package with rpmkeys --checksig /path/to/package.rpm.
5. Enable dnf verification
Transfer the public key to the client through a trusted channel:
Then enable the checks that correspond to what you signed:
Set gpgcheck=0 if package-body signing is not configured. Do not disable
repo_gpgcheck after configuring metadata signing.
6. Enable APT verification
Install the public key as a dedicated keyring:
Reference it from deb822 configuration and do not set Trusted: yes:
Run apt update and treat any signature error as a failed deployment, not as a reason to
weaken the client configuration.
Plain-mode RPM signing
Plain mode can sign RPM package bodies, but it does not sign repository metadata or create
an APT Release:
The key must contain exactly 16, 40, or 64 hexadecimal characters after an optional 0x or
0X prefix. SOW removes that prefix and normalizes the key to uppercase. The
matching private key must be usable by the ambient rpm/GPG setup. Without --overwrite,
already signed RPMs keep their bytes; adding --overwrite explicitly re-signs every RPM.
SOW signs private staged copies before replacing package bytes and metadata.
An existing signature does not mean the RPM is signed by the key passed to --sign-with.
If every package must use your key, verify all RPMs against that key and selectively re-sign
mismatches in a candidate copy, or deliberately use --overwrite for the whole set.
For an existing online YUM repository, also preserve publication time. SOW 0.5.0
adds --metadata-timestamp; after the final create, sign and verify the new
repomd.xml separately before exposing it. Package signing and index signing are independent
checks. The YUM migration guide gives the full sequence,
including acceptance with cached clients.
Key changes
In Managed mode, changing a key reference or resolved fingerprint marks affected Dists dirty. A metadata
key can be changed by distributing the new public key, rebuilding, checking, and then
switching client enforcement. RPM package keys need a staged rollover: Package Objects
are immutable, and build rejects stored RPMs that do not satisfy the new policy instead
of re-signing them in place. Use fill with the old public key in trusted_keys until old
package coordinates have been withdrawn or replaced. Finish with a real client acceptance
test in the target environment.
Run the final signed repository through the exact dnf/APT versions and trust policy used in production. The automated scope is listed under Platforms & Integrations.