37 lines
1.2 KiB
YAML
37 lines
1.2 KiB
YAML
|
|
name: secrets-guard
|
||
|
|
|
||
|
|
# Fail the build if any deploy/secrets/*.yaml is committed UNENCRYPTED. SOPS stores a
|
||
|
|
# `sops:` metadata block and wraps every value in ENC[...]; a plaintext leak has
|
||
|
|
# neither. This is the backstop against the classic "committed the decrypted file by
|
||
|
|
# accident" incident. .sops.yaml (the plaintext config) and README.md are not *.yaml
|
||
|
|
# under deploy/secrets/, so they're correctly ignored.
|
||
|
|
on:
|
||
|
|
pull_request:
|
||
|
|
push:
|
||
|
|
branches: [dev, main, release]
|
||
|
|
|
||
|
|
jobs:
|
||
|
|
encrypted:
|
||
|
|
runs-on: docker
|
||
|
|
steps:
|
||
|
|
- uses: actions/checkout@v4
|
||
|
|
- name: Assert deploy/secrets/*.yaml are SOPS-encrypted
|
||
|
|
run: |
|
||
|
|
set -euo pipefail
|
||
|
|
shopt -s nullglob
|
||
|
|
files=(deploy/secrets/*.yaml)
|
||
|
|
if [ ${#files[@]} -eq 0 ]; then
|
||
|
|
echo "no deploy/secrets/*.yaml yet — nothing to check"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
fail=0
|
||
|
|
for f in "${files[@]}"; do
|
||
|
|
if grep -q '^sops:' "$f" && grep -q 'ENC\[AES256_GCM' "$f"; then
|
||
|
|
echo "ok: $f is SOPS-encrypted"
|
||
|
|
else
|
||
|
|
echo "::error file=$f::NOT SOPS-encrypted — refusing to accept a plaintext secrets file"
|
||
|
|
fail=1
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
exit $fail
|