Versions
The Secrets Blueprint workflows pin sops 3.13.3 and yq v4.47.1, verify both downloads against a SHA-256 checksum before they run, and reference every GitHub Action by its full commit SHA. The repository holds no OpenTofu or Terragrunt code: the keys and the identity it uses belong to the Azure Baseline and follow the Baseline's pins.
Where the pins live
Both workflows carry the same env block, so the pull-request check and the sync decrypt with the same sops and parse with the same yq:
env:
SECRETS_NAMESPACE: acme # TODO: set to your namespace (vault names kv-<namespace>-<env>-<slug>-app)
ENV: eus2 # TODO: set to the home region slug of the platform baseline (vault names)
SOPS_VERSION: "3.13.3"
SOPS_SHA256: e5bec3346a873ae91d871550f3e698c1aad962aff462a080e40f25fde17fef6b # sops-v3.13.3.linux.amd64, release checksums.txt
YQ_VERSION: v4.47.1
YQ_SHA256: 0fb28c6680193c41b364193d0c0fc4a03177aecde51cfc04d506b1517158c2fb # yq_linux_amd64 v4.47.1, release checksums
The install step downloads the Linux amd64 release of each tool into the runner's temporary folder and runs sha256sum --check --strict on both files. A download whose checksum does not match fails the job before any secret is decrypted.
- name: Install sops and yq (pinned, checksum-verified)
run: |
bin="$RUNNER_TEMP/bin"
mkdir -p "$bin"
curl -fsSL -o "$bin/sops" "https://github.com/getsops/sops/releases/download/v${SOPS_VERSION}/sops-v${SOPS_VERSION}.linux.amd64"
curl -fsSL -o "$bin/yq" "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64"
printf '%s %s\n' "$SOPS_SHA256" "$bin/sops" "$YQ_SHA256" "$bin/yq" | sha256sum --check --strict
chmod 0755 "$bin/sops" "$bin/yq"
echo "$bin" >> "$GITHUB_PATH"
"$bin/sops" --disable-version-check --version
"$bin/yq" --version
Tools
| Tool | Version | Where it runs |
|---|---|---|
sops | 3.13.3, SHA-256 verified | Both workflows, installed in each job |
yq (mikefarah) | v4.47.1, SHA-256 verified | Both workflows, installed in each job |
| Azure CLI | The runner image's | push-to-keyvault.sh reads, writes and lists secrets with az |
| Bash | 4 or later | Both scripts (associative arrays) |
Engineers who edit secrets on their own machines need sops and yq v4 locally, Bash 4 or later, and an Azure CLI session from az login.
GitHub Actions
| Action | Version | Used by |
|---|---|---|
actions/checkout | v7.0.1 | Both workflows, with persist-credentials: false |
azure/login | v3.1.0 | Both workflows, federated sign-in |
actions/github-script | v9.0.0 | The plan workflow, the pull request comment |
Each is referenced by its full commit SHA with the version in a comment, so a moved tag cannot change what runs.
Pre-commit hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: check-yaml
exclude: '^(sandbox|dev|staging|prod)/' # encrypted files carry a sops: block that is valid YAML, but keep the hook off them
- id: detect-private-key
- id: end-of-file-fixer
- repo: local
hooks:
- id: sops-encrypted
name: Stage files must be SOPS-encrypted
# Folded scalar: the command contains ": ", which a plain YAML scalar does not allow.
entry: >-
bash -c 'rc=0; for f in "$@"; do grep -q "^sops:" "$f" || { echo "NOT ENCRYPTED: $f (sops --encrypt --in-place $f)"; rc=1; }; done; exit $rc' --
language: system
files: '^(sandbox|dev|staging|prod)/.*\.ya?ml$'
pre-commit-hooks v6.0.0 provides check-yaml (kept off the stage folders), detect-private-key and end-of-file-fixer. The local sops-encrypted hook rejects any stage file without a sops: block. See pre-commit for how the hooks run.
Keys
The SOPS keys are RSA 4096 keys with a yearly rotation policy; the Baseline creates four, and the repository uses the three of dev, staging and prod until sandbox is opted in. .sops.yaml names each key by its version, so after a rotation the platform leads update the three URLs and re-encrypt the data keys; SOPS configuration explains why and what changes.
How versions change
A version change is its own pull request against both workflows: the new version and the new checksum from the release's checksum file, in plan.yml and sync.yml together. CODEOWNERS sends .github/ to the platform leads and infrastructure admins. The policy is on the versioning policy page, and the versions across all BuiltForProd repositories are in the release notes.