name: secrets-guard

# Fail the build if any infra/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 infra/deploy/secrets/,
# so they're correctly ignored.
#
# Deliberately NOT path-filtered: it's a ~1s grep, and a backstop that only
# runs when you expect it to isn't a backstop.

on:
  pull_request:
  push:
    branches: [dev, main, release]

jobs:
  encrypted:
    runs-on: docker
    steps:
      - uses: actions/checkout@v4
      - name: Assert infra/deploy/secrets/*.yaml are SOPS-encrypted
        run: |
          set -euo pipefail
          shopt -s nullglob
          files=(infra/deploy/secrets/*.yaml)
          if [ ${#files[@]} -eq 0 ]; then
            echo "no infra/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
