Skip to content

Commit 8f1318e

Browse files
leliaclaude
andcommitted
fix(dependency-review): gate enterprise on write-access (non-fork), not author_association
author_association only reflects PUBLIC org membership, so private members (the common case here) show as CONTRIBUTOR and were misclassified -> the enterprise job always skipped. Switch the trust gate to "non-fork PR and not Dependabot": only accounts with write access can push an in-repo branch, the same boundary GitHub uses for secret exposure. No read:org token needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 6d2433c commit 8f1318e

1 file changed

Lines changed: 17 additions & 11 deletions

File tree

.github/workflows/dependency-review.yml

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ name: dependency-review
44
# and maintainers. `inspect` classifies the PR, then exactly one Socket
55
# Firewall (sfw) install smoke job runs when Python deps change:
66
#
7-
# - python-sfw-smoke-enterprise -- trusted SocketDev org members
8-
# (author_association OWNER/MEMBER) on an in-repo (non-fork) PR. Runs the
7+
# - python-sfw-smoke-enterprise -- trusted authors: any in-repo (non-fork)
8+
# PR other than Dependabot's (i.e. someone with write access). Runs the
99
# authenticated enterprise edition for full org-policy enforcement. The
1010
# SOCKET_SFW_API_TOKEN is scoped to the `socket-firewall` environment, so
1111
# it is the ONLY job that can read the token.
12-
# - python-sfw-smoke-free -- everyone else (Dependabot, forks, outside
13-
# collaborators, external contributors). Anonymous free edition, no token.
14-
# This job never references the secret.
12+
# - python-sfw-smoke-free -- everyone else (Dependabot + all fork PRs from
13+
# external contributors). Anonymous free edition, no token. This job never
14+
# references the secret.
1515
#
1616
# Splitting the jobs (rather than picking a mode in one job) keeps the token
1717
# out of scope on every untrusted run and satisfies zizmor's
@@ -76,18 +76,24 @@ jobs:
7676
7777
- name: Classify PR trust
7878
id: trust
79-
# Trusted == a SocketDev org member (OWNER/MEMBER) on an in-repo
80-
# (non-fork) PR. Note this references NO secret -- it only decides which
81-
# smoke job runs; the token stays scoped to the enterprise job.
79+
# Trusted == any in-repo (non-fork) PR that isn't Dependabot's. Only
80+
# accounts with write access can push a branch to this repo, so a
81+
# non-fork PR already implies a trusted author -- the same boundary
82+
# GitHub uses to decide whether secrets are exposed at all.
83+
#
84+
# NB: author_association is deliberately NOT used to require strict org
85+
# membership. It only reflects PUBLIC org membership, so private members
86+
# (the common case) show up as CONTRIBUTOR and would be misclassified.
87+
# Reliable strict-membership detection would need a read:org token or
88+
# public membership. This step references NO secret regardless -- it
89+
# only decides which smoke job runs.
8290
env:
8391
IS_DEPENDABOT: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
8492
IS_FORK: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
8593
AUTHOR_ASSOC: ${{ github.event.pull_request.author_association }}
8694
run: |
8795
is_trusted=false
88-
if [ "$IS_DEPENDABOT" != "true" ] \
89-
&& [ "$IS_FORK" != "true" ] \
90-
&& printf '%s' "$AUTHOR_ASSOC" | grep -qE '^(OWNER|MEMBER)$'; then
96+
if [ "$IS_DEPENDABOT" != "true" ] && [ "$IS_FORK" != "true" ]; then
9197
is_trusted=true
9298
fi
9399

0 commit comments

Comments
 (0)