Skip to content

Commit bca454d

Browse files
leliaclaude
andcommitted
Extend dependency review to maintainers (free + enterprise SFW)
Broaden dependabot-review into dependency-review so the Socket Firewall guardrail covers maintainer PRs too, not just Dependabot: - inspect now runs on every PR and computes the SFW edition per-PR: enterprise for a trusted SocketDev member (author_association OWNER/ MEMBER/COLLABORATOR) on an in-repo (non-fork) PR when SOCKET_API_TOKEN is present; free (anonymous) for Dependabot, forks, external contributors, or when the token is absent. - The mode degrades to free whenever the token is missing, so this is safe to ship before the secret exists and auto-upgrades to enterprise once SOCKET_API_TOKEN is added (repo or org level). The SDK has no Socket token today (cf. socket-python-cli's SOCKET_CLI_API_TOKEN). - setup-sfw composite action gains `mode` + `socket-token` inputs, forwarded to socketdev/action (same action, firewall-free vs firewall-enterprise). - Rename workflow dependabot-review.yml -> dependency-review.yml to match the broadened scope (not a required status check). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 69524b9 commit bca454d

2 files changed

Lines changed: 65 additions & 18 deletions

File tree

.github/actions/setup-sfw/action.yml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
name: "Set up Socket Firewall (free)"
1+
name: "Set up Socket Firewall"
22
description: >-
3-
Set up the requested language toolchain and install Socket Firewall (free
4-
edition) so subsequent steps can run package-manager commands wrapped with
5-
`sfw`. Free/anonymous mode -- no API token, safe on untrusted/Dependabot PRs.
3+
Set up the requested Python/uv toolchain and install Socket Firewall so
4+
subsequent steps can run package-manager commands wrapped with `sfw`.
5+
Defaults to free/anonymous mode (no API token -- safe on untrusted /
6+
Dependabot / fork PRs). Pass mode: firewall-enterprise + socket-token for
7+
full org-policy enforcement on trusted maintainer PRs.
68
79
inputs:
810
python:
@@ -11,6 +13,12 @@ inputs:
1113
uv:
1214
description: "Install uv (implies Python)"
1315
default: "false"
16+
mode:
17+
description: "socketdev/action mode: firewall-free or firewall-enterprise"
18+
default: "firewall-free"
19+
socket-token:
20+
description: "Socket API token (only used/required for firewall-enterprise)"
21+
default: ""
1422

1523
runs:
1624
using: "composite"
@@ -21,9 +29,11 @@ runs:
2129
python-version: "3.12"
2230

2331
# Official Socket setup action. Wires up sfw routing correctly.
32+
# socket-token is ignored in firewall-free mode and empty when absent.
2433
- uses: socketdev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2
2534
with:
26-
mode: firewall-free
35+
mode: ${{ inputs.mode }}
36+
socket-token: ${{ inputs.socket-token }}
2737

2838
- if: ${{ inputs.uv == 'true' }}
2939
name: Install uv
Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
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. Inspects the changed files, then runs a Socket Firewall
5+
# (sfw) install smoke job for Python dependency changes, picking the firewall
6+
# edition per-PR:
47
#
5-
# Runs only on PRs opened by dependabot[bot]. Inspects which files
6-
# changed, then conditionally runs a Socket Firewall (sfw) install smoke
7-
# job for the Python dependency set. Because sfw uses the free, anonymous
8-
# Socket public-data path it needs NO API key, so we can run it from the
9-
# unprivileged `pull_request` context without pull_request_target or any
10-
# of its security tradeoffs.
8+
# - Trusted SocketDev members on an in-repo (non-fork) PR, when the
9+
# SOCKET_API_TOKEN secret is present -> Socket Firewall ENTERPRISE
10+
# (authenticated, full org-policy enforcement).
11+
# - Everything else -- Dependabot, forks, external contributors, or a
12+
# missing token -> Socket Firewall FREE (anonymous, no API token), which
13+
# is safe in the unprivileged `pull_request` context.
14+
#
15+
# The mode is computed in `inspect` and degrades to free whenever the token is
16+
# absent (e.g. before it has been added to the repo/org, or on fork PRs where
17+
# GitHub withholds secrets), so this workflow is safe to ship as-is and starts
18+
# using the enterprise edition automatically once the secret exists.
1119
#
1220
# Pattern adapted from SocketDev/socket-python-cli.
1321

@@ -19,17 +27,17 @@ permissions:
1927
contents: read
2028

2129
concurrency:
22-
group: dependabot-review-${{ github.event.pull_request.number }}
30+
group: dependency-review-${{ github.event.pull_request.number }}
2331
cancel-in-progress: true
2432

2533
jobs:
2634
inspect:
27-
if: github.event.pull_request.user.login == 'dependabot[bot]'
2835
runs-on: ubuntu-latest
2936
timeout-minutes: 5
3037
outputs:
3138
python_deps_changed: ${{ steps.diff.outputs.python_deps_changed }}
3239
workflow_or_action_changed: ${{ steps.diff.outputs.workflow_or_action_changed }}
40+
sfw_mode: ${{ steps.mode.outputs.sfw_mode }}
3341
steps:
3442
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3543
with:
@@ -65,15 +73,42 @@ jobs:
6573
echo "workflow_or_action_changed=$(has_file '^\.github/workflows/|^\.github/actions/|^\.github/dependabot\.yml$')"
6674
} >> "$GITHUB_OUTPUT"
6775
76+
- name: Determine Socket Firewall mode
77+
id: mode
78+
env:
79+
IS_DEPENDABOT: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
80+
IS_FORK: ${{ github.event.pull_request.head.repo.full_name != github.repository }}
81+
AUTHOR_ASSOC: ${{ github.event.pull_request.author_association }}
82+
# Empty for fork PRs (secrets withheld) and until the secret is added.
83+
SOCKET_API_TOKEN: ${{ secrets.SOCKET_API_TOKEN }}
84+
run: |
85+
mode=firewall-free
86+
# Enterprise only for a trusted SocketDev member (OWNER/MEMBER) or
87+
# repo collaborator on an in-repo PR, and only when the token is
88+
# actually present. Anything else falls back to the free edition.
89+
if [ "$IS_DEPENDABOT" != "true" ] \
90+
&& [ "$IS_FORK" != "true" ] \
91+
&& [ -n "$SOCKET_API_TOKEN" ] \
92+
&& printf '%s' "$AUTHOR_ASSOC" | grep -qE '^(OWNER|MEMBER|COLLABORATOR)$'; then
93+
mode=firewall-enterprise
94+
fi
95+
96+
echo "sfw_mode=$mode" >> "$GITHUB_OUTPUT"
97+
{
98+
echo "## Socket Firewall mode: \`$mode\`"
99+
echo "- author_association: \`$AUTHOR_ASSOC\`"
100+
echo "- dependabot: \`$IS_DEPENDABOT\` | fork: \`$IS_FORK\`"
101+
} >> "$GITHUB_STEP_SUMMARY"
102+
68103
- name: Summarize review expectations
69104
env:
70105
PR_URL: ${{ github.event.pull_request.html_url }}
71106
run: |
72107
{
73-
echo "## Dependabot Review Checklist"
108+
echo "## Dependency Review Checklist"
74109
echo "- PR: $PR_URL"
75110
echo "- Confirm upstream release notes before merge"
76-
echo "- Do not treat a Dependabot PR as trusted solely because of the actor"
111+
echo "- Do not treat a dependency PR as trusted solely because of the actor"
77112
echo "- This workflow runs in pull_request context only; no publish secrets are exposed"
78113
} >> "$GITHUB_STEP_SUMMARY"
79114
@@ -91,6 +126,8 @@ jobs:
91126
- uses: ./.github/actions/setup-sfw
92127
with:
93128
uv: "true"
129+
mode: ${{ needs.inspect.outputs.sfw_mode }}
130+
socket-token: ${{ secrets.SOCKET_API_TOKEN }}
94131

95132
- name: Sync project through Socket Firewall
96133
# `sfw uv sync` is the intended way to route uv through Socket Firewall
@@ -121,6 +158,6 @@ jobs:
121158
run: |
122159
{
123160
echo "## Sensitive File Notice"
124-
echo "This Dependabot PR changes workflow or dependabot config files."
161+
echo "This PR changes workflow, composite-action, or dependabot config files."
125162
echo "Require explicit human review before merge."
126163
} >> "$GITHUB_STEP_SUMMARY"

0 commit comments

Comments
 (0)