security(storage): keep the repository signing key out of list() enumeration - #965
Merged
Conversation
|
🐳 Test image pushed: docker pull ghcr.io/getnora-io/nora:pr-965
docker run --rm -p 4000:4000 ghcr.io/getnora-io/nora:pr-965 |
ertime037
approved these changes
Sep 6, 2026
devitway
force-pushed
the
feat/891-signing-key-leak
branch
from
September 6, 2026 08:35
be4a77f to
7d95325
Compare
…eration StorageBackend::list()/list_with_meta() enumerated the .signing/ key as an artifact, so backup (0644 tar), migrate (plaintext object) and GC swept it up. Exclude the .signing/ prefix on both backends via a shared is_reserved_signing_key helper; the key loads via direct filesystem I/O, never list(), so zero runtime impact. Regression tests: list_excludes_signing_key, test_backup_omits_signing_key.
|
🐳 Test image pushed: docker pull ghcr.io/getnora-io/nora:pr-965
docker run --rm -p 4000:4000 ghcr.io/getnora-io/nora:pr-965 |
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 repository signing private key lives at
<storage.path>/.signing/nora.keyand is persisted owner-only (0600). ButStorageBackend::list()/list_with_meta()enumerated it as if it were an artifact — only the pin sidecar was excluded — so it was swept into every enumeration-based operation:backupwrote it into the tar at mode0644(widened from the on-disk0600), andrestorethen left it0644on disk;migrate --to s3copied it into the bucket as a plaintext object, with no owner-only protection;This excludes the
.signing/prefix from both backends' enumeration (local + object store), mirroring the existing pin-sidecar exclusion, through a single sharedis_reserved_signing_keyhelper. The key is loaded through direct filesystem I/O, never throughlist(), so the exclusion has zero runtime impact; operators provision it out-of-band.Tests
Regression guards that fail without the fix:
list()no longer surfaces the key (storage::local::tests::list_excludes_signing_key);backup::tests::test_backup_omits_signing_key).