F45 signature enforcement: what the three paths actually do
Fedora 45 changes the RPM default verification mode to enforcing signature checking (official ChangeSet: Enforcing signature checking by default). Which layer “enforced” lands on decides whether your third-party RPMs suddenly refuse to install — the same unsigned package takes three different paths to three different outcomes.
Every terminal output on this page was produced by building an unsigned package with rpmbuild on F45 and running each path, not copied from the docs.
First: is the package signed at all?
Section titled “First: is the package signed at all?”You do not need to install anything to find out; two commands are enough:
rpm -K utest-1.0-1.noarch.rpmrpm -qpi utest-1.0-1.noarch.rpm | head -8For an unsigned package, rpm -K reports:
/tmp/urpms/noarch/utest-1.0-1.noarch.rpm: digests SIGNATURES NOT OKSIGNATURES NOT OK is where the three paths start to diverge.
Three paths, three outcomes
Section titled “Three paths, three outcomes”Path one: rpm -i — refused outright
Section titled “Path one: rpm -i — refused outright”sudo rpm -i utest-1.0-1.noarch.rpmpackage utest-1.0-1.noarch does not verify: no signatureThe exit code is 1 and the package is not installed (rpm -q utest reports package utest is not installed). This is the biggest behavioural difference from F44: rpm 6.0.x on F44 installs it directly.
Path two: dnf install ./x.rpm — warns and installs
Section titled “Path two: dnf install ./x.rpm — warns and installs”sudo dnf -y install ./utest-1.0-1.noarch.rpm[3/3] Installing utest-0:1.0-1.noarch 100% | 4.3 KiB/s | 268.0 B | 00m00sWarning: skipped OpenPGP checks for 1 package from repository: @commandlineComplete!It installs. Note from repository: @commandline — dnf treats the local file as a temporary repository, and that repository carries no gpgcheck constraint, so it only warns.
Path three: repository install (gpgcheck=1) — refused at transaction
Section titled “Path three: repository install (gpgcheck=1) — refused at transaction”Put the unsigned package in a repository with gpgcheck=1 and install it by name:
sudo dnf -y install utestRunning transactionTransaction failed: Signature verification failed.OpenPGP check for package "utest-1.0-1.noarch" (.../utest-1.0-1.noarch.rpm)from repo "unsigned-local" has failed: The package is not signed.The failure happens at the transaction stage: the package is already in the cache, but it is refused for writing into the system.
Error-message table
Section titled “Error-message table”| Message you see | Path | Outcome | What to do |
|---|---|---|---|
does not verify: no signature | rpm -i | refused | add --nosignature or switch to a repository |
skipped OpenPGP checks … @commandline | dnf install ./x.rpm | installed | do not use the local-file path if you want a hard block |
The package is not signed | dnf repository install | refused | sign the package, or disable gpgcheck temporarily |
SIGNATURES NOT OK | rpm -K | report only | check where the package came from |
How to override
Section titled “How to override”Each path has its own override, and picking the wrong one leaves the risk in the system:
# 1) Allow this one install (rpm layer)sudo rpm -i --nosignature utest-1.0-1.noarch.rpm
# 2) Disable checking for one repository for this command only (writes no file)sudo dnf install --setopt=unsigned-local.gpgcheck=0 utest
# 3) The proper route: sign the package and install from a repositoryrpm --addsign utest-1.0-1.noarch.rpmBatch signing and a private repository
Section titled “Batch signing and a private repository”Teams usually end up running their own repository. The smallest reproducible flow:
# Generate a key (once)gpg --batch --gen-key <<'EOF'%no-protectionKey-Type: RSAKey-Length: 4096Name-Real: Internal RPM SigningName-Email: [email protected]Expire-Date: 2y%commitEOF
# Export the public key for clients, import the private one into rpmgpg --export -a "Internal RPM Signing" > RPM-GPG-KEY-internalsudo rpm --import RPM-GPG-KEY-internal
# Sign each package and rebuild metadatarpm --addsign *.rpmcreaterepo_c .Point the client repository file at the key with gpgkey= and gpgcheck=1, so unsigned packages are blocked at the transaction stage instead of being discovered after installation.
Post-upgrade checklist
Section titled “Post-upgrade checklist”Four steps to confirm you are not blocked:
rpm -q rpm— confirm 6.1, not 6.0.x;rpm -K your-third-party.rpm— check the signature state;- Run
dnf install ./x.rpmonce and confirm it only warns; - Run it by repository name and confirm it is refused — being refused is the expected behaviour.
Related pages
Section titled “Related pages”- Error lookup — exact signature messages and fixes
- Fedora 45: changes, download and upgrade — the six changes at a glance
- Repository configuration moves to /usr — which file
gpgchecklives in - Fedora security updates and advisories — updates and signature policy
- Upgrading to Fedora 45 — post-upgrade checks
- Official: Fedora 45 ChangeSet