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. Revalidate and rebuild after changing the policy:
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 be exactly 16, 40, or 64 hexadecimal characters, with no 0x prefix, and 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.
Key changes
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.