Skip to content

age: optional caching of key command output#2247

Open
oivindoh wants to merge 1 commit into
getsops:mainfrom
oivindoh:cache-age-key-cmd
Open

age: optional caching of key command output#2247
oivindoh wants to merge 1 commit into
getsops:mainfrom
oivindoh:cache-age-key-cmd

Conversation

@oivindoh

@oivindoh oivindoh commented Jul 9, 2026

Copy link
Copy Markdown

Since sops loads identities once per recipient it attempts, executing SOPS_AGE_KEY_CMD/SOPS_AGE_SSH_PRIVATE_KEY_CMD each time when set, using slow clients like bw is painful when files have many recipients. In my testing, a file with 7 recipients where the matching key is last takes ~20 seconds to finish decrypting.

To fix this, add the opt-in SOPS_AGE_KEY_CMD_CACHE to make the command run at most once per process and reuse the result for each recipient. If unset or false, no behaviour changes.

Opt-in because a command may use SOPS_AGE_RECIPIENT to return a different key per recipient; caching can break that (a command that exits non-zero for unknown recipients survives, since errors are not cached). The flag is only for commands that ignore the recipient.

  • Only successful outputs are cached.
  • The lock is not held while the command runs, so concurrent misses behave as uncached.
  • No invalidation: a long-lived keyservice serves the cached key until restart. The flag targets short-lived CLI use.

Tests cover once-per-process with the flag, once-per-recipient without, and errors not being cached.

SOPS constructs one MasterKey per recipient and loads identities for
each in turn, executing SOPS_AGE_KEY_CMD / SOPS_AGE_SSH_PRIVATE_KEY_CMD
once per attempted recipient. With a slow command (e.g. a password
manager CLI) a single decrypt multiplies into many seconds.

Setting SOPS_AGE_KEY_CMD_CACHE=true executes each command at most once
per process and reuses the output for every recipient. Opt-in because
the command receives SOPS_AGE_RECIPIENT and may legitimately return a
different key per recipient.

Only successful outputs are cached, and the lock is not held while the
command runs, so a failing or slow command cannot poison or serialise
decrypts in long-lived processes such as the keyservice.

Signed-off-by: Øivind Hoel <oivind.hoel@gmail.com>
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.

1 participant