RFC 9116 recommends signing security.txt with an OpenPGP cleartext signature. The reason is subtle but important: the file's whole job is to tell researchers where to send vulnerability reports — so an attacker who compromises your web server could swap in their own contact address and quietly intercept every report. A signature made with a key you control lets researchers detect that tampering. This guide covers generating the key with GnuPG, publishing it, and signing the file.
gpg (or on a hardware token such as a YubiKey) and keep the private key offline. Never generate or paste a signing key into a website — including this one. That is why ShowDNS provides this guide rather than a "PGP key generator" tool.Step 1 — Generate a PGP Key with GnuPG
GnuPG ships with most Linux distributions and macOS (via brew install gnupg); Windows users can install Gpg4win. Create a modern Ed25519 key bound to your security role address — not a personal mailbox:
gpg --quick-generate-key "Example Corp Security <security@example.com>" ed25519 sign 2yYou will be prompted for a passphrase — use a strong one and store it in your team's password manager. The 2y expiry is deliberate: like the Expires field in security.txt itself, a key that must be renewed periodically proves the security program is still staffed.
security@yourdomain, the same address you publish in the Contact field. Researchers cross-check the key's user ID against the contact — a mismatch looks suspicious.Step 2 — Export and Publish the Public Key
Export the public key in ASCII-armored form:
gpg --armor --export security@example.com > pgp-key.txtHost pgp-key.txt on your website over HTTPS and reference it from the Encryption field of your security.txt. This one URL serves two purposes: researchers use the key to verify your signature and to encrypt reports they send you.
Encryption: https://example.com/pgp-key.txtStep 3 — Write the Unsigned File
Prepare your security.txt with at least Contact and Expires — the Security.txt Generator builds a valid one in seconds. Make sure the Encryption field points at the key you just published:
Contact: mailto:security@example.com
Expires: 2027-07-01T00:00:00Z
Encryption: https://example.com/pgp-key.txt
Canonical: https://example.com/.well-known/security.txtStep 4 — Cleartext-Sign the File
A cleartext signature wraps the file so it stays human-readable while carrying the signature inline — exactly the form RFC 9116 expects:
gpg --clearsign --local-user security@example.com security.txt
mv security.txt.asc security.txtThe signed result looks like this and is what you deploy:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
Contact: mailto:security@example.com
Expires: 2027-07-01T00:00:00Z
Encryption: https://example.com/pgp-key.txt
Canonical: https://example.com/.well-known/security.txt
-----BEGIN PGP SIGNATURE-----
iHUEARYKAB0WIQT...
-----END PGP SIGNATURE-----gpg --clearsign after every change, and always when you re-issue the file before its Expires date. Editing the deployed file in place without re-signing is worse than not signing at all: a broken signature actively signals tampering.Step 5 — Deploy and Verify
Upload the signed file to /.well-known/security.txt, served as text/plain; charset=utf-8 over HTTPS. Then verify the signature the same way a researcher would:
# Import the published key and verify the live file
curl -s https://example.com/pgp-key.txt | gpg --import
curl -s https://example.com/.well-known/security.txt | gpg --verify
# Expected: gpg: Good signature from "Example Corp Security <security@example.com>"Finally, run the ShowDNS Security.txt Tester — it detects the cleartext signature and validates every other RFC 9116 requirement (location, Contact, Expires, HTTPS rules) in one pass.
Key Maintenance
- Back up the private key (
gpg --export-secret-keys --armor) to encrypted offline storage — losing it means researchers can no longer verify continuity. - Renew before expiry with
gpg --quick-set-expire, then re-publish the public key and re-sign the file. - Rotate on staff changes if anyone with passphrase access leaves the security team.
- Consider a hardware token (YubiKey, Nitrokey) so the private key never touches disk on a networked machine.