chore: enforce private-key file permission check for Ed25519 key - #16
Merged
Conversation
loadXMSSMTKey refuses to load a private key whose file is group- or world-accessible, but loadEd25519Key did not apply the same guard. Both are signing keys of the timestamping service, so an Ed25519 key left with lax permissions was loaded silently while an equally-exposed XMSSMT key was rejected. Extract the shared permission predicate into keyFilePermsInsecure, apply it in both loaders, and add a regression test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rubenhensen
previously approved these changes
Jul 20, 2026
rubenhensen
marked this pull request as ready for review
July 20, 2026 10:02
A blanket perm&077 != 0 check cannot pass on Kubernetes: secret volumes are written root-owned, and fsGroup — the standard mechanism for exposing them to a non-root container — chowns them to the pod's group and yields mode 0440. The group-read bit is the only thing that lets the process read its own key, so refusing it makes the check incompatible with the platform rather than stricter. Follow PostgreSQL's ssl_key_file precedent: still refuse any world bits, group-write and group-execute, but accept group-read when the file's group is the process' effective or a supplementary group — that grants nobody access the process does not already have.
rubenhensen
approved these changes
Jul 20, 2026
w-ensink
approved these changes
Jul 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The XMSSMT key loader refuses to load a private key file with lax permissions; the Ed25519 key loader did not apply the same guard. Both are signing keys of the timestamping service, so an Ed25519 key left with lax file permissions was loaded silently while an equally-exposed XMSSMT key would be rejected.
This change:
keyFilePermsInsecure,loadXMSSMTKeyandloadEd25519Key,The predicate is deliberately not the blanket
perm&077 != 0the XMSSMT loader used before: that check cannot pass on Kubernetes, where secret volumes are written root-owned andfsGroup— the standard mechanism for exposing them to a non-root container — yields mode0440. Instead, following PostgreSQL'sssl_key_fileprecedent:Verified against a running cluster deployment (secret mounted with
defaultMode: 0400+fsGroup, resulting inroot:1000 0440): the old check would have crash-looped the pod on the next image pull; the amended check accepts it while still refusing genuinely exposed keys.Defense-in-depth hardening; no protocol or config changes.
go test -race ./...passes.Found during a routine in-depth security review of this repository.