Skip to content

Commit 6371592

Browse files
committed
ci(release): gate privileged workflows with release-admin actor guard
1 parent 93c6fab commit 6371592

14 files changed

Lines changed: 207 additions & 0 deletions

.github/workflows/build-tauri.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,17 @@ env:
5050
UI_REPO: ${{ github.repository }}
5151

5252
jobs:
53+
release_actor_guard:
54+
name: Release actor guard
55+
permissions:
56+
contents: read
57+
members: read
58+
uses: ./.github/workflows/release-actor-guard.yml
59+
5360
resolve_source:
5461
name: Resolve source ref to SHA
5562
runs-on: ubuntu-latest
63+
needs: [release_actor_guard]
5664
outputs:
5765
source_sha: ${{ steps.resolve.outputs.source_sha }}
5866
steps:

.github/workflows/deploy.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,16 @@ concurrency:
5959
cancel-in-progress: false
6060

6161
jobs:
62+
release_actor_guard:
63+
if: (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call' || startsWith(github.ref_name, 'deploy/production/') || startsWith(github.ref_name, 'deploy/preview/')) && !(github.event_name == 'push' && contains(github.actor, '[bot]'))
64+
name: Release actor guard
65+
permissions:
66+
contents: read
67+
members: read
68+
uses: ./.github/workflows/release-actor-guard.yml
69+
6270
deploy:
71+
needs: [release_actor_guard]
6372
runs-on: ubuntu-latest
6473
# Deploy branches are promoted from release workflows. Those pushes may be authored by bots,
6574
# and we prefer deploying via explicit workflow_call (to avoid relying on push-trigger semantics).

.github/workflows/promote-branch.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,15 @@ concurrency:
7272
cancel-in-progress: false
7373

7474
jobs:
75+
release_actor_guard:
76+
name: Release actor guard
77+
permissions:
78+
contents: read
79+
members: read
80+
uses: ./.github/workflows/release-actor-guard.yml
81+
7582
promote:
83+
needs: [release_actor_guard]
7684
runs-on: ubuntu-latest
7785
environment: release-shared
7886
steps:

.github/workflows/promote-docs.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,15 @@ concurrency:
6565
cancel-in-progress: false
6666

6767
jobs:
68+
release_actor_guard:
69+
name: Release actor guard
70+
permissions:
71+
contents: read
72+
members: read
73+
uses: ./.github/workflows/release-actor-guard.yml
74+
6875
promote:
76+
needs: [release_actor_guard]
6977
runs-on: ubuntu-latest
7078
environment: release-shared
7179
steps:

.github/workflows/promote-server.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,15 @@ concurrency:
8080
cancel-in-progress: false
8181

8282
jobs:
83+
release_actor_guard:
84+
name: Release actor guard
85+
permissions:
86+
contents: read
87+
members: read
88+
uses: ./.github/workflows/release-actor-guard.yml
89+
8390
promote:
91+
needs: [release_actor_guard]
8492
runs-on: ubuntu-latest
8593
environment: release-shared
8694
steps:

.github/workflows/promote-ui.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,15 @@ concurrency:
155155
cancel-in-progress: false
156156

157157
jobs:
158+
release_actor_guard:
159+
name: Release actor guard
160+
permissions:
161+
contents: read
162+
members: read
163+
uses: ./.github/workflows/release-actor-guard.yml
164+
158165
promote:
166+
needs: [release_actor_guard]
159167
runs-on: ubuntu-latest
160168
environment: release-shared
161169
outputs:

.github/workflows/promote-website.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,15 @@ concurrency:
8080
cancel-in-progress: false
8181

8282
jobs:
83+
release_actor_guard:
84+
name: Release actor guard
85+
permissions:
86+
contents: read
87+
members: read
88+
uses: ./.github/workflows/release-actor-guard.yml
89+
8390
promote:
91+
needs: [release_actor_guard]
8492
runs-on: ubuntu-latest
8593
environment: release-shared
8694
steps:

.github/workflows/providers-contracts.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,15 @@ concurrency:
7878
cancel-in-progress: true
7979

8080
jobs:
81+
release_actor_guard:
82+
name: Release actor guard
83+
permissions:
84+
contents: read
85+
members: read
86+
uses: ./.github/workflows/release-actor-guard.yml
87+
8188
trusted_ref_guard:
89+
needs: [release_actor_guard]
8290
runs-on: ubuntu-latest
8391
steps:
8492
- name: Enforce trusted refs for manual dispatch

.github/workflows/publish-github-release.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,15 @@ concurrency:
5454
cancel-in-progress: false
5555

5656
jobs:
57+
release_actor_guard:
58+
name: Release actor guard
59+
permissions:
60+
contents: read
61+
members: read
62+
uses: ./.github/workflows/release-actor-guard.yml
63+
5764
publish:
65+
needs: [release_actor_guard]
5866
runs-on: ubuntu-latest
5967
environment: release-shared
6068
steps:
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: GUARD — Release Actor Authorization
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
team_slug:
7+
description: Team slug allowed to run release/deploy/provider workflows
8+
required: false
9+
type: string
10+
default: release-admins
11+
org:
12+
description: GitHub organization that owns the team
13+
required: false
14+
type: string
15+
default: ""
16+
17+
permissions:
18+
contents: read
19+
members: read
20+
21+
jobs:
22+
authorize:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Verify triggering actor is in release admin team
26+
env:
27+
INPUT_ORG: ${{ inputs.org }}
28+
INPUT_TEAM_SLUG: ${{ inputs.team_slug }}
29+
REPO_OWNER: ${{ github.repository_owner }}
30+
GITHUB_TOKEN: ${{ github.token }}
31+
run: |
32+
set -euo pipefail
33+
34+
actor="${GITHUB_TRIGGERING_ACTOR:-${GITHUB_ACTOR:-}}"
35+
if [ -z "${actor}" ]; then
36+
echo "Unable to resolve triggering actor." >&2
37+
exit 1
38+
fi
39+
40+
team_slug="${INPUT_TEAM_SLUG:-release-admins}"
41+
org="${INPUT_ORG:-$REPO_OWNER}"
42+
if [ -z "${org}" ]; then
43+
echo "Unable to resolve organization owner." >&2
44+
exit 1
45+
fi
46+
47+
echo "Authorizing actor '${actor}' against team '${org}/${team_slug}'."
48+
49+
gh api --silent \
50+
--header "Accept: application/vnd.github+json" \
51+
"orgs/${org}/teams/${team_slug}/memberships/${actor}" >/dev/null

0 commit comments

Comments
 (0)