From 0381711323c86eb7d64bc71f22e1960e92dbc5d4 Mon Sep 17 00:00:00 2001 From: Steve Gontzes Date: Tue, 26 May 2026 19:29:30 -0400 Subject: [PATCH 1/2] Derive shortened release role names --- .github/workflows/release.yaml | 67 +++++++++++++++++++++++++-- Makefile | 9 +++- scripts/derive-iam-role-name.sh | 68 ++++++++++++++++++++++++++++ scripts/test-derive-iam-role-name.sh | 35 ++++++++++++++ 4 files changed, 173 insertions(+), 6 deletions(-) create mode 100755 scripts/derive-iam-role-name.sh create mode 100755 scripts/test-derive-iam-role-name.sh diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index def1c34..7e932b9 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -204,6 +204,19 @@ jobs: ref: ${{ needs.determine-workflows-ref.outputs.ref }} persist-credentials: false + - name: Derive AWS role names + id: role-names + working-directory: _workflows + shell: bash + env: + REPO_OWNER: ${{ github.event.repository.owner.login }} + REPO_NAME: ${{ github.event.repository.name }} + run: | + bash ./scripts/derive-iam-role-name.sh \ + --prefix GHA-Artifacts- \ + --suffix "${REPO_OWNER}-${REPO_NAME}" \ + --output-name gha_artifacts_role_name >> "$GITHUB_OUTPUT" + - name: Set up Go for caller uses: actions/setup-go@v6 with: @@ -256,7 +269,7 @@ jobs: - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v5 with: - role-to-assume: arn:aws:iam::025044153841:role/GHA-Artifacts-${{ github.event.repository.owner.login }}-${{ github.event.repository.name }} + role-to-assume: arn:aws:iam::025044153841:role/${{ steps.role-names.outputs.gha_artifacts_role_name }} aws-region: us-west-2 - name: Run GoReleaser @@ -472,6 +485,19 @@ jobs: ref: ${{ needs.determine-workflows-ref.outputs.ref }} persist-credentials: false + - name: Derive AWS role names + id: role-names + working-directory: _workflows + shell: bash + env: + REPO_OWNER: ${{ github.event.repository.owner.login }} + REPO_NAME: ${{ github.event.repository.name }} + run: | + bash ./scripts/derive-iam-role-name.sh \ + --prefix GHA-Artifacts- \ + --suffix "${REPO_OWNER}-${REPO_NAME}" \ + --output-name gha_artifacts_role_name >> "$GITHUB_OUTPUT" + - name: Set up Go for caller uses: actions/setup-go@v6 with: @@ -639,7 +665,7 @@ jobs: - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v5 with: - role-to-assume: arn:aws:iam::025044153841:role/GHA-Artifacts-${{ github.event.repository.owner.login }}-${{ github.event.repository.name }} + role-to-assume: arn:aws:iam::025044153841:role/${{ steps.role-names.outputs.gha_artifacts_role_name }} aws-region: us-west-2 - name: Calculate S3 directory @@ -781,6 +807,24 @@ jobs: ref: ${{ needs.determine-workflows-ref.outputs.ref }} persist-credentials: false + - name: Derive AWS role names + id: role-names + if: inputs.docker == true || inputs.lambda == true + working-directory: _workflows + shell: bash + env: + REPO_OWNER: ${{ github.event.repository.owner.login }} + REPO_NAME: ${{ github.event.repository.name }} + run: | + bash ./scripts/derive-iam-role-name.sh \ + --prefix GHA-Artifacts- \ + --suffix "${REPO_OWNER}-${REPO_NAME}" \ + --output-name gha_artifacts_role_name >> "$GITHUB_OUTPUT" + bash ./scripts/derive-iam-role-name.sh \ + --prefix GitHubActionsECRPushRole- \ + --suffix "${REPO_NAME}" \ + --output-name ecr_push_role_name >> "$GITHUB_OUTPUT" + - name: Set up Go for caller if: inputs.docker == true || inputs.lambda == true uses: actions/setup-go@v6 @@ -875,7 +919,7 @@ jobs: if: inputs.docker == true uses: aws-actions/configure-aws-credentials@v5 with: - role-to-assume: arn:aws:iam::025044153841:role/GHA-Artifacts-${{ github.event.repository.owner.login }}-${{ github.event.repository.name }} + role-to-assume: arn:aws:iam::025044153841:role/${{ steps.role-names.outputs.gha_artifacts_role_name }} aws-region: us-east-1 - name: Login to Public ECR @@ -899,7 +943,7 @@ jobs: if: inputs.lambda == true uses: aws-actions/configure-aws-credentials@v5 with: - role-to-assume: "arn:aws:iam::168442440833:role/GitHubActionsECRPushRole-${{ github.event.repository.name }}" + role-to-assume: "arn:aws:iam::168442440833:role/${{ steps.role-names.outputs.ecr_push_role_name }}" aws-region: us-west-2 - name: Login to Lambda ECR @@ -1015,6 +1059,19 @@ jobs: ref: ${{ needs.determine-workflows-ref.outputs.ref }} persist-credentials: false + - name: Derive AWS role names + id: role-names + working-directory: _workflows + shell: bash + env: + REPO_OWNER: ${{ github.event.repository.owner.login }} + REPO_NAME: ${{ github.event.repository.name }} + run: | + bash ./scripts/derive-iam-role-name.sh \ + --prefix GHA-Artifacts- \ + --suffix "${REPO_OWNER}-${REPO_NAME}" \ + --output-name gha_artifacts_role_name >> "$GITHUB_OUTPUT" + - name: Set up Go for workflows uses: actions/setup-go@v6 with: @@ -1042,7 +1099,7 @@ jobs: - name: Configure AWS credentials via OIDC uses: aws-actions/configure-aws-credentials@v5 with: - role-to-assume: arn:aws:iam::025044153841:role/GHA-Artifacts-${{ github.event.repository.owner.login }}-${{ github.event.repository.name }} + role-to-assume: arn:aws:iam::025044153841:role/${{ steps.role-names.outputs.gha_artifacts_role_name }} aws-region: us-west-2 - name: Create unified checksums file diff --git a/Makefile b/Makefile index 808ccec..ecd701b 100644 --- a/Makefile +++ b/Makefile @@ -10,9 +10,16 @@ protofmt: @echo "Protobuf formatting complete." .PHONY: test -test: +test: test-go test-scripts + +.PHONY: test-go +test-go: go test ./cmd/record-release ./cmd/generate-manifest ./cmd/merge-manifests +.PHONY: test-scripts +test-scripts: + bash scripts/test-derive-iam-role-name.sh + .PHONY: workflow-validate workflow-validate: yq '.' .github/workflows/release.yaml >/dev/null diff --git a/scripts/derive-iam-role-name.sh b/scripts/derive-iam-role-name.sh new file mode 100755 index 0000000..161a843 --- /dev/null +++ b/scripts/derive-iam-role-name.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +set -euo pipefail + +iam_role_name_max_length=64 +iam_role_name_hash_length=8 + +usage() { + echo "usage: derive-iam-role-name.sh --prefix PREFIX --suffix SUFFIX --output-name NAME" >&2 +} + +prefix="" +suffix="" +output_name="iam_role_name" + +while [ "$#" -gt 0 ]; do + case "$1" in + --prefix) + prefix="${2:-}" + shift 2 + ;; + --suffix) + suffix="${2:-}" + shift 2 + ;; + --output-name) + output_name="${2:-}" + shift 2 + ;; + -h | --help) + usage + exit 0 + ;; + *) + usage + echo "unknown argument: $1" >&2 + exit 2 + ;; + esac +done + +if [ -z "$prefix" ] || [ -z "$suffix" ] || [ -z "$output_name" ]; then + usage + echo "prefix, suffix, and output-name are required" >&2 + exit 2 +fi + +if [[ ! "$output_name" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]]; then + echo "output-name must be a safe GitHub output key" >&2 + exit 2 +fi + +role_name="${prefix}${suffix}" +if [ "${#role_name}" -gt "$iam_role_name_max_length" ]; then + if command -v shasum >/dev/null 2>&1; then + hash_output="$(printf '%s' "$role_name" | shasum -a 256)" + elif command -v sha256sum >/dev/null 2>&1; then + hash_output="$(printf '%s' "$role_name" | sha256sum)" + else + echo "shasum or sha256sum is required" >&2 + exit 1 + fi + hash="${hash_output%% *}" + hash="${hash:0:$iam_role_name_hash_length}" + keep=$((iam_role_name_max_length - iam_role_name_hash_length - 1)) + role_name="${role_name:0:$keep}-${hash}" +fi + +printf '%s=%s\n' "$output_name" "$role_name" diff --git a/scripts/test-derive-iam-role-name.sh b/scripts/test-derive-iam-role-name.sh new file mode 100755 index 0000000..73645f0 --- /dev/null +++ b/scripts/test-derive-iam-role-name.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -euo pipefail + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +script="${script_dir}/derive-iam-role-name.sh" + +assert_output() { + local want="$1" + shift + local got + got="$(bash "$script" "$@")" + if [ "$got" != "$want" ]; then + echo "got: $got" >&2 + echo "want: $want" >&2 + exit 1 + fi +} + +assert_output \ + "gha_artifacts_role_name=GHA-Artifacts-ConductorOne-baton-axiomatic-jira" \ + --prefix GHA-Artifacts- \ + --suffix ConductorOne-baton-axiomatic-jira \ + --output-name gha_artifacts_role_name + +assert_output \ + "gha_artifacts_role_name=GHA-Artifacts-ConductorOne-baton-axiomatic-github-enter-f6552060" \ + --prefix GHA-Artifacts- \ + --suffix ConductorOne-baton-axiomatic-github-enterprise-cloud \ + --output-name gha_artifacts_role_name + +assert_output \ + "ecr_push_role_name=GitHubActionsECRPushRole-baton-axiomatic-github-enterprise-cloud" \ + --prefix GitHubActionsECRPushRole- \ + --suffix baton-axiomatic-github-enterprise-cloud \ + --output-name ecr_push_role_name From 1344447b2c1916fb610cadd719f59b6d54640b91 Mon Sep 17 00:00:00 2001 From: Steve Gontzes Date: Tue, 26 May 2026 19:35:55 -0400 Subject: [PATCH 2/2] Harden release role name helper --- scripts/derive-iam-role-name.sh | 1 + scripts/test-derive-iam-role-name.sh | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/scripts/derive-iam-role-name.sh b/scripts/derive-iam-role-name.sh index 161a843..ec35941 100755 --- a/scripts/derive-iam-role-name.sh +++ b/scripts/derive-iam-role-name.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -euo pipefail +export LC_ALL=C iam_role_name_max_length=64 iam_role_name_hash_length=8 diff --git a/scripts/test-derive-iam-role-name.sh b/scripts/test-derive-iam-role-name.sh index 73645f0..076a50c 100755 --- a/scripts/test-derive-iam-role-name.sh +++ b/scripts/test-derive-iam-role-name.sh @@ -28,8 +28,20 @@ assert_output \ --suffix ConductorOne-baton-axiomatic-github-enterprise-cloud \ --output-name gha_artifacts_role_name +assert_output \ + "gha_artifacts_role_name=GHA-Artifacts-ConductorOne-baton-axiomatic-github-enter-571914a9" \ + --prefix GHA-Artifacts- \ + --suffix ConductorOne-baton-axiomatic-github-enterprise-cloud-extra-long-name \ + --output-name gha_artifacts_role_name + assert_output \ "ecr_push_role_name=GitHubActionsECRPushRole-baton-axiomatic-github-enterprise-cloud" \ --prefix GitHubActionsECRPushRole- \ --suffix baton-axiomatic-github-enterprise-cloud \ --output-name ecr_push_role_name + +assert_output \ + "ecr_push_role_name=GitHubActionsECRPushRole-baton-axiomatic-github-enterpr-302f51c5" \ + --prefix GitHubActionsECRPushRole- \ + --suffix baton-axiomatic-github-enterprise-cloud-extra \ + --output-name ecr_push_role_name