Skip to content

feature: filter rekey operations by recipient - #295

Open
felixscheinost wants to merge 3 commits into
ryantm:mainfrom
felixscheinost:rekey-specific-identity
Open

felixscheinost wants to merge 3 commits into
ryantm:mainfrom
felixscheinost:rekey-specific-identity

Conversation

@felixscheinost

@felixscheinost felixscheinost commented Oct 25, 2024 •

Copy link
Copy Markdown
Contributor

Allow agenix --rekey 'PUBLIC_KEY' to re-encrypt only secrets whose current rules contain that exact recipient string. Without the optional argument, rekey continues to process every secret. This helps apply a shared recipient change without re-encrypting unrelated machine or personal secrets.

Pass the filter to Nix as data, reject empty or unmatched filters, and leave unselected ciphertext unchanged. Selection uses the current rules; it does not inspect recipients in existing ciphertext.

Validation: package CLI tests cover recipient selection, unchanged excluded files, retained plaintext, and invalid or injection-like filter strings. Linux and macOS CI pass.

Review follow-up: rekey filters now use a Bash array and JSON data passed to Nix. Multiple quoted public keys select the union of matching secrets, repeated --rekey options accumulate filters, and --rekey -v still selects every secret. Tests cover multi-key selection, unrelated files, repeated options, option parsing, and strings that would be Nix code if interpolated unsafely. Linux CLI/ShellCheck, formatting, and documentation validation pass.

Currently rekey re-encrypts all files.

For my personal use-case, agenix would ideally only files that require rekeying, i.e. files where the identities changed.
But I don’t think there’s an (easy) way to achieve that with `age` currently, as there’s no way to get the current recipients from an encrypted file?

This change would allow the user to manually specifiy that only secrets that contain a given identity should be rekeyed.

In my use-case this is handy as when I add a new server I want all secrets that are shared between servers (where the new identity was added) to be rekeyed, but I don’t want all secrets that are personal to different servers to also be rekeyed.
Comment thread pkgs/agenix.sh Outdated
Comment thread pkgs/agenix.sh Outdated
Comment thread pkgs/agenix.sh Outdated

@benaryorg benaryorg left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see one issue with the PR as it is right now; it adds no value over running env EDITOR=: agenix --edit $identity, unless I'm somehow mistaken.

I do think providing some benefit would be nice, hence allowing multiple arguments seems like a solid choice.

Comment thread pkgs/agenix.sh Outdated
Comment thread pkgs/agenix.sh Outdated
Comment thread pkgs/agenix.sh Outdated
Comment thread pkgs/agenix.sh Outdated
@felixscheinost

Copy link
Copy Markdown
Contributor Author

I see one issue with the PR as it is right now; it adds no value over running env EDITOR=: agenix --edit $identity, unless I'm somehow mistaken.

@benaryorg I must be misunderstanding what you mean because the command you suggested would only update a single file, $identity, defined in secrets.nix, right?

If I substitute $identity for one of the identities actually used in "secrets.nix" I get, as expected, an error:

error: attribute '"ssh-ed25519 [snip]"' missing

       at «string»:1:39:

            1| (let rules = import ./secrets.nix; in rules."ssh-ed25519 [snip]".publicKeys)

This change allows one to rekey all secrets where a given identity is included. I use this when adding a new host that shares a couple of secrets with other hosts. I don't want to need to manually look through which secrets need to be rekeyed and I also don't want to rekey ALL my secrets.

I recently came across https://github.com/oddlama/agenix-rekey, which might also provide this feature? I am planning to look into it.

@benaryorg

Copy link
Copy Markdown

Addendum to my review:

I had a missing [@] in a place (line 198, comment is edited now).
Due to a limitation of GitHub's review feature I can't seem to comment on lines outside the diff though, because line 200 or so also needs to be changed from for FILE in $FILES to for FILE in "${FILES[@]}".
There may be other bits around the changed code which may need minor adaption.


@benaryorg I must be misunderstanding what you mean because the command you suggested would only update a single file, $identity, defined in secrets.nix, right?

Oooohh, damn. Yes, you are 100% right, passing the identity doesn't do much.
Somehow I mixed up identities with files halfway through, sorry about that.

I recently came across https://github.com/oddlama/agenix-rekey, which might also provide this feature? I am planning to look into it.

It would still be nice to have rekeying in agenix directly.
I for instance do not use agenix-rekey, and instead have secrets.nix import my regular infra repo and calculates the secrets, their paths, and the identities from the configuration itself (i.e. I only add agenix secrets in nix and create/rekey the file).
Today I did however replace one machine with another and ran into the issue of having to rekey a bunch of files, and stumbled upon this PR, and it would absolutely be a great fit in agenix itself.

@ryantm ryantm changed the title feat: rekey only specific identity feature: filter rekey operations by recipient Oct 2, 2026

This branch has not been deployed

No deployments
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.

3 participants