112 lines
3.9 KiB
Nix
112 lines
3.9 KiB
Nix
|
{ sys, pkgs, inputs, flake, ... }: {
|
||
|
imports = [ inputs.sops-nix.nixosModules.sops ];
|
||
|
sops = {
|
||
|
age.sshKeyPaths = [ "${sys.ssh.path}/${sys.ssh.privateKey}" ];
|
||
|
#age.keyFile = "/home/${sys.username}/.config/sops/age/keys.txt"; # This file is expected to be provided from outside the nix-store
|
||
|
age.generateKey = false;
|
||
|
};
|
||
|
|
||
|
home-manager.users.${sys.username}.home.packages = with pkgs; [
|
||
|
sops
|
||
|
age
|
||
|
ssh-to-age
|
||
|
( writeShellApplication {
|
||
|
name = "sops-nix";
|
||
|
runtimeInputs = [ git ssh-to-age openssh yq ];
|
||
|
text = ''
|
||
|
#! bash
|
||
|
|
||
|
# shellcheck disable=SC2002
|
||
|
# shellcheck disable=SC2016
|
||
|
|
||
|
REPO_ROOT="/home/${sys.username}/${flake.repoPath}"
|
||
|
# shellcheck disable=SC2034
|
||
|
SOPS_AGE_KEY_FILE="/home/${sys.username}/.config/sops/age/keys.txt"
|
||
|
|
||
|
listSecrets () {
|
||
|
# shellcheck disable=SC2002
|
||
|
SOPS_REGEX="$(cat "$REPO_ROOT/.sops.yaml" | yq -y '.creation_rules.[].path_regex' | head -n1)"
|
||
|
find "$REPO_ROOT" -regextype posix-extended -regex "$SOPS_REGEX"
|
||
|
}
|
||
|
|
||
|
getPubkey () {
|
||
|
ADDRESS="$1"
|
||
|
AGE_PUBKEY="$(ssh-keyscan -t ed25519 "$ADDRESS" | ssh-to-age)"
|
||
|
echo "$AGE_PUBKEY"
|
||
|
}
|
||
|
|
||
|
addPubkey () { # Note: Does not edit any files. Prints .sops.yaml with the given key added.
|
||
|
AGE_PUBKEY="$1"
|
||
|
# shellcheck disable=SC2002,SC2016
|
||
|
cat "$REPO_ROOT"/.sops.yaml |\
|
||
|
yq -y --arg key "$AGE_PUBKEY" '.keys += [$key]' |\
|
||
|
yq -y --arg key "$AGE_PUBKEY" '.creation_rules.[].key_groups.[].age += [$key]'
|
||
|
}
|
||
|
|
||
|
updateKey () { # Note: Interactive
|
||
|
sops updatekeys --input-type json "$1"
|
||
|
}
|
||
|
|
||
|
encryptFile () { # Note: All encrypted files are in json format
|
||
|
FILE="$1"
|
||
|
FILE_EXT="''$''\{FILE##*.}"
|
||
|
case "$FILE_EXT" in
|
||
|
"env") FILE_TYPE=dotenv ;;
|
||
|
"json") FILE_TYPE=json ;;
|
||
|
"yaml|yml") FILE_TYPE=yaml ;;
|
||
|
"ini") FILE_TYPE=ini ;;
|
||
|
*) FILE_TYPE=binary ;;
|
||
|
esac
|
||
|
sops --encrypt --config "$REPO_ROOT/.sops.yaml" --input-type "$FILE_TYPE" --output-type json "$FILE"
|
||
|
}
|
||
|
|
||
|
decryptFile () { # Note: All encrypted files are in json format.
|
||
|
# File extension is used as the hint for decrypted file type.
|
||
|
FILE="$1"
|
||
|
FILE_EXT="''$''\{FILE##*.}"
|
||
|
case "$FILE_EXT" in
|
||
|
"env") FILE_TYPE=dotenv ;;
|
||
|
"json") FILE_TYPE=json ;;
|
||
|
"yaml|yml") FILE_TYPE=yaml ;;
|
||
|
"ini") FILE_TYPE=ini ;;
|
||
|
*) FILE_TYPE=binary ;;
|
||
|
esac
|
||
|
sops --decrypt --config "$REPO_ROOT/.sops.yaml" --input-type json --output-type "$FILE_TYPE" "$FILE"
|
||
|
}
|
||
|
|
||
|
isJson () {
|
||
|
FILE="$1"
|
||
|
jq -e . >/dev/null 2>&1 <<<"$(cat "$FILE")" && return 0 || return 1;
|
||
|
}
|
||
|
|
||
|
isEncrypted () {
|
||
|
FILE="$1"
|
||
|
FILE_EXT="''$''\{FILE##*.}"
|
||
|
case "$FILE_EXT" in
|
||
|
"env") FILE_TYPE=dotenv ;;
|
||
|
"json") FILE_TYPE=json ;;
|
||
|
"yaml|yml") FILE_TYPE=yaml ;;
|
||
|
"ini") FILE_TYPE=ini ;;
|
||
|
*) FILE_TYPE=binary ;;
|
||
|
esac
|
||
|
if isJson "$FILE" && [[ "$(sops filestatus "$FILE")" == '{"encrypted":true}' ]]; then echo True; else echo False; fi
|
||
|
}
|
||
|
|
||
|
listSecretStatus () {
|
||
|
for file in $(listSecrets); do
|
||
|
FILE="$(realpath -s --relative-to="$REPO_ROOT" "$file")"
|
||
|
echo -n "$FILE: " |\
|
||
|
xargs echo -n
|
||
|
if sops --decrypt --input-type json "$file" >/dev/null 2>&1; then
|
||
|
echo Decryptable
|
||
|
else
|
||
|
echo "Not decryptable"
|
||
|
fi
|
||
|
done
|
||
|
}
|
||
|
|
||
|
"$@"
|
||
|
'';
|
||
|
} )
|
||
|
];
|
||
|
}
|