namecheap-secret-sync #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: namecheap-secret-sync | |
| on: | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| id-token: write | |
| pull-requests: write | |
| concurrency: | |
| group: namecheap-secret-sync | |
| cancel-in-progress: false | |
| jobs: | |
| sync: | |
| # The OIDC trust policy is restricted to the default branch; fail closed if | |
| # someone dispatches this workflow from another ref. | |
| if: github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 10 | |
| env: | |
| AWS_REGION: us-west-2 | |
| SECRET_ID: xnoto-namecheap-api | |
| SOPS_VERSION: v3.13.3 | |
| SOPS_SHA256: e5bec3346a873ae91d871550f3e698c1aad962aff462a080e40f25fde17fef6b | |
| AWS_ROLE_ARN: ${{ vars.NAMECHEAP_SECRET_SYNC_AWS_ROLE_ARN }} | |
| SECRETS_KMS_KEY_ARN: ${{ vars.NAMECHEAP_SECRET_SYNC_SECRETS_KMS_KEY_ARN }} | |
| steps: | |
| - name: Check required configuration | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| set +x | |
| test -n "$AWS_ROLE_ARN" | |
| test -n "$SECRETS_KMS_KEY_ARN" | |
| - name: Check out main | |
| uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 | |
| with: | |
| ref: main | |
| persist-credentials: true | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@e6de054238d6b7531b4efff3b6587d9aade6a06c # v6.2.3 | |
| with: | |
| aws-region: ${{ env.AWS_REGION }} | |
| role-to-assume: ${{ env.AWS_ROLE_ARN }} | |
| role-session-name: namecheap-secret-sync-${{ github.run_id }} | |
| role-duration-seconds: 900 | |
| allowed-account-ids: 332355796717 | |
| mask-aws-account-id: true | |
| unset-current-credentials: true | |
| retry-max-attempts: 3 | |
| action-timeout-s: 30 | |
| inline-session-policy: >- | |
| {"Version":"2012-10-17","Statement":[{"Sid":"ReadOnlyNamecheapSecret","Effect":"Allow","Action":"secretsmanager:GetSecretValue","Resource":"arn:aws:secretsmanager:us-west-2:332355796717:secret:xnoto-namecheap-api-*"},{"Sid":"DecryptOnlyRequiredKeys","Effect":"Allow","Action":"kms:Decrypt","Resource":["arn:aws:kms:us-west-2:332355796717:key/0a45c0f6-71dc-4d54-ab33-9df4de1a9e91","${{ env.SECRETS_KMS_KEY_ARN }}"]}]} | |
| - name: Install verified SOPS | |
| id: sops | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| set +x | |
| sops_bin="$RUNNER_TEMP/sops-${SOPS_VERSION}" | |
| curl --fail --silent --show-error --location --proto '=https' --tlsv1.2 \ | |
| --output "$sops_bin" \ | |
| "https://github.com/getsops/sops/releases/download/${SOPS_VERSION}/sops-${SOPS_VERSION}.linux.amd64" | |
| printf '%s %s\n' "$SOPS_SHA256" "$sops_bin" | sha256sum --check --status | |
| chmod 0755 "$sops_bin" | |
| printf 'path=%s\n' "$sops_bin" >> "$GITHUB_OUTPUT" | |
| - name: Update the allowlisted encrypted key | |
| env: | |
| SOPS_BIN: ${{ steps.sops.outputs.path }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| set +x | |
| umask 077 | |
| # Fail rather than create a new key; no decrypted value is emitted. | |
| "$SOPS_BIN" --decrypt --extract '["namecheap_api_key"]' secrets/secrets.yaml >/dev/null | |
| namecheap_api_key="$(aws secretsmanager get-secret-value \ | |
| --secret-id "$SECRET_ID" \ | |
| --query SecretString \ | |
| --output text)" | |
| test -n "$namecheap_api_key" | |
| # --set edits the existing encrypted document in place, limiting the | |
| # plaintext lifetime to this shell and avoiding decrypted files. | |
| json_value="$(printf '%s' "$namecheap_api_key" | jq -Rsc '.')" | |
| "$SOPS_BIN" --set '["namecheap_api_key"] '"$json_value" secrets/secrets.yaml | |
| unset json_value namecheap_api_key | |
| - name: Create a scoped pull request | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| set +x | |
| branch="automation/secret-sync-namecheap-api-${GITHUB_RUN_ID}" | |
| git add -- secrets/secrets.yaml | |
| git diff --cached --check | |
| if git diff --cached --quiet; then | |
| printf '%s\n' 'The encrypted value is already current; no pull request was created.' | |
| exit 0 | |
| fi | |
| changed_files="$(git diff --cached --name-only)" | |
| test "$changed_files" = "secrets/secrets.yaml" | |
| git switch --create "$branch" | |
| git config user.name 'github-actions[bot]' | |
| git config user.email '41898282+github-actions[bot]@users.noreply.github.com' | |
| git commit -m 'chore: sync Namecheap API key' | |
| git push --set-upstream origin "$branch" | |
| pr_url="$(gh pr create \ | |
| --base main \ | |
| --head "$branch" \ | |
| --title 'chore: sync Namecheap API key' \ | |
| --body 'Automated manual sync of the encrypted `namecheap_api_key` value. Review the encrypted-file diff before merge.')" | |
| { | |
| printf 'Created branch: `%s`\n\n' "$branch" | |
| printf 'Created pull request: %s\n' "$pr_url" | |
| } >> "$GITHUB_STEP_SUMMARY" |