Merge branch 'main' into issue-204

This commit is contained in:
Giorgio Gallo 2024-07-25 11:36:52 +02:00 committed by GitHub
commit 2bc0bf8ad7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 209 additions and 92 deletions

35
.github/release-drafter.yml vendored Normal file
View file

@ -0,0 +1,35 @@
name-template: '$RESOLVED_VERSION'
tag-template: '$RESOLVED_VERSION'
categories:
- title: '🚀 Features'
labels:
- 'feature'
- 'enhancement'
- title: '🐛 Bug Fixes'
labels:
- 'fix'
- 'bugfix'
- 'bug'
- title: '🧰 Development'
label: 'dev'
- title: '🤖 Dependencies'
label: 'dependencies'
- title: '🔒 Security'
label: 'security'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
version-resolver:
major:
labels:
- 'major'
minor:
labels:
- 'minor'
patch:
labels:
- 'patch'
default: patch
template: |
## Changes
$CHANGES

View file

@ -9,27 +9,37 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: cachix/install-nix-action@v22 - uses: cachix/install-nix-action@v22
with: with:
extra_nix_config: "system-features = nixos-test benchmark big-parallel kvm" extra_nix_config: |
system-features = nixos-test recursive-nix benchmark big-parallel kvm
extra-experimental-features = recursive-nix nix-command flakes
- run: nix build - run: nix build
- run: nix build .#doc - run: nix build .#doc
- run: nix fmt . -- --check - run: nix fmt . -- --check
- run: nix flake check - run: nix flake check
tests-darwin: tests-darwin:
runs-on: macos-11 runs-on: macos-12
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: cachix/install-nix-action@v22 - uses: cachix/install-nix-action@v24
with: with:
extra_nix_config: "system-features = nixos-test benchmark big-parallel kvm" extra_nix_config: |
system-features = nixos-test recursive-nix benchmark big-parallel kvm
extra-experimental-features = recursive-nix nix-command flakes
- run: nix build - run: nix build
- run: nix build .#doc - run: nix build .#doc
- run: nix fmt . -- --check - run: nix fmt . -- --check
- run: nix flake check - run: nix flake check
- name: "Install nix-darwin module" - name: "Install nix-darwin module"
run: | run: |
system=$(nix build --no-link --print-out-paths .#checks.x86_64-darwin.integration) # https://github.com/ryantm/agenix/pull/230#issuecomment-1867025385
${system}/activate-user
sudo ${system}/activate sudo mv /etc/nix/nix.conf{,.bak}
nix \
--extra-experimental-features 'nix-command flakes' \
build .#checks.x86_64-darwin.integration
./result/activate-user
sudo ./result/activate
- name: "Test nix-darwin module" - name: "Test nix-darwin module"
run: | run: |
sudo /run/current-system/sw/bin/agenix-integration sudo /run/current-system/sw/bin/agenix-integration

33
.github/workflows/release-drafter.yml vendored Normal file
View file

@ -0,0 +1,33 @@
name: Release Drafter
on:
push:
# branches to consider in the event; optional, defaults to all
branches:
- main
# pull_request event is required only for autolabeler
pull_request:
# Only following types are handled by the action, but one can default to all as well
types: [opened, reopened, synchronize]
# pull_request_target event is required for autolabeler to support PRs from forks
pull_request_target:
types: [opened, reopened, synchronize]
permissions:
contents: read
jobs:
update_release_draft:
permissions:
# write permission is required to create a github release
contents: write
# write permission is required for autolabeler
# otherwise, read permission is required at least
pull-requests: write
runs-on: ubuntu-latest
steps:
# Drafts your next Release notes as Pull Requests are merged into "main"
- uses: release-drafter/release-drafter@v5
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -45,7 +45,7 @@ All files in the Nix store are readable by any system user, so it is not a suita
## Notices ## Notices
* Password-protected ssh keys: since the underlying tool age/rage do not support ssh-agent, password-protected ssh keys do not work well. For example, if you need to rekey 20 secrets you will have to enter your password 20 times. * Password-protected ssh keys: since age does not support ssh-agent, password-protected ssh keys do not work well. For example, if you need to rekey 20 secrets you will have to enter your password 20 times.
## Installation ## Installation
@ -205,7 +205,7 @@ You can run the CLI tool ad-hoc without installing it:
nix run github:ryantm/agenix -- --help nix run github:ryantm/agenix -- --help
``` ```
But you can also add it permanently into a [NixOS module](https://nixos.wiki/wiki/NixOS_modules) But you can also add it permanently into a [NixOS module](https://wiki.nixos.org/wiki/NixOS_modules)
(replace system "x86_64-linux" with your system): (replace system "x86_64-linux" with your system):
```nix ```nix
@ -273,7 +273,7 @@ e.g. inside your `flake.nix` file:
* your local computer usually in `~/.ssh`, e.g. `~/.ssh/id_ed25519.pub`. * your local computer usually in `~/.ssh`, e.g. `~/.ssh/id_ed25519.pub`.
* from a running target machine with `ssh-keyscan`: * from a running target machine with `ssh-keyscan`:
```ShellSession ```ShellSession
$ ssh-keyscan <user>@<ip-address> $ ssh-keyscan <ip-address>
... ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKzxQgondgEYcLpcPdJLrTdNgZ2gznOHCAxMdaceTUT1 ... ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKzxQgondgEYcLpcPdJLrTdNgZ2gznOHCAxMdaceTUT1
... ...
``` ```
@ -445,7 +445,7 @@ Example:
#### `age.secrets.<name>.symlink` #### `age.secrets.<name>.symlink`
`age.secrets.<name>.symlink` is a boolean. If true (the default), `age.secrets.<name>.symlink` is a boolean. If true (the default),
secrets are symlinked to `age.secrets.<name>.path`. If false, secerts secrets are symlinked to `age.secrets.<name>.path`. If false, secrets
are copied to `age.secrets.<name>.path`. Usually, you want to keep are copied to `age.secrets.<name>.path`. Usually, you want to keep
this as true, because it secure cleanup of secrets no longer this as true, because it secure cleanup of secrets no longer
used. (The symlink will still be there, but it will be broken.) If used. (The symlink will still be there, but it will be broken.) If
@ -487,7 +487,7 @@ Example of a secret with a name different from its attrpath:
#### `age.ageBin` #### `age.ageBin`
`age.ageBin` the string of the path to the `age` binary. Usually, you `age.ageBin` the string of the path to the `age` binary. Usually, you
don't need to change this. Defaults to `rage/bin/rage`. don't need to change this. Defaults to `age/bin/age`.
Overriding `age.ageBin` example: Overriding `age.ageBin` example:
@ -592,13 +592,13 @@ improved upon by reading the identities from the age file.)
#### Overriding age binary #### Overriding age binary
The agenix CLI uses `rage` by default as its age implemenation, you The agenix CLI uses `age` by default as its age implemenation, you
can use the reference implementation `age` with Flakes like this: can use the `rage` implementation with Flakes like this:
```nix ```nix
{pkgs,agenix,...}:{ {pkgs,agenix,...}:{
environment.systemPackages = [ environment.systemPackages = [
(agenix.packages.x86_64-linux.default.override { ageBin = "${pkgs.age}/bin/age"; }) (agenix.packages.x86_64-linux.default.override { ageBin = "${pkgs.rage}/bin/rage"; })
]; ];
} }
``` ```
@ -623,6 +623,8 @@ authentication code (MAC) like other implementations like GPG or
[sops](https://github.com/Mic92/sops-nix) have, however this was left [sops](https://github.com/Mic92/sops-nix) have, however this was left
out for simplicity in `age`. out for simplicity in `age`.
Additionally you should only encrypt secrets that you are able to make useless in the event that they are decrypted in the future and be ready to rotate them periodically as [age](https://github.com/FiloSottile/age) is [as of 19th June 2024 NOT Post-Quantum Safe](https://github.com/FiloSottile/age/discussions/231#discussioncomment-3092773) and so in case the threat actor can access your encrypted keys e.g. via their use in a public repository then they can utilize the strategy of [Harvest Now, Decrypt Later](https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later) to store your keys now for later decryption including the case where a major vulnerability is found that would expose the secrets. See https://github.com/FiloSottile/age/issues/578 for details.
## Contributing ## Contributing
* The main branch is protected against direct pushes * The main branch is protected against direct pushes

View file

@ -1,3 +1,3 @@
# Notices {#notices} # Notices {#notices}
* Password-protected ssh keys: since the underlying tool age/rage do not support ssh-agent, password-protected ssh keys do not work well. For example, if you need to rekey 20 secrets you will have to enter your password 20 times. * Password-protected ssh keys: since age does not support ssh-agent, password-protected ssh keys do not work well. For example, if you need to rekey 20 secrets you will have to enter your password 20 times.

View file

@ -1,12 +1,12 @@
# Overriding age binary {#overriding-age-binary} # Overriding age binary {#overriding-age-binary}
The agenix CLI uses `rage` by default as its age implemenation, you The agenix CLI uses `age` by default as its age implemenation, you
can use the reference implementation `age` with Flakes like this: can use the `rage` implementation with Flakes like this:
```nix ```nix
{pkgs,agenix,...}:{ {pkgs,agenix,...}:{
environment.systemPackages = [ environment.systemPackages = [
(agenix.packages.x86_64-linux.default.override { ageBin = "${pkgs.age}/bin/age"; }) (agenix.packages.x86_64-linux.default.override { ageBin = "${pkgs.rage}/bin/rage"; })
]; ];
} }
``` ```

View file

@ -166,7 +166,7 @@ Example of a secret with a name different from its attrpath:
### `age.ageBin` ### `age.ageBin`
`age.ageBin` the string of the path to the `age` binary. Usually, you `age.ageBin` the string of the path to the `age` binary. Usually, you
don't need to change this. Defaults to `rage/bin/rage`. don't need to change this. Defaults to `age/bin/age`.
Overriding `age.ageBin` example: Overriding `age.ageBin` example:

View file

@ -7,11 +7,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1673295039, "lastModified": 1700795494,
"narHash": "sha256-AsdYgE8/GPwcelGgrntlijMg4t3hLFJFCRF3tL5WVjA=", "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=",
"owner": "lnl7", "owner": "lnl7",
"repo": "nix-darwin", "repo": "nix-darwin",
"rev": "87b9d090ad39b25b2400029c64825fc2a8868943", "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -28,11 +28,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1682203081, "lastModified": 1703113217,
"narHash": "sha256-kRL4ejWDhi0zph/FpebFYhzqlOBrk0Pl3dzGEKSAlEw=", "narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "32d3e39c491e2f91152c84f8ad8b003420eab0a1", "rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -43,11 +43,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1677676435, "lastModified": 1703013332,
"narHash": "sha256-6FxdcmQr5JeZqsQvfinIMr0XcTyTuR7EXX0H3ANShpQ=", "narHash": "sha256-+tFNwMvlXLbJZXiMHqYq77z/RfmpfpiI3yjL6o/Zo9M=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a08d6979dd7c82c4cef0dcc6ac45ab16051c1169", "rev": "54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -61,7 +61,23 @@
"inputs": { "inputs": {
"darwin": "darwin", "darwin": "darwin",
"home-manager": "home-manager", "home-manager": "home-manager",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs",
"systems": "systems"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
} }
} }
}, },

View file

@ -11,6 +11,7 @@
url = "github:nix-community/home-manager"; url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
systems.url = "github:nix-systems/default";
}; };
outputs = { outputs = {
@ -18,9 +19,9 @@
nixpkgs, nixpkgs,
darwin, darwin,
home-manager, home-manager,
systems,
}: let }: let
agenix = system: nixpkgs.legacyPackages.${system}.callPackage ./pkgs/agenix.nix {}; eachSystem = nixpkgs.lib.genAttrs (import systems);
doc = system: nixpkgs.legacyPackages.${system}.callPackage ./pkgs/doc.nix {};
in { in {
nixosModules.age = import ./modules/age.nix; nixosModules.age = import ./modules/age.nix;
nixosModules.default = self.nixosModules.age; nixosModules.default = self.nixosModules.age;
@ -33,30 +34,13 @@
overlays.default = import ./overlay.nix; overlays.default = import ./overlay.nix;
formatter.x86_64-darwin = nixpkgs.legacyPackages.x86_64-darwin.alejandra; formatter = eachSystem (system: nixpkgs.legacyPackages.${system}.alejandra);
packages.x86_64-darwin.agenix = agenix "x86_64-darwin";
packages.x86_64-darwin.doc = doc "x86_64-darwin";
packages.x86_64-darwin.default = self.packages.x86_64-darwin.agenix;
formatter.aarch64-darwin = nixpkgs.legacyPackages.aarch64-darwin.alejandra; packages = eachSystem (system: {
packages.aarch64-darwin.agenix = agenix "aarch64-darwin"; agenix = nixpkgs.legacyPackages.${system}.callPackage ./pkgs/agenix.nix {};
packages.aarch64-darwin.doc = doc "aarch64-darwin"; doc = nixpkgs.legacyPackages.${system}.callPackage ./pkgs/doc.nix {inherit self;};
packages.aarch64-darwin.default = self.packages.aarch64-darwin.agenix; default = self.packages.${system}.agenix;
});
formatter.aarch64-linux = nixpkgs.legacyPackages.aarch64-linux.alejandra;
packages.aarch64-linux.agenix = agenix "aarch64-linux";
packages.aarch64-linux.doc = doc "aarch64-linux";
packages.aarch64-linux.default = self.packages.aarch64-linux.agenix;
formatter.i686-linux = nixpkgs.legacyPackages.i686-linux.alejandra;
packages.i686-linux.agenix = agenix "i686-linux";
packages.i686-linux.doc = doc "i686-linux";
packages.i686-linux.default = self.packages.i686-linux.agenix;
formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.alejandra;
packages.x86_64-linux.agenix = agenix "x86_64-linux";
packages.x86_64-linux.default = self.packages.x86_64-linux.agenix;
packages.x86_64-linux.doc = doc "x86_64-linux";
checks = checks =
nixpkgs.lib.genAttrs ["aarch64-darwin" "x86_64-darwin"] (system: { nixpkgs.lib.genAttrs ["aarch64-darwin" "x86_64-darwin"] (system: {
@ -65,7 +49,10 @@
inherit system; inherit system;
modules = [ modules = [
./test/integration_darwin.nix ./test/integration_darwin.nix
"${darwin.outPath}/pkgs/darwin-installer/installer.nix"
# Allow new-style nix commands in CI
{nix.extraOptions = "experimental-features = nix-command flakes";}
home-manager.darwinModules.home-manager home-manager.darwinModules.home-manager
{ {
home-manager = { home-manager = {

View file

@ -61,7 +61,7 @@ with lib; let
${optionalString secretType.symlink '' ${optionalString secretType.symlink ''
# shellcheck disable=SC2193,SC2050 # shellcheck disable=SC2193,SC2050
[ "${secretType.path}" != "${cfg.secretsDir}/${secretType.name}" ] && ln -sfn "${cfg.secretsDir}/${secretType.name}" "${secretType.path}" [ "${secretType.path}" != "${cfg.secretsDir}/${secretType.name}" ] && ln -sfT "${cfg.secretsDir}/${secretType.name}" "${secretType.path}"
''} ''}
''; '';
@ -76,7 +76,7 @@ with lib; let
_agenix_generation="$(basename "$(readlink "${cfg.secretsDir}")" || echo 0)" _agenix_generation="$(basename "$(readlink "${cfg.secretsDir}")" || echo 0)"
(( ++_agenix_generation )) (( ++_agenix_generation ))
echo "[agenix] symlinking new secrets to ${cfg.secretsDir} (generation $_agenix_generation)..." echo "[agenix] symlinking new secrets to ${cfg.secretsDir} (generation $_agenix_generation)..."
ln -sfn "${cfg.secretsMountPoint}/$_agenix_generation" "${cfg.secretsDir}" ln -sfT "${cfg.secretsMountPoint}/$_agenix_generation" "${cfg.secretsDir}"
(( _agenix_generation > 1 )) && { (( _agenix_generation > 1 )) && {
echo "[agenix] removing old secrets (generation $(( _agenix_generation - 1 )))..." echo "[agenix] removing old secrets (generation $(( _agenix_generation - 1 )))..."
@ -155,7 +155,7 @@ with lib; let
''; '';
in { in {
options.age = { options.age = {
package = mkPackageOption pkgs "rage" {}; package = mkPackageOption pkgs "age" {};
secrets = mkOption { secrets = mkOption {
type = types.attrsOf secretType; type = types.attrsOf secretType;

View file

@ -69,6 +69,7 @@ with lib; let
IDENTITIES=() IDENTITIES=()
for identity in ${toString cfg.identityPaths}; do for identity in ${toString cfg.identityPaths}; do
test -r "$identity" || continue test -r "$identity" || continue
test -s "$identity" || continue
IDENTITIES+=(-i) IDENTITIES+=(-i)
IDENTITIES+=("$identity") IDENTITIES+=("$identity")
done done
@ -87,7 +88,7 @@ with lib; let
mv -f "$TMP_FILE" "$_truePath" mv -f "$TMP_FILE" "$_truePath"
${optionalString secretType.symlink '' ${optionalString secretType.symlink ''
[ "${secretType.path}" != "${cfg.secretsDir}/${secretType.name}" ] && ln -sfn "${cfg.secretsDir}/${secretType.name}" "${secretType.path}" [ "${secretType.path}" != "${cfg.secretsDir}/${secretType.name}" ] && ln -sfT "${cfg.secretsDir}/${secretType.name}" "${secretType.path}"
''} ''}
''; '';
@ -102,7 +103,7 @@ with lib; let
_agenix_generation="$(basename "$(readlink ${cfg.secretsDir})" || echo 0)" _agenix_generation="$(basename "$(readlink ${cfg.secretsDir})" || echo 0)"
(( ++_agenix_generation )) (( ++_agenix_generation ))
echo "[agenix] symlinking new secrets to ${cfg.secretsDir} (generation $_agenix_generation)..." echo "[agenix] symlinking new secrets to ${cfg.secretsDir} (generation $_agenix_generation)..."
ln -sfn "${cfg.secretsMountPoint}/$_agenix_generation" ${cfg.secretsDir} ln -sfT "${cfg.secretsMountPoint}/$_agenix_generation" ${cfg.secretsDir}
(( _agenix_generation > 1 )) && { (( _agenix_generation > 1 )) && {
echo "[agenix] removing old secrets (generation $(( _agenix_generation - 1 )))..." echo "[agenix] removing old secrets (generation $(( _agenix_generation - 1 )))..."
@ -189,9 +190,9 @@ in {
options.age = { options.age = {
ageBin = mkOption { ageBin = mkOption {
type = types.str; type = types.str;
default = "${pkgs.rage}/bin/rage"; default = "${pkgs.age}/bin/age";
defaultText = literalExpression '' defaultText = literalExpression ''
"''${pkgs.rage}/bin/rage" "''${pkgs.age}/bin/age"
''; '';
description = '' description = ''
The age executable to use. The age executable to use.

View file

@ -1,37 +1,66 @@
{ {
lib, lib,
stdenv, stdenv,
rage, age,
jq, jq,
nix, nix,
mktemp, mktemp,
diffutils, diffutils,
substituteAll, substituteAll,
ageBin ? "${rage}/bin/rage", ageBin ? "${age}/bin/age",
shellcheck, shellcheck,
}: }: let
stdenv.mkDerivation rec { bin = "${placeholder "out"}/bin/agenix";
pname = "agenix"; in
version = "0.14.0"; stdenv.mkDerivation rec {
src = substituteAll { pname = "agenix";
inherit ageBin version; version = "0.15.0";
jqBin = "${jq}/bin/jq"; src = substituteAll {
nixInstantiate = "${nix}/bin/nix-instantiate"; inherit ageBin version;
mktempBin = "${mktemp}/bin/mktemp"; jqBin = "${jq}/bin/jq";
diffBin = "${diffutils}/bin/diff"; nixInstantiate = "${nix}/bin/nix-instantiate";
src = ./agenix.sh; mktempBin = "${mktemp}/bin/mktemp";
}; diffBin = "${diffutils}/bin/diff";
dontUnpack = true; src = ./agenix.sh;
};
dontUnpack = true;
doInstallCheck = true;
installCheckInputs = [shellcheck];
postInstallCheck = ''
shellcheck ${bin}
${bin} -h | grep ${version}
doCheck = true; test_tmp=$(mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir')
checkInputs = [shellcheck]; export HOME="$test_tmp/home"
postCheck = '' export NIX_STORE_DIR="$test_tmp/nix/store"
shellcheck $src export NIX_STATE_DIR="$test_tmp/nix/var"
''; mkdir -p "$HOME" "$NIX_STORE_DIR" "$NIX_STATE_DIR"
function cleanup {
rm -rf "$test_tmp"
}
trap "cleanup" 0 2 3 15
installPhase = '' mkdir -p $HOME/.ssh
install -D $src ${placeholder "out"}/bin/agenix cp -r "${../example}" $HOME/secrets
''; chmod -R u+rw $HOME/secrets
(
umask u=rw,g=r,o=r
cp ${../example_keys/user1.pub} $HOME/.ssh/id_ed25519.pub
chown $UID $HOME/.ssh/id_ed25519.pub
)
(
umask u=rw,g=,o=
cp ${../example_keys/user1} $HOME/.ssh/id_ed25519
chown $UID $HOME/.ssh/id_ed25519
)
meta.description = "age-encrypted secrets for NixOS"; cd $HOME/secrets
} test $(${bin} -d secret1.age) = "hello"
'';
installPhase = ''
install -D $src ${bin}
'';
meta.description = "age-encrypted secrets for NixOS";
}

View file

@ -148,7 +148,7 @@ function cleanup {
trap "cleanup" 0 2 3 15 trap "cleanup" 0 2 3 15
function keys { function keys {
(@nixInstantiate@ --json --eval --strict -E "(let rules = import $RULES; in rules.\"$FILE\".publicKeys)" | @jqBin@ -r .[]) || exit 1 (@nixInstantiate@ --json --eval --strict -E "(let rules = import $RULES; in rules.\"$1\".publicKeys)" | @jqBin@ -r .[]) || exit 1
} }
function decrypt { function decrypt {
@ -188,7 +188,7 @@ function edit {
decrypt "$FILE" "$KEYS" || exit 1 decrypt "$FILE" "$KEYS" || exit 1
cp "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before" [ ! -f "$CLEARTEXT_FILE" ] || cp "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before"
[ -t 0 ] || EDITOR='cp /dev/stdin' [ -t 0 ] || EDITOR='cp /dev/stdin'
@ -204,7 +204,9 @@ function edit {
ENCRYPT=() ENCRYPT=()
while IFS= read -r key while IFS= read -r key
do do
ENCRYPT+=(--recipient "$key") if [ -n "$key" ]; then
ENCRYPT+=(--recipient "$key")
fi
done <<< "$KEYS" done <<< "$KEYS"
REENCRYPTED_DIR=$(@mktempBin@ -d) REENCRYPTED_DIR=$(@mktempBin@ -d)
@ -214,7 +216,9 @@ function edit {
@ageBin@ "${ENCRYPT[@]}" <"$CLEARTEXT_FILE" || exit 1 @ageBin@ "${ENCRYPT[@]}" <"$CLEARTEXT_FILE" || exit 1
mv -f "$REENCRYPTED_FILE" "$1" mkdir -p "$(dirname "$FILE")"
mv -f "$REENCRYPTED_FILE" "$FILE"
} }
function rekey { function rekey {