59. pepsi-keydisc

Find a correspondent’s public key or certificate, and record how much its source is worth.

59.1. Role

pepsi-keydisc is the key-discovery layer: given an e-mail address it finds the correspondent’s OpenPGP key or S/MIME certificate, records where it came from and whether the lookup was DNSSEC-validated, and caches it in pepsi.peer_key. It is not a stage. It connects through [pepsi-postgres] and is configured entirely by [pepsi-keydiscovery].

Discovery is asynchronous and outside the stages. A stage that needs a key it does not have in cache performs no network I/O: it commits the work it has already done, pauses the message and enqueues a request in pepsi.key_request; a discovery instance answers the request and, in the same round-trip that stores the key, releases every message parked on that address. So no stage worker ever waits on a key server, a hundred messages to one correspondent cost one lookup, and a request that settles without a key releases its waiters just the same — the services find keys, the stages decide about mail. Reference: pepsi-keydisc(1).

The chapter Key management explains the trust ranking these results are judged by, and how the discovery layer relates to the key store as a whole.

59.2. Features

  • One process per method, from the systemd template pepsi-keydisc@.service: @dane, @wkd-advanced, @wkd-direct, @vks and (in a build with the ldap cargo feature) @ldap. A hung LDAP bind cannot stall WKD, and turning a method off is systemctl disable pepsi-keydisc@ldap. An instance whose method is absent from [pepsi-keydiscovery] SOURCES refuses to start, because the stop rule waits only for the methods SOURCES names.

  • The two WKD methods are separate ranks, and therefore separate instances run concurrently rather than a fallback chain — running direct only “if advanced fails” would accept the weaker answer whenever the stronger one was merely slow.

  • DANE is AD-gated. OPENPGPKEY (RFC 7929) and SMIMEA (RFC 8162) are refused outright without the resolver’s DNSSEC AD bit: an unvalidated DNS answer is not a weaker answer, it is no answer.

  • A hardened fetch for WKD and VKS: HTTPS only, certificate validation with no insecure mode, at most one HTTPS-to-HTTPS redirect to the same host, refusal to connect to loopback/private/link-local addresses, a byte cap enforced while streaming, a deadline on every step, and IDNA A-label conversion. A returned key whose User ID does not name the queried address is discarded.

  • probe — run the whole fan-out for one address and print what each method found, storing nothing (not even a negative-cache entry), as a diagnostic.

  • The narrowest database role in the deployment, provisioned by pepsi-setup: peer_key, key_request, the keydisc_* functions, and on pepsi.ingress only SELECT plus a column-level UPDATE (status, timeout) — enough to wake a parked message and nothing more. It runs as its own pepsi-keydisc account with no setuid or setgid bit.

59.3. See also

pepsi-keys, pepsi-setup, Key management, RFC Index, pepsi-keydisc(1), pepsi-keys(1), pepsi.conf(5).