1- name : dependabot -review
1+ name : dependency -review
22
3- # Dependency-update PR guardrails for Dependabot-authored PRs.
3+ # Supply-chain guardrails for dependency-update PRs -- for BOTH Dependabot
4+ # and maintainers.
45#
5- # Runs only on PRs opened by dependabot[bot]. Inspects which files
6- # changed, then conditionally runs Socket Firewall (sfw) install smoke
7- # jobs for the affected manifests. Because sfw uses the free, anonymous
8- # Socket public-data path it needs NO API key, so we can run it from
9- # the unprivileged `pull_request` context without pull_request_target
10- # or any of its security tradeoffs.
6+ # Inspects the changed files, then conditionally runs Socket Firewall (sfw)
7+ # install smoke jobs for the affected manifests, picking the firewall edition
8+ # per PR:
9+ #
10+ # - Trusted SocketDev members on an in-repo (non-fork) PR, when the
11+ # SOCKET_API_TOKEN secret is present -> Socket Firewall ENTERPRISE
12+ # (authenticated, full org-policy enforcement).
13+ # - Everything else -- Dependabot, forks, external contributors, or a
14+ # missing token -> Socket Firewall FREE (anonymous, no API token), which
15+ # is safe in the unprivileged `pull_request` context.
16+ #
17+ # The mode degrades to free whenever the token is absent, so this workflow is
18+ # safe to ship before the secret exists and starts using enterprise
19+ # automatically once SOCKET_API_TOKEN is configured.
1120#
1221# Pattern adapted from SocketDev/socket-basics.
1322
@@ -19,12 +28,11 @@ permissions:
1928 contents : read
2029
2130concurrency :
22- group : dependabot -review-${{ github.event.pull_request.number }}
31+ group : dependency -review-${{ github.event.pull_request.number }}
2332 cancel-in-progress : true
2433
2534jobs :
2635 inspect :
27- if : github.event.pull_request.user.login == 'dependabot[bot]'
2836 runs-on : ubuntu-latest
2937 timeout-minutes : 5
3038 outputs :
3341 fixture_pypi_changed : ${{ steps.diff.outputs.fixture_pypi_changed }}
3442 dockerfile_changed : ${{ steps.diff.outputs.dockerfile_changed }}
3543 workflow_or_action_changed : ${{ steps.diff.outputs.workflow_or_action_changed }}
44+ sfw_mode : ${{ steps.mode.outputs.sfw_mode }}
3645 steps :
3746 - uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3847 with :
@@ -71,15 +80,42 @@ jobs:
7180 echo "workflow_or_action_changed=$(has_file '^\.github/workflows/|^\.github/actions/|^\.github/dependabot\.yml$')"
7281 } >> "$GITHUB_OUTPUT"
7382
83+ - name : Determine Socket Firewall mode
84+ id : mode
85+ env :
86+ IS_DEPENDABOT : ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
87+ IS_FORK : ${{ github.event.pull_request.head.repo.full_name != github.repository }}
88+ AUTHOR_ASSOC : ${{ github.event.pull_request.author_association }}
89+ # Empty for fork PRs (secrets withheld) and until the secret is added.
90+ SOCKET_API_TOKEN : ${{ secrets.SOCKET_API_TOKEN }}
91+ run : |
92+ mode=firewall-free
93+ # Enterprise only for a trusted SocketDev member (OWNER/MEMBER) or
94+ # repo collaborator on an in-repo PR, and only when the token is
95+ # actually present. Anything else falls back to the free edition.
96+ if [ "$IS_DEPENDABOT" != "true" ] \
97+ && [ "$IS_FORK" != "true" ] \
98+ && [ -n "$SOCKET_API_TOKEN" ] \
99+ && printf '%s' "$AUTHOR_ASSOC" | grep -qE '^(OWNER|MEMBER|COLLABORATOR)$'; then
100+ mode=firewall-enterprise
101+ fi
102+
103+ echo "sfw_mode=$mode" >> "$GITHUB_OUTPUT"
104+ {
105+ echo "## Socket Firewall mode: \`$mode\`"
106+ echo "- author_association: \`$AUTHOR_ASSOC\`"
107+ echo "- dependabot: \`$IS_DEPENDABOT\` | fork: \`$IS_FORK\`"
108+ } >> "$GITHUB_STEP_SUMMARY"
109+
74110 - name : Summarize review expectations
75111 env :
76112 PR_URL : ${{ github.event.pull_request.html_url }}
77113 run : |
78114 {
79- echo "## Dependabot Review Checklist"
115+ echo "## Dependency Review Checklist"
80116 echo "- PR: $PR_URL"
81117 echo "- Confirm upstream release notes before merge"
82- echo "- Do not treat a Dependabot PR as trusted solely because of the actor"
118+ echo "- Do not treat a dependency PR as trusted solely because of the actor"
83119 echo "- This workflow runs in pull_request context only; no publish secrets are exposed"
84120 } >> "$GITHUB_STEP_SUMMARY"
85121
97133 - uses : ./.github/actions/setup-sfw
98134 with :
99135 uv : " true"
136+ mode : ${{ needs.inspect.outputs.sfw_mode }}
137+ socket-token : ${{ secrets.SOCKET_API_TOKEN }}
100138
101139 - name : Sync project through Socket Firewall
102140 # `sfw uv sync` is the intended way to route uv through Socket Firewall
@@ -105,9 +143,19 @@ jobs:
105143 # re-resolving, so the firewall inspects precisely what would install.
106144 # Note: uv's sfw integration is quieter than npm/pip -- it does not
107145 # print the "N packages fetched" footer, but interception is active.
146+ #
147+ # Use the runner's setup-python interpreter and forbid managed-Python
148+ # downloads. The firewall is here to vet PyPI installs, not the
149+ # interpreter/toolchain download path.
150+ env :
151+ UV_PYTHON : " 3.12"
152+ UV_PYTHON_DOWNLOADS : never
108153 run : sfw uv sync --locked --extra test --extra dev
109154
110155 - name : Import smoke test
156+ env :
157+ UV_PYTHON : " 3.12"
158+ UV_PYTHON_DOWNLOADS : never
111159 run : |
112160 uv run python -c "
113161 from socketsecurity.socketcli import cli, build_socket_sdk
@@ -134,6 +182,8 @@ jobs:
134182 - uses : ./.github/actions/setup-sfw
135183 with :
136184 node : " true"
185+ mode : ${{ needs.inspect.outputs.sfw_mode }}
186+ socket-token : ${{ secrets.SOCKET_API_TOKEN }}
137187
138188 - name : Install fixture through Socket Firewall
139189 working-directory : tests/e2e/fixtures/simple-npm
@@ -153,6 +203,8 @@ jobs:
153203 - uses : ./.github/actions/setup-sfw
154204 with :
155205 python : " true"
206+ mode : ${{ needs.inspect.outputs.sfw_mode }}
207+ socket-token : ${{ secrets.SOCKET_API_TOKEN }}
156208
157209 - name : Install fixture through Socket Firewall
158210 working-directory : tests/e2e/fixtures/simple-pypi
@@ -186,6 +238,6 @@ jobs:
186238 run : |
187239 {
188240 echo "## Sensitive File Notice"
189- echo "This Dependabot PR changes workflow or dependabot config files."
241+ echo "This PR changes workflow, composite-action, or dependabot config files."
190242 echo "Require explicit human review before merge."
191243 } >> "$GITHUB_STEP_SUMMARY"
0 commit comments