From 4bfb62fb272ff0f077f8d162b1dd867e75844920 Mon Sep 17 00:00:00 2001 From: alessandrovitali Date: Thu, 8 Oct 2026 01:56:19 +0200 Subject: [PATCH] actions: add SOPS decryption action --- sops/README.md | 5 +++++ sops/action.yml | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 sops/README.md create mode 100644 sops/action.yml diff --git a/sops/README.md b/sops/README.md new file mode 100644 index 0000000..f11832e --- /dev/null +++ b/sops/README.md @@ -0,0 +1,5 @@ +# secret handling with SOPS + +generate new age keys with `age-keygen -o ~/.config/sops/age/key-name.txt`. encrypt local secrets with `sops -e service-name/.env > service-name/.sops.env`. + +the action installs the pinned, checksum-verified SOPS build for the runner's OS/arch and decrypts every `*.sops.*` file except `.sops.yaml`, writing `service-name/.sops.env` back to `service-name/.env` via a temp file and atomic move. diff --git a/sops/action.yml b/sops/action.yml new file mode 100644 index 0000000..a24918b --- /dev/null +++ b/sops/action.yml @@ -0,0 +1,55 @@ +name: decrypt SOPS secrets +description: installs SOPS and decrypts all *.sops.* files using an age key + +inputs: + sops-age-key: + description: age private key SOPS_AGE_KEY + required: true + +runs: + using: "composite" + steps: + - name: install SOPS + shell: bash + env: + ## renovate: datasource=github-releases depName=getsops/sops + SOPS_VERSION: v3.13.3 ## latest + run: | + set -euo pipefail + + os=$(uname -s | tr '[:upper:]' '[:lower:]') + arch=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') + asset="sops-${SOPS_VERSION}.${os}.${arch}" + url="https://github.com/getsops/sops/releases/download/${SOPS_VERSION}" + + curl -fsSL -o "$asset" "${url}/${asset}" -o checksums.txt "${url}/sops-${SOPS_VERSION}.checksums.txt" + grep " ${asset}$" checksums.txt | shasum -a 256 -c - + + chmod +x "$asset" + sudo mv "$asset" /usr/local/bin/sops + rm checksums.txt + + - name: decrypt .sops files + shell: bash + env: + SOPS_AGE_KEY: ${{ inputs.sops-age-key }} + run: | + set -euo pipefail + + echo "searching for SOPS files to decrypt..." + + ## decrypt every *.sops.* file (except .sops.yaml) + while IFS= read -r -d '' file; do + dir=$(dirname "$file"); base=$(basename "$file") + output_file="$dir/${base/.sops/}" + + echo "decrypting '$file' to '$output_file'" + + tmp=$(mktemp) + sops --decrypt "$file" > "$tmp" + [ -s "$tmp" ] || { echo "decryption of '$file' produced empty output" >&2; exit 1; } + chmod 600 "$tmp" + mv "$tmp" "$output_file" + done < <(find . -type f -name "*.sops.*" -not -name ".sops.yaml" -print0) + + echo "SOPS decryption complete."