Watch
1
0
Fork
You've already forked keys
0
keys/README.md
Alexander Hess 30fee8de37
Add security.txt
- Add scripts/security-txt.sh
  to generate a security.txt file
- Add the current security.txt
- Extend verify.sh to verify security.txt by default
  and cross-check that it expires together with the signing key
- Describe security.txt in OPENPGP.md and README.md
2026-09-21 21:19:12 +02:00

137 lines
4.2 KiB
Markdown

# Keys
Public record of the cryptographic keys of Alexander Hess
(i.e., "me" in this repository):
What they are, how they are handled, and how to verify them.
There are two audiences for this repository:
- **I** want a how-to:
[`OPENPGP.md`](OPENPGP.md) and [`AGE.md`](AGE.md) hold the policies and ceremonies,
and the [`scripts/`](scripts/) run them.
- **Readers** want to confirm my keys and my identity:
Everything needed for that is in the [Verify](#verify) section below.
## Verify
The fingerprint of my [current PGP key](public-key.asc) is in [`KEYS.md`](KEYS.md),
which is signed.
Compare the fingerprint with at least one source outside this repository
to confirm my identity:
- [WKD](https://wiki.gnupg.org/WKD),
for example, via `gpg --locate-keys ah@alexander-hess.com`
- The keyservers listed in [`OPENPGP.md`](OPENPGP.md),
for example, `gpg --keyserver hkps://keys.openpgp.org --search-keys alexander@webartifex.de`
- [`KEYS.md`](KEYS.md) obtained from my websites:
- [alexander-hess.com](https://www.alexander-hess.com/KEYS.md)
- [webartifex.de](https://www.webartifex.de/KEYS.md)
Then:
```bash
gpg --import public-key.asc
gpg --verify KEYS.md.asc KEYS.md
gpg --verify OPENPGP.md.asc OPENPGP.md
gpg --verify AGE.md.asc AGE.md
gpg --verify security.txt
```
Each `gpg --verify` will print two things:
1. `Good signature from "Alexander Hess <...>"`:
The file is intact and was signed by this key.
2. `WARNING: This key is not certified with a trusted signature!`:
Because `gpg` likely has no record that this key is mine.
So, a good signature plus a matching `Primary key fingerprint` line is the full result.
To silence the warning on your machine,
tell `gpg` about your check:
```bash
gpg --lsign-key <FPR> # after comparing the fingerprint yourself
```
If you trusted one of the two keys I retired in 2026,
they certified the current one,
and the supersession is recorded in [`ceremonies/`](ceremonies/):
```bash
gpg --import history/344EA5AB10D868E0-public.asc history/6D11C1E91D3B0265-public.asc
gpg --check-signatures 8B1140ADB5185334E9FA513B75681C8167312680
gpg --verify ceremonies/2026-07-08_supersession.md.asc ceremonies/2026-07-08_supersession.md
```
## Contents
The files in this repository are described below.
### OpenPGP
How I implement [OpenPGP](https://www.openpgp.org/):
- [`KEYS.md`](KEYS.md):
Current keys, signed
- [`KEYS.md.asc`](KEYS.md.asc):
Detached signature, renewed at every ceremony
- [`OPENPGP.md`](OPENPGP.md):
OpenPGP policies, ceremonies, and history
- [`OPENPGP.md.asc`](OPENPGP.md.asc):
Detached signature, renewed at every ceremony
- [`public-key.asc`](public-key.asc):
Armored export of the current OpenPGP key
- [`security.txt`](security.txt): [RFC 9116](https://www.rfc-editor.org/info/rfc9116/)
contact file, clearsigned, renewed at every ceremony
- [`snapshots/`](snapshots/):
Yearly exports of the current OpenPGP key
- [`ceremonies/`](ceremonies/):
Signed records of exceptional events
- [`history/`](history/):
Armored public keys of all previous OpenPGP keys
### `age`
Besides OpenPGP,
I also use the modern [`age`](https://github.com/FiloSottile/age) encryption:
- [`AGE.md`](AGE.md):
`age` policies
- [`AGE.md.asc`](AGE.md.asc):
Detached signature, renewed at every ceremony
- [`age-recipient.txt`](age-recipient.txt):
`age` public key for `age -R`
- [`ceremonies/`](ceremonies/):
Signed record of when a recipient became valid or rotated
because `age` keys carry no metadata of their own
### Scripts
`sh` scripts for my own use:
- [`bootstrap.sh`](scripts/bootstrap.sh):
Imports and trusts all keys on a new machine,
then verifies all files
- [`sign.sh`](scripts/sign.sh):
Renews the detached signatures
- [`verify.sh`](scripts/verify.sh):
Verifies all signed files against the pinned signing subkey,
warns when the key is about to expire, and
cross-checks `age-recipient.txt` and `security.txt`
- [`snapshot.sh`](scripts/snapshot.sh):
Exports the current key to `snapshots/` and `public-key.asc`
- [`publish.sh`](scripts/publish.sh):
Pushes the current key to the keyservers
- [`security-txt.sh`](scripts/security-txt.sh):
Generates and clearsigns `security.txt`