Skip to content

DKIM keys and rotation

The relay uses an RSA and Ed25519 key pair for the member domain and another pair for the operator domain. Member-domain signatures provide DMARC alignment for mail from that domain. Operator signatures support the operator’s own verification and feedback processing.

The implementation is in comail-relay: pkg/relay/dkim.go, pkg/relay/operator_dkim.go, and pkg/admin/operator_dkim.go.

Key generation

Enrollment generates RSA-2048 and Ed25519 keys. The selector base uses the enrollment date, such as atmos20260515. The signer appends r or e:

atmos20260515r._domainkey.example.com TXT v=DKIM1; k=rsa; p=...
atmos20260515e._domainkey.example.com TXT v=DKIM1; k=ed25519; p=...

Copy the exact values from enrollment. Receivers that do not support Ed25519 can verify the RSA signature.

Key storage

Member keys are stored in the member_domains table as encrypted PKCS#8 data when the PII encryption key is configured. The relay decrypts them for signing. They are not separate member key files, but they are part of the database and its backups.

Binary DKIM values have an encryption marker. They do not use the textual ENC: prefix used for fields such as forwarding addresses. Keep the database and its matching encryption key together in the recovery plan.

Operator keys live in the configured JSON key file, normally operator-dkim-keys.json under the state directory, with mode 0600. The file includes the selector, domain, and private keys. LoadOrCreateOperatorDKIMKeys loads it at startup or creates it if absent. Restarting with the existing file preserves its selector.

Legacy encryption migration

The admin API has two optional migration endpoints:

POST /admin/migrate-dkim-encryption
POST /admin/migrate-forward-to-encryption

They encrypt legacy plaintext values and skip already encrypted values. Both return {"rotated": N, "skipped": M} and require the configured PII key. The endpoints are disabled by default. Operators must follow the migration runbook and verify results before disabling them again.

These migrations do not generate new signing keys or re-encrypt existing ciphertext under a replacement PII key. They cannot repair data that no longer decrypts with the configured key.

Member key rotation

There is no dedicated member DKIM rotation endpoint in the checked release. Regenerating an SMTP/API key leaves DKIM keys unchanged.

Deleting and re-enrolling an account is not an equivalent rotation operation: it affects the account, domains, labels, and related state. Contact the operator to plan recovery from a suspected key compromise. Do not delete an account as routine key maintenance. A targeted rotation flow is tracked separately.

Operator key rotation

Operator rotation needs a coordinated key and DNS change. Removing the key file causes the next startup to create new keys, but that is not an overlapping rotation workflow. New signatures fail verification until the matching DNS records are available.

Selectors are date-based. Generating another key on the same day can reuse the selector with different key material, breaking verification for mail signed with the previous key. Plan distinct selectors and preserve the old keys and DNS records for the agreed recovery and in-flight-mail period, unless compromise requires revocation.

Hosted Comail changes must follow the reviewed infrastructure and CI/CD procedure. Do not manually delete the live key file or restart services to perform a rotation. An independent operator needs an equivalent tested procedure for distributing keys, publishing DNS, switching signers, and rolling back.

The protected /admin/operator/dkim view shows the active selector and public DNS values. Access uses the deployment’s admin authorization; it is not a member endpoint.

Rotation schedule

The relay does not provide an automatic DKIM rotation schedule. Operators must plan rotations according to their security requirements and the available tooling. A key incident can require immediate action; routine rotation should be rehearsed before production use.

Check a signing failure

GET /admin/dkim-check/{domain} compares stored member key material with DNS and reports selector health. Inspect key_parse_error and dns_error separately: a decryption failure and a DNS lookup failure need different recovery steps.

If keys stopped decrypting after a PII-key change, follow the encryption-key recovery runbook. The legacy plaintext migration does not convert ciphertext encrypted with an old key.

For operator signatures, compare the receiver’s s= selector and d= domain with the protected operator DKIM view and authoritative DNS. For member signatures, compare them with the records shown in the member’s domain setup.

Back to docs