Skip to content

age keystore: support stream reading#2163

Open
Dexmachi wants to merge 8 commits intogetsops:mainfrom
Dexmachi:main
Open

age keystore: support stream reading#2163
Dexmachi wants to merge 8 commits intogetsops:mainfrom
Dexmachi:main

Conversation

@Dexmachi
Copy link
Copy Markdown

@Dexmachi Dexmachi commented Apr 29, 2026

closes #2162
closes #1303

Why

Currently, sops fails to read multiple age keys passed via process substitution or named pipes (like /dev/fd/X) because these are read-once streams without "seek" support, throwing an EOF when it attempts to read it more than once during loadIdentities() (which happens when there are multiple recipients or during parsing retries).

Passing keys via file descriptors is a fairly common security pattern to prevent decrypted secrets from ever touching the disk or leaking into child processes via /prox/PPID/environ.

How

  • Added a fileStreamCache (sync.Map) and a readStreamSafe(path string) ([]byte, error) helper function in age/keysource.go.

  • When loading identities, readStreamSafe checks if the path points to a stream with a .HasPrefix, checking for /dev/fd/ or /proc/

  • if it is a stream: It reads it into memory and caches the []byte for subsequent calls within the same process.

  • if it is not a stream: It bypasses the cache and reads from the disk, as it was originally.

  • a exportable ClearFileStreamCache() was created in order to zero out cached memory.

  • All unit tests passing.

  • Locally tested intended behavior, works as intended.

@felixfontein
Copy link
Copy Markdown
Contributor

Thanks for your contribution! Can you please make sure to sign-off your commits (otherwise this cannot be merged), and to remove all unrelated code changes (reformatting) from the PR? Thanks.

@Dexmachi
Copy link
Copy Markdown
Author

Thanks for your contribution! Can you please make sure to sign-off your commits (otherwise this cannot be merged), and to remove all unrelated code changes (reformatting) from the PR? Thanks.

oh, damn, ofc, I am sorry

Signed-off-by: Caio Rocha de Oliveira <caiorocoli@gmail.com>
Signed-off-by: Caio Rocha de Oliveira <caiorocoli@gmail.com>
@Dexmachi
Copy link
Copy Markdown
Author

Dexmachi commented Apr 29, 2026

I'm kinda stupid, rolled back my changes only to forget to declare 1 variable and 1 dep lmao

(and the signoff)

Signed-off-by: Caio Rocha de Oliveira <caiorocoli@gmail.com>
Signed-off-by: Caio Rocha de Oliveira <caiorocoli@gmail.com>
Signed-off-by: Caio Rocha de Oliveira <caiorocoli@gmail.com>
@felixfontein felixfontein changed the title fix(age): support /dev/fd and /proc stream reading age keystore: support /dev/fd and /proc stream reading May 2, 2026
Comment thread age/keysource.go Outdated
Signed-off-by: Caio Rocha de Oliveira <caiorocoli@gmail.com>
@felixfontein
Copy link
Copy Markdown
Contributor

Please note that your PR has a conflict.

Signed-off-by: Caio Rocha de Oliveira <caiorocoli@gmail.com>
@Dexmachi
Copy link
Copy Markdown
Author

Dexmachi commented May 3, 2026

Please note that your PR has a conflict.

Trying to resolve it right now

Signed-off-by: Caio Rocha de Oliveira <caiorocoli@gmail.com>
@Dexmachi Dexmachi changed the title age keystore: support /dev/fd and /proc stream reading age keystore: support stream reading May 3, 2026
@Dexmachi Dexmachi requested a review from felixfontein May 5, 2026 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SOPS_AGE_KEY_FILE not being able to read from file descriptors in SSS setups Passing age keys via stdin SOPS_AGE_KEY_FILE=/dev/stdin not working

2 participants