Skip to content

fix(release): develop to main - #659

Merged
bedatty merged 53 commits into
mainfrom
develop
Aug 7, 2026
Merged

fix(release): develop to main#659
bedatty merged 53 commits into
mainfrom
develop

Conversation

@bedatty

@bedatty bedatty commented Aug 7, 2026

Copy link
Copy Markdown
Contributor
Lerian

GitHub Actions Shared Workflows


Description

Type of Change

  • feat: New workflow or new input/output/step in an existing workflow
  • fix: Bug fix in a workflow (incorrect behavior, broken step, wrong condition)
  • perf: Performance improvement (e.g. caching, parallelism, reduced steps)
  • refactor: Internal restructuring with no behavior change
  • docs: Documentation only (README, docs/, inline comments)
  • ci: Changes to self-CI (workflows under .github/workflows/ that run on this repo)
  • chore: Dependency bumps, config updates, maintenance
  • test: Adding or updating tests
  • BREAKING CHANGE: Callers must update their configuration after this PR

Breaking Changes

None.

Testing

  • YAML syntax validated locally
  • Triggered a real workflow run on a caller repository using @this-branch or the beta tag
  • Verified all existing inputs still work with default values
  • Confirmed no secrets or tokens are printed in logs
  • Checked that unrelated workflows are not affected

Caller repo / workflow run:

Related Issues

Closes #

dependabot Bot and others added 30 commits August 3, 2026 11:06
Bumps the go-tooling group with 1 update in the / directory: [fgrosse/go-coverage-report](https://github.com/fgrosse/go-coverage-report).


Updates `fgrosse/go-coverage-report` from 1.3.0 to 1.3.1
- [Release notes](https://github.com/fgrosse/go-coverage-report/releases)
- [Changelog](https://github.com/fgrosse/go-coverage-report/blob/main/CHANGELOG.md)
- [Commits](fgrosse/go-coverage-report@v1.3.0...v1.3.1)

---
updated-dependencies:
- dependency-name: fgrosse/go-coverage-report
  dependency-version: 1.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-tooling
...

Signed-off-by: dependabot[bot] <support@github.com>
Add a Socket supply-chain layer to the JS/TS PR umbrella, covering the
gap npm audit, Trivy and CodeQL leave open: malicious install scripts,
typosquats and hijacked patch releases.

Two independent composites, toggled from the workflow:

- src/security/socket-firewall — free tier, no token. Installs Socket
  Firewall, shims the package manager and runs the dependency install
  through it. Enabled by default and blocking, since a blocked package
  is malware, not a finding to triage. Skips with a warning when no
  lockfile is found in working-dir so monorepos do not go red on a
  configuration gap.
- src/security/socket-scan — paid tier, socketcli. Posts the alert
  report on the PR and enforces the org policy. Disabled by default and
  advisory when enabled; skips with a notice when SOCKET_SECURITY_API_KEY
  is absent, so enabling it early breaks nothing.

The socket job sits behind the existing change gate and exposes a stable
Socket status check via result-gate, matching Frontend Analysis and
Security. All inputs are additive with defaults and the new secret is
optional — no caller migration needed.
Address the CodeRabbit review. Two of the findings were real bypasses that
made the free tier a no-op reporting success:

- The pinned SocketDev/action v1.3.2 exposes no `shims` input — verified
  against action.yml at ba6de6cc, where the input is absent and dist/main.js
  contains no shim logic; the README at that SHA documents `sfw npm install`.
  `shims: 'true'` was therefore silently ignored and bare `npm ci` installed
  completely uninspected. Every command is now prefixed with `sfw`.
- actions/setup-node restored the package-manager cache, and Socket Firewall
  free can only inspect what crosses the network — per its docs, "if there
  are no network requests, as is the case when artifacts are cached locally,
  there is nothing for sfw to block". Dropped `cache:` and purge the cache
  before the guarded install. Dropping `cache:` also stops this job from
  writing a post-run cache entry other jobs would restore.

Also from the review:

- socketcli has no native --dry-run: any invocation authenticates, creates a
  real scan and comments on the PR. dry-run now skips the CLI entirely.
- Stopped passing --disable-blocking in advisory mode. It forces exit 0 over
  everything, including API failures that surface as exit 3, so advisory mode
  was indistinguishable from a clean scan. The native exit code now reaches
  the evaluate step, which was already the only gate.
- sarif-file is exported only once the report exists on disk.
- Added socket_use_cache so the composite's use-cache is reachable, per the
  repo guideline that every optional composite feature gets a workflow input.
- Documented the rationale for each third-party action in both composite
  READMEs, and corrected the docs wording that called a default-true
  run_socket "opt-in".
`pip install socketsecurity --upgrade` resolved whatever PyPI had published
most recently and the next step ran it with SOCKET_SECURITY_API_KEY and a
GitHub token in its environment — an unreviewed package executing with
credentials, which is the exact risk class this composite exists to catch.

Pin via a new cli-version input (default 2.5.8, the current release). PyPI
forbids re-uploading an existing version, so an exact pin already resolves to
a fixed artifact; --require-hashes is not used because it would also demand
hashes for every transitive dependency, which is unmaintainable in a shared
composite. `cli-version: latest` restores the old behavior and warns.

Exposed as socket_cli_version on the umbrella and documented in both places.
Bumping is manual, like the action SHAs — Dependabot does not scan src/**.
TEMPORARY, revert before merge. The socket-firewall and socket-scan composites
do not exist at the v1 tag yet, so the socket job cannot resolve them and the
end-to-end validation on a real caller is impossible without this.

src/lint/pinned-actions reports internal refs outside @vN/@develop/@main as a
warning, not an error, so the repo's own CI stays green.
Reshape the Socket layer around what the organization already runs. The
socket-security GitHub App is installed and posts Socket Security: Project
Report and Pull Request Alerts, both observed passing on product-console#682.

Remove socket-scan. Running socketcli would re-scan the same dependency graph
the App already analyses, post a second competing PR report and consume quota,
for no added coverage. Drops the SOCKET_SECURITY_API_KEY secret and its inputs.

Add src/setup/setup-node-guarded and use it for all twelve install jobs in
frontend-pr-analysis.yml. This closes the real gap: the firewall shim only
protects installs in its own job, so guarding one job left eleven running bare
npm ci, where a malicious postinstall executes with the runner's tokens. The
guarded path drops the package-manager cache by necessity — sfw only inspects
what crosses the network — at a measured cost of ~20s per cold install.

Add src/security/socket-app-gate. The App analyses but does not enforce: its
checks land as success, neutral or skipped, and neither neutral nor skipped
blocks a merge. The gate waits for those checks on the PR head SHA and converts
them into a verdict we own, with no token and no duplicate scan. inconclusive
(neutral/skipped/timeout) blocks by default, because the un-mergeable-PR skip
means no diff was analysed at all and must not read as clean; missing (no App
installed) only warns, so those repositories stay green on layer 1 alone.

Add src/security/socket-reporter, posting one upserted PR comment in the same
Stage/Status/Blocking layout as the security scan comment, under its own marker.
A separate comment is forced by topology: pr-security-reporter runs inside the
security_scan job of pr-security-scan.yml and step outputs do not cross jobs.
Without result-encoding: string, actions/github-script JSON-encodes the
returned string, so the step output arrived as "{\"has_findings\":false}" — a
quoted string — and the jq validation rejected it as missing has_findings.
pr-security-reporter already sets it; the new reporter did not.

Caught by the end-to-end run on product-console#682, where Socket Firewall and
the App gate both passed and only the report step failed.
Two defects found while auditing what tokens the Socket layer actually needs.

The workflow-level permissions block omitted checks: read, which socket-app-gate
needs to read the App's check runs. A reusable workflow's permissions are
intersected with the caller's, never expanded, so any caller pinning its own
permissions block would starve the gate. Added at workflow level and to the
docs usage example, which every consuming repo copies verbatim.

That failure was also silent: gh errors were folded into an empty result via
`|| echo '[]'`, and no checks is classified as `missing`, which only warns. A
missing scope therefore looked like "App not installed" and passed. A non-zero
gh exit is now a hard error naming the likely cause.

The run on product-console#682 passed only because that caller declares no
permissions block and inherits the repository default.
No job consumes it: the firewall inspects traffic locally and the App gate reads
the GitHub checks API, both token-free. It is declared because a reusable
workflow cannot receive a secret it does not declare — not even via
`secrets: inherit` — so declaring it now lets an organization secret become
usable without cutting a release.

Marked in-line and in the docs as intentionally unconsumed, with Socket Firewall
enterprise named as the intended consumer, so it is not later removed as dead.
Documented the least-privilege scope guidance alongside it.
TEMPORARY, remove before merge. Confirms an organization secret actually reaches
this reusable workflow via secrets: inherit — the sole reason
SOCKET_SECURITY_API_KEY is declared, since no job consumes it yet.

Reports length and a 4-char prefix only, never the value.
It answered its question on product-console#682: the secret arrives (55 chars,
skts prefix), so org secret -> selected repository -> secrets: inherit ->
reusable workflow works end to end. Removed rather than left to ship.
Replace log grepping with the Socket Firewall JSON report, whose schema was
extracted from the v1.15.0 binary — the same version CI resolves:

  { blocked: [{name, namespace, version, purlString, registryFqdn,
               alerts:[{alert, action, actionSource, inputPurl}]}] | null,
    parseFail: [{registryFqdn, urlPath}] | null }

Detection was matching prose in the install output, written without ever having
seen a real block. Reading blocked[] is deterministic and removes the failure
mode where a genuine block was reported as blocked=false.

The report now renders a per-package table — package, version, registry and each
alert type — plus the policy source, and surfaces parseFail entries, which are a
coverage gap the previous version discarded silently: an unparsed request means
that package was never inspected.

socket-app-gate now captures each check's output.summary, so the comment shows
what the App actually said ("no net changes to dependencies" vs "Skipped
un-mergeable pull request") rather than a bare conclusion that hides which.

The five branches of the evaluate logic were exercised locally against synthetic
reports in the real schema — blocked/blocking, blocked/advisory, clean, failed
without a block, and report missing — since no safe canary package exists to
trigger a live block. safe-chain-test does not work: npm replaced it with a
benign security holding package and sfw installs it without complaint.
…cket API

Neither existing layer can say which package has which finding. Socket Firewall
free reports only what it refused — its JSON is {blocked, parseFail}, silent on
everything that passed. The App's checks carry a status and a link; Project
Report's output.text is null and the detail lives on the dashboard.

Add src/security/socket-api-report. It parses the org slug and full-scan id from
the dashboard URL the App publishes, then reads that scan back through
GET /v0/orgs/{org}/full-scans/{id} (NDJSON). Nothing is re-analysed and no scan
is created — one quota unit. Creating a scan with socketcli would have duplicated
work the App had already done and produced a competing report.

The comment gains scan scores, an alerts-by-type breakdown, and a per-package
table with severity, alert type, and whether the dependency is direct or
transitive, prod or dev.

Advisory by construction: every failure path exits 0, and HTTP statuses are
classified separately (401 invalid, 403 missing full-scans:list, 404 wrong scan,
429 quota) because they need different fixes. A Socket outage or an exhausted
quota must not read as a security finding — enforcement stays with the App gate
and with the firewall refusing an install.

The token goes through a curl --config file rather than argv, so it never lands
in the process table of a shared runner. Alert objects are read defensively, with
key/alert as fallbacks for type, so an upstream rename degrades to a label rather
than an empty report; debug-sample logs the real shape when adapting.

The jq extraction was validated against synthetic NDJSON in the documented shape.
The non-200 handler printed a hint derived from the status code, which is only a
guess, and discarded the response body — the one place Socket names the missing
permission. That turned scope debugging into trial and error: a 403 reported
'missing full-scans:list' even when the real cause was something else.

The body is an error document, not scan data, so printing it leaks nothing.
… denial

api.socket.dev sits behind a Cloudflare managed challenge that answers
non-browser clients with 403, an HTML interstitial and cf-mitigated: challenge.
By status code alone that is indistinguishable from a missing token scope, and
the previous message asserted the scope reading — sending a real investigation
after a token permission that was never the cause.

Reproduced from a developer machine and from the Blacksmith CI runner, with
Authorization: Bearer, HTTP Basic with the token as username, a custom
User-Agent, and the exact header shape socket-sdk-python sends, against both
/v0/quota and the full-scan endpoint. Three spaced retries, same result — not
transient.

Now classified on evidence: the cf-mitigated header and the interstitial are
checked before the status code, and the message states that the request never
reached Socket, so no scope audit is triggered. Also sends Accept and a
User-Agent, which is correct practice even though neither lifts the challenge.

Layer 3 stays wired: it exits 0 on every failure path, so the job stays green
and the comment still renders, as observed on product-console#682.
Cloudflare fingerprints the HTTP client in front of api.socket.dev. curl is
answered with a managed challenge — 403, an HTML interstitial, cf-mitigated —
regardless of credentials, headers, auth form, endpoint or egress: reproduced
with Bearer, with Basic, with a custom User-Agent, with the exact header shape
socket-sdk-python sends, on /v0/quota and on the full-scan endpoint, from a
developer machine and from a Blacksmith runner, three spaced retries each.

Python's stdlib client is not challenged and returns real JSON from the API. It
is the same stack the official SDK uses, and it explains why sfw reaches Socket
from the very runner where curl is blocked — sfw is not curl.

So this was never a Socket support matter, and never a token scope matter. The
earlier diagnosis pointed at both and was wrong on both counts.

The cf-mitigated check is kept as a regression guard should the fingerprint
policy widen. The token is read from the environment inside the Python process
rather than passed as an argument, so it stays out of the process table.

Validated locally end to end: an invalid token now yields a clean HTTP 401 with
Socket's own JSON error body, no challenge, step exit 0.
The first rendering was unusable: 4636 raw alerts, the same envVars repeated
hundreds of times per package, ranked by raw count so the noisiest package led.
The dashboard's 36 comes from filtering on alert action — a field this code has
never inspected.

TEMPORARY. Dumps the alert object keys and the distinct action/severity/category
values so the filtering is built against the real shape rather than guessed.
Placed in the composite rather than behind the workflow-level debug input,
because gh run rerun reloads composites from the branch but replays the original
reusable-workflow graph — so a workflow input change needs a fresh push while a
composite change does not.

The action axis is what the Socket dashboard filters on, and the difference
between 36 actionable alerts and 4636 raw ones.
…decision

The first real rendering was unusable: 4636 alerts, the same envVars repeated
hundreds of times per package, ranked by raw count so the noisiest package led.
The dashboard's much smaller number comes from filtering on alert action — a
field the extraction had never inspected.

Measured on a 1897-artifact scan: action is "ignore" for 4594 of 4636 alerts,
"monitor" for 24 and "warn" for 18. So 42 alerts carry a policy decision and the
rest are capability observations. Severity alone is not a usable filter — 118
alerts are "high" yet still ignored by policy.

The extraction now keeps only alerts whose action is in include-actions
(error,warn,monitor by default), collapses repeats per package+type into a count
with the first file, and ranks by action then severity rather than volume. Alert
objects also carry file, start, end and fix, so the comment can point at the
location and surface remediation.

Adds fail-on-actions, wired to the job gate: findings can now block the pull
request under a policy defined here rather than deferring to the App's verdict.
Default empty preserves report-only. The API-failure paths report zero blocking
findings by construction, so an unreachable Socket still cannot fail a PR.

Also stops the extraction from failing silently: a jq error previously produced
{} and a comment that read as a clean scan.
…ella

Wires include-actions and fail-on-actions through as socket_api_include_actions
and socket_api_fail_on_actions, and makes the job gate honour the blocking count.

Default fail-on-actions is empty, so behaviour is report-only until a repository
opts in. The API-failure paths report zero blocking findings by construction, so
an unreachable Socket still cannot fail a pull request — only real findings can.

Also drops the temporary debug-sample hardcode; the action distribution it was
added to discover is now logged compactly by the composite on every run.
…t Object]

The alert fix field is an object, not a string, so the suggested-fixes list
printed [object Object] for every entry — the most actionable field Socket
returns, lost in the render.

Its shape is not documented, so the reporter prefers the human-readable fields
and falls back to compact JSON rather than dropping the content, and the
composite now logs the first non-null fix so the preference list can be
narrowed against the real shape.
…g debt

The findings reported so far were the whole dependency tree, not the pull
request. On product-console that is 42 actioned findings on packages like
react-color and brace-expansion, none of which any given PR touches — they would
appear on every pull request forever. Worse, fail-on-actions applied to them:
setting it to "warn" would have blocked every PR in the repository for 18
pre-existing obfuscatedFile alerts nobody introduced, which is how a gate gets
switched off in its first week.

socket-api-report now reads the most recent full scan of the target branch as a
baseline and classifies each finding. A finding is introduced when this
package@version did not already carry that alert type on the base — so a version
bump counts as new, the conservative reading. The baseline is resolved through
full-scans?branch=, which needs only the full-scans:list scope already granted;
the diff-scans API would have required two more.

Only introduced findings can block. Pre-existing ones are collapsed into a
<details> and never gate.

The extraction moved from jq to python: a two-scan diff in jq would have been
unreadable, and python was already required for the HTTP call.

The comment now carries findings only. Whether the scan ran, which App checks
passed and how many alerts were filtered out are operational facts that belong
in the job log and the Socket status check — not in a comment people are asked to
read. With comment-when: findings (the default) nothing is posted when there is
nothing to act on, and an existing comment collapses to a resolved note so a
stale one never reads as current.
The split reported 38 findings as introduced by a pull request that changed only
@types/lodash, which cannot be right. The baseline is whatever full scan of the
target branch is most recent, and nothing so far reveals which scan that is or
how complete it looks.

Logs the baseline scan id, timestamp, commit, state and artifact count, and warns
when the baseline is less than half the size of the head scan — an unrelated or
incomplete baseline makes everything look introduced.
The first attribution was wrong: 38 findings reported as introduced by a pull
request that changed only @types/lodash. The baseline was the most recent scan of
the target branch regardless of state, and that scan was in state "resolve" —
still resolving dependencies. It carried 1556 artifacts and 1412 alert keys
against 1897 and 4636 in the head scan, so everything absent from it looked new.

Two defences now, because a wrong attribution is worse than none:

  1. Candidates in pending/precrawl/resolve are skipped.
  2. The candidate must be at least 80% the size of the head scan, which tests
     what actually matters instead of trusting a state label.

Up to ten candidates are considered, newest first. If none qualify, everything is
reported as pre-existing and the comment says no baseline was available — no
attribution is honest, a confident wrong one is not.

Verified against a stub serving a resolve-state candidate, an 8%-size candidate
and a 92% one: the first two are rejected with the reason logged and the third is
used, splitting a genuinely new package from inherited debt.
All ten baseline candidates on develop were rejected as pending/resolve, so no
baseline was available and everything fell back to pre-existing. Ten out of ten
in an in-progress state is suspicious: the assumption that pending/precrawl/
resolve mean incomplete is an inference from the documented enum, not something
the docs state.

Logs the state reported for the head commit's own scan. That scan carries 1897
artifacts and 4636 alerts, so its data is demonstrably complete — if it also
reports 'resolve', the state filter is wrong and the size check is the only
trustworthy signal.
scan_state is not a completion signal. Every scan in this organization persists
as 'pending' or 'resolve' — including the head scan itself, which carries 1897
artifacts and 4636 alerts and is demonstrably complete. Filtering on it rejected
all ten candidates, so no baseline was ever found and every finding fell back to
pre-existing.

Replaced with the measurement that matters: how much of this tree the candidate
actually shares. A candidate is accepted when at least 90% of the head scan's
package@version set is present in it. That tests comparability directly, where the
previous artifact-count ratio only approximated it and would have accepted the
1556-artifact scan that caused the 38 false attributions.

scan_state is still logged, since it is useful context even though it cannot be
trusted as a gate.
Two home-grown baselines failed, and the second failure explained the first.
Comparing against the newest scan of the target branch produced 38 false
attributions on a change to a single types package. Filtering candidates by
scan_state then rejected all ten, because every scan in this organization
persists as 'pending' or 'resolve' — the head scan included, whose data is
demonstrably complete, so scan_state carries no completion meaning here.

Measuring package overlap showed why no baseline was usable at all: the newest
target-branch scan shared only 31.8% of this tree's package@version set despite
holding 82% as many artifacts. An artifact-count threshold would have accepted it,
which is precisely how the 38 false attributions happened.

The Socket App already computes the correct diff per pull request, so it is read
rather than approximated. The diff scan is looked up by after_full_scan_id, which
makes it exact rather than heuristic, and its added/updated/replaced buckets
define what this pull request is responsible for. Needs diff-scans:list.

Without a diff scan nothing is attributed and everything is reported as
pre-existing, so a lookup failure cannot manufacture findings.
…ard links

The header stated ⚠️ whenever any finding existed, including a pull request that
introduced none and only inherited tree debt. That is a pass, and marking it as a
warning trains people to ignore the warning that matters. Now: ❌ for blocking
introduced findings, ⚠️ for introduced but non-blocking, ✅ for none introduced.

Adds the dashboard links the App's comment has and ours lacked. Package rows
deep-link into the scan when Socket gave the artifact an id, and a footer links
the diff, the full project report and the run logs. Only URL shapes observed
coming from the App itself are used — socket.dev answers curl with a Cloudflare
challenge, so these cannot be verified from CI and a guessed shape would be a
dead link.

Resolves the diff scan id from the App's own comment. Looking it up by
after_full_scan_id returned nothing: the App diffs against a different full scan
than the one its Project Report check links to. The comment only carries an id
when dependencies actually changed, which is also exactly when attribution is
possible — with no id nothing is attributed and everything reads as pre-existing.
The previous form collapsed into a single 253-character line, the only long-line
warning this branch adds over the baseline.
Collapsed behind a bare summary line, the pre-existing findings read as an
unexplained ▶ with no sense of scale — a reader cannot tell whether expanding it
shows two rows or two hundred.

Now it gets a heading, a sentence stating what it is and that this change did not
touch it, and an action breakdown (🟠 18 warn · 🟡 24 monitor) before the
collapsed table. The same breakdown precedes the introduced section, and
horizontal rules separate the verdict, the debt and the links.
@bedatty
bedatty requested a review from a team as a code owner August 7, 2026 19:09
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

Summary by CodeRabbit

  • New Features

    • Added configurable dependency protection for frontend analysis and JavaScript pull-request validation.
    • Added supply-chain checks for blocked packages, security findings, application verdicts, and status gates.
    • Added workflow summaries, pull-request comments, API reports, and configurable failure handling.
    • Added reusable security actions supporting npm, Yarn, and pnpm, with caching and opt-out controls.
  • Documentation

    • Added setup guidance, configuration options, outputs, permissions, and usage examples.
  • Chores

    • Pinned workflow actions to immutable versions.
    • Added grouped Dependabot coverage for security-scanning updates.
    • Added linter files to ignored project artifacts.

Walkthrough

Adds Socket guarded dependency installation, App checks, API findings reports, pull-request comments, and aggregate status handling to reusable JavaScript validation workflows. It also updates frontend integration, documentation, Dependabot grouping, local ignore rules, and GitHub Action pinning.

Changes

Socket supply-chain security

Layer / File(s) Summary
Guarded dependency installation
src/setup/setup-node-guarded/*, src/security/socket-firewall/*
Adds guarded npm, Yarn, and pnpm installation through Socket Firewall. It handles lockfiles, cache purging, reports, blocked packages, dry runs, failure policies, and documentation.
Frontend workflow integration
.github/workflows/frontend-pr-analysis.yml, docs/frontend-pr-analysis-workflow.md
Replaces manual dependency setup across analysis jobs with setup-node-guarded and adds Socket Firewall inputs and documentation.
Socket checks and findings reports
src/security/socket-app-gate/*, src/security/socket-api-report/*
Adds App check polling and API scan processing with diff attribution, alert filtering, dependency ancestry, deduplication, and structured outputs.
Findings comment publication
src/security/socket-reporter/*
Adds sanitized pull-request comment creation and updates for introduced findings, pre-existing debt, blocked packages, remediation, and report links.
Reusable validation orchestration
.github/workflows/js-pr-validation.yml, docs/js-pr-validation.md, .github/dependabot.yml, .gitignore, .github/workflows/go-ci.yml
Adds Socket inputs, secret and permission wiring, the Socket job, aggregate gating, documentation, Dependabot grouping, the /typos ignore rule, action pinning, and shell quoting updates.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested reviewers: guimoreirar

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description copies the template but omits the change summary, change type, testing results, workflow run link, and related issue details. Describe the affected workflows and behavior changes, select the change type, record completed testing, add the caller workflow run link, and provide issue details.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title identifies the branch merge but does not describe the primary Socket security and workflow changes in the pull request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Comment @coderabbitai help to get the list of available commands.

@lerian-studio lerian-studio added size/XL PR changes ≥ 1000 lines — consider splitting documentation Improvements or additions to documentation workflow Changes to one or more reusable workflow files dependencies Dependency updates (usually opened by Dependabot) typescript Changes to TypeScript or Frontend workflows security Changes to security workflows or vulnerability reporting policy github-config Changes to repository configuration (templates, CODEOWNERS, labeler, etc.) composite Changes to any composite action manifest (src/**/*.yml) labels Aug 7, 2026
@lerian-studio

lerian-studio commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🔍 PR Validation Summary

✅ PR Mergeable — no blocking failures

Check Status Blocking
Source Branch ✅ success yes
PR Title ✅ success yes
PR Description ✅ success yes
Breaking Change Guard ✅ success yes
PR Size ✅ success no
Auto Labels ✅ success no
PR Metadata ✅ success no

🔍 View workflow run

@lerian-studio

lerian-studio commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🔍 Lint Analysis

Check Files Scanned Status
YAML Lint 9 file(s) ✅ success
Action Lint 3 file(s) ✅ success
Pinned Actions 8 file(s) ✅ success
Markdown Link Check 7 file(s) ✅ success
Spelling Check 17 file(s) ✅ success
Shell Check 8 file(s) ✅ success
README Check 8 file(s) ✅ success
Composite Schema 5 file(s) ✅ success
Deployment Matrix no changes ⏭️ skipped

🔍 View full scan logs

@lerian-studio

lerian-studio commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

🛡️ CodeQL Analysis Results

Languages analyzed: actions

✅ No security issues found.


🔍 View full scan logs | 🛡️ Security tab

@bedatty
bedatty temporarily deployed to create_release August 7, 2026 19:15 — with GitHub Actions Inactive
@lerian-studio lerian-studio added the golang Changes to Go-related workflows label Aug 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 20

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/frontend-pr-analysis.yml:
- Around line 55-69: Change the default for the enable_socket_firewall workflow
input from true to false so existing callers retain prior cache and registry
behavior. Keep the explicit opt-in path and related socket_firewall_version and
socket_fail_on_block inputs unchanged.

In @.github/workflows/js-pr-validation.yml:
- Around line 382-389: Update the comments at
.github/workflows/js-pr-validation.yml lines 382-389 and
docs/js-pr-validation.md line 134 to reflect that the Socket API Report step
consumes SOCKET_SECURITY_API_KEY, requiring the full-scans:list and
diff-scans:list scopes; document that the step skips with a notice when the key
is unavailable, matching the existing guidance at line 256, and remove the
outdated Socket Firewall enterprise consumer claim.

In `@src/security/socket-api-report/action.yml`:
- Around line 42-45: Remove the diagnostic probe-package input from the action
metadata and remove its associated probe block from the composite action
implementation. Verify the README inputs table exactly matches the remaining
action.yml inputs, including each name, required value, and default.
- Around line 577-583: Rename the global alert-type aggregation variable in the
block iterating over introduced and preexisting findings from by_type to
type_totals, including its initialization, updates, and sorted-values reference,
while leaving the per-package by_type aggregation unchanged.
- Around line 585-612: Update the README JSON schema/example to document the
actual keys preexistingHidden and preexistingHiddenFindings instead of
preexistingTruncated, matching the output written by the report action and
consumed by socket-reporter. Add the category field to the documented
per-finding objects, while leaving the implementation unchanged.
- Around line 414-418: Rename the parsed diff-scan creation response local in
the diff-scan creation branch from body to created, and update the subsequent
diff_scan lookup to use created. Preserve the original body binding for the
full-scan response.
- Around line 410-418: Update the condition guarding the Socket API Report
diff-scan creation flow to also require !inputs.dry_run, preventing the post
call and scan creation during dry runs while preserving the existing behavior
for normal runs.

In `@src/security/socket-api-report/README.md`:
- Around line 63-67: Update the attribution section in the README to match the
current diff resolution implemented by diff_for_head(): first use the
after_full_scan_id lookup, then use diff-scan-id only as a hint for resolving a
base and rebuilding the diff, and otherwise proceed without attribution. Remove
the outdated claim that the App comment is the sole source and that disabled
comments silently disable attribution.
- Around line 75-82: Update the “Token scopes” table in the README to include
the diff-scans:create scope required by the POST fallback in the action
configuration, and revise the “Grant nothing else” statement to reflect that the
action writes during attribution. Keep the existing read scopes and descriptions
intact.

In `@src/security/socket-app-gate/action.yml`:
- Around line 80-84: Update the jq filter in the check-runs API command to read
the app slug from the process environment via jq’s $ENV.APP_SLUG, and pass
APP_SLUG through the command environment instead of interpolating it into the jq
program. Preserve the existing filtering and output structure while removing
direct shell expansion from the filter.
- Around line 98-122: Move the DEADLINE comparison and timeout handling to the
beginning of the polling loop so it executes before the complete-but-unstable
branch and every other path. Preserve the existing timeout output, warning
message, and break behavior, while removing the now-duplicated later check.
- Around line 149-157: Update the verdict classification around TIMED_OUT,
TOTAL, BAD, and UNDECIDED so any timed-out wait is classified as inconclusive
before the TOTAL=0 missing branch, ensuring timed-out runs never pass as
missing. Preserve findings handling according to the intended priority, either
by evaluating inconclusive before findings or by preventing only the missing
branch when TIMED_OUT is true.

In `@src/security/socket-firewall/README.md`:
- Around line 53-62: Update the README documentation to match the JSON report
flow in the composite action definitions: in
src/security/socket-firewall/README.md lines 53-62, describe report-based
detection and make the zero-exit row pass only when no package is blocked; in
lines 28-35, add blocked-count and findings-file outputs and define blocked by
the report. Apply the equivalent changes in
src/setup/setup-node-guarded/README.md lines 49-58 by renaming the block-marker
column and correcting the zero-exit row, and in lines 26-33 by adding skipped,
blocked-count, and findings-file outputs and using the same blocked definition.
Also verify each inputs table exactly matches its action.yml, including names,
required values, and defaults.
- Line 66: Update the dry-run description in the README to state that dry-run is
preview-only and skips firewall setup, cache purge, installation, and
evaluation. Remove the claim that the install runs through the firewall or that
findings are reported, so the documentation matches the dry-run behavior defined
by the action.

In `@src/security/socket-reporter/action.yml`:
- Around line 99-101: Update the blockingCount calculation near hasFindings to
add blockedPkgs.length when firewall-blocked is true and the report is readable,
while retaining a count of 1 only when firewall-blocked is true but the report
file is unreadable; preserve the existing apiBlocking contribution.
- Around line 173-181: Update the JSON fallback in fixText to return the
truncated serialized object without backticks, since the result is later
processed by cell() and should not render curly quotes. Preserve the existing
string and object-field selection behavior, and let the call site handle any
code-span formatting.
- Around line 270-273: Update the preexisting-results block to pass
api.baseBranch through cell() before interpolating it into the code span,
preserving the fallback for a missing branch. Rename the inner base variable to
a distinct name so it no longer shadows the outer base declaration or creates a
temporal dead zone.

In `@src/security/socket-reporter/README.md`:
- Around line 93-119: Wrap the “As a composite step” YAML example in a complete
jobs.socket job, set runs-on to blacksmith-4vcpu-ubuntu-2404, include the
required permissions, and place the existing firewall, api-report, and Socket
findings steps under steps with consistent indentation.

In `@src/setup/setup-node-guarded/action.yml`:
- Around line 136-142: Update src/setup/setup-node-guarded/action.yml at lines
136-142 to coerce inputs.job-summary from none to errors when passing
job-summary to SocketDev/action, and add the explanatory comment used by the
sibling composite. Update the input description at lines 25-28 to document that
none is coerced to errors, keeping the advertised contract consistent with the
implementation.
- Around line 25-28: Update the job-summary input description and validation
around the job-summary handling logic to reflect the actual behavior when the
value is none: either document that none is coerced to a supported summary mode,
or remove none from the advertised supported values and reject it during
validation. Keep the description and implementation behavior consistent.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a37573ba-154a-41a4-8320-5ca9ec6774e7

📥 Commits

Reviewing files that changed from the base of the PR and between 4983e32 and 513193d.

📒 Files selected for processing (16)
  • .github/dependabot.yml
  • .github/workflows/frontend-pr-analysis.yml
  • .github/workflows/js-pr-validation.yml
  • .gitignore
  • docs/frontend-pr-analysis-workflow.md
  • docs/js-pr-validation.md
  • src/security/socket-api-report/README.md
  • src/security/socket-api-report/action.yml
  • src/security/socket-app-gate/README.md
  • src/security/socket-app-gate/action.yml
  • src/security/socket-firewall/README.md
  • src/security/socket-firewall/action.yml
  • src/security/socket-reporter/README.md
  • src/security/socket-reporter/action.yml
  • src/setup/setup-node-guarded/README.md
  • src/setup/setup-node-guarded/action.yml

Comment thread .github/workflows/frontend-pr-analysis.yml
Comment thread .github/workflows/js-pr-validation.yml Outdated
Comment thread src/security/socket-api-report/action.yml Outdated
Comment thread src/security/socket-api-report/action.yml
Comment thread src/security/socket-api-report/action.yml
Comment thread src/security/socket-reporter/action.yml
Comment thread src/security/socket-reporter/action.yml
Comment thread src/security/socket-reporter/README.md
Comment thread src/setup/setup-node-guarded/action.yml
Comment thread src/setup/setup-node-guarded/action.yml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/go-ci.yml:
- Line 129: Update the go-coverage-report action reference in the workflow to
use the immutable commit SHA e432de98ee94a276e8f666d25bfd76347665f75b, retaining
the v1.3.1 version comment for readability.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e8f62ff9-86b6-427c-a5d3-c86d8611dfc4

📥 Commits

Reviewing files that changed from the base of the PR and between 513193d and 6908449.

📒 Files selected for processing (1)
  • .github/workflows/go-ci.yml

Comment thread .github/workflows/go-ci.yml Outdated
Pin all 18 third-party action references by commit SHA with a version
comment, as required by the Pinned Actions check. Tags are mutable and
can be force-pushed upstream.

Fix the shellcheck findings in the cross-compilation loop: read -r to
stop backslash mangling of the jq output, and quote the target
expansions so an os/arch value with whitespace cannot word-split.
@bedatty
bedatty temporarily deployed to create_release August 7, 2026 19:32 — with GitHub Actions Inactive
Comment thread .github/workflows/go-ci.yml Fixed
Correctness:
- socket-app-gate: classify a timed-out wait as inconclusive before the
  zero-checks 'missing' branch. A slow App expiring the deadline with no
  checks published produced a green gate, contradicting the documented
  contract that a timeout is never success. An adverse conclusion already
  observed keeps priority and is still reported as findings.
- socket-app-gate: evaluate the deadline once per iteration so the
  complete-but-unstable path honours it. A set of checks that kept growing
  changed the signature on every poll and looped past timeout-seconds.
- socket-app-gate: read app-slug from the process environment in the jq
  program instead of interpolating it into the filter text.
- setup-node-guarded: coerce job-summary none to errors, as the sibling
  composite already did. Without it the pinned action never exports the
  report path and a genuine block is misread as an ordinary install failure.
- js-pr-validation: skip Socket API Report on a dry run. It can POST
  diff-scans/from-ids, which creates a scan on the Socket organization.
- socket-reporter: count refused packages in the blocking heading instead
  of one per block, so the number agrees with the table beneath it.
- socket-reporter: drop the backticks fixText added, which cell() replaced
  with curly quotes; pass baseBranch through cell() and stop shadowing the
  outer base holding the dashboard URL.
- go-ci: pass build_path and build_targets through env instead of
  interpolating them into the run block (CodeQL actions/code-injection).

Contract and documentation:
- socket-api-report: drop probe-package, a diagnostic input that shipped in
  the public contract undocumented.
- Document diff-scans:create, required by the diff the action rebuilds, and
  drop the claim that it only reads.
- Rewrite the attribution section as the three-step resolution the code
  performs: after_full_scan_id first, the App's id only as a hint for the
  before side, otherwise no attribution.
- Correct the emitted-shape example to preexistingHidden and
  preexistingHiddenFindings.
- Both firewall READMEs: describe report-based block detection, add the
  blocked-count, findings-file and skipped outputs, and correct the dry-run
  description, which claimed the install still ran through the firewall.
- socket-reporter README: wrap the composite example in a job with the
  required runner.
- Correct both statements that SOCKET_SECURITY_API_KEY is unconsumed.
@bedatty
bedatty temporarily deployed to create_release August 7, 2026 19:52 — with GitHub Actions Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

CodeRabbit couldn't request changes on this pull request because it doesn't have sufficient GitHub permissions.

Please grant CodeRabbit Pull requests: Read and write permission and re-run the review.

👉 Steps to fix this

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/workflows/js-pr-validation.yml (2)

601-604: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Security Misconfiguration (CWE-693)

Reachability: External · Exploitability: Moderate

Aggregate paginated comments before selecting the newest diff scan.

gh api --paginate --jq "$JQ" applies $JQ per page. head -1 can therefore select an older page-local result. That stale ID reaches socket-api-report as the baseline and can classify introduced findings as pre-existing.

Do not combine --slurp and --jq in gh api. Pipe all pages to jq -sr and flatten them before applying last.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/js-pr-validation.yml around lines 601 - 604, Update the
comment retrieval logic in the BODY/ID block to aggregate all paginated
responses before selecting the newest socket-security[bot] comment. Remove the
per-page --jq filtering, pipe gh api --paginate output to jq -sr, flatten the
page arrays, then apply the existing user filter and last selection before
extracting the diff-scan ID.

289-376: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Preserve compatibility for private registries.

socket_enable_firewall defaults to true and enables Socket Firewall for every frontend install and the dedicated Socket job. Socket Firewall Free supports public registries only, so private-registry callers can fail during dependency installation. Retain the previous default or publish an explicit breaking migration before enabling this default for external callers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/js-pr-validation.yml around lines 289 - 376, Change the
default for socket_enable_firewall back to false to preserve compatibility with
callers using private registries. Keep the existing firewall configuration and
opt-in behavior unchanged for workflows that explicitly enable it.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/js-pr-validation.yml:
- Around line 612-616: Update .github/workflows/js-pr-validation.yml lines
612-616 in the Socket API Report gating/output logic so dry-run explicitly
reports API findings as unavailable and never renders an unset blocking count as
0, while preserving resolved-input and computed-variable preview behavior.
Update docs/js-pr-validation.md line 256 to state that dry-run skips API
findings and does not compute an API blocking count.

In `@src/security/socket-app-gate/action.yml`:
- Around line 111-113: Update the signature/deadline branch in the action’s
check-set evaluation so unchanged signatures still write timed_out=false, while
a changed signature with EXPIRED=true writes timed_out=true before breaking.
Preserve BAD priority so an already observed adverse check remains
authoritative.

---

Outside diff comments:
In @.github/workflows/js-pr-validation.yml:
- Around line 601-604: Update the comment retrieval logic in the BODY/ID block
to aggregate all paginated responses before selecting the newest
socket-security[bot] comment. Remove the per-page --jq filtering, pipe gh api
--paginate output to jq -sr, flatten the page arrays, then apply the existing
user filter and last selection before extracting the diff-scan ID.
- Around line 289-376: Change the default for socket_enable_firewall back to
false to preserve compatibility with callers using private registries. Keep the
existing firewall configuration and opt-in behavior unchanged for workflows that
explicitly enable it.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2e5de80f-d63d-43ba-8828-6c065cefcbc3

📥 Commits

Reviewing files that changed from the base of the PR and between b7e5915 and c0cced3.

📒 Files selected for processing (12)
  • .github/workflows/go-ci.yml
  • .github/workflows/js-pr-validation.yml
  • docs/js-pr-validation.md
  • src/security/socket-api-report/README.md
  • src/security/socket-api-report/action.yml
  • src/security/socket-app-gate/action.yml
  • src/security/socket-firewall/README.md
  • src/security/socket-firewall/action.yml
  • src/security/socket-reporter/README.md
  • src/security/socket-reporter/action.yml
  • src/setup/setup-node-guarded/README.md
  • src/setup/setup-node-guarded/action.yml

Comment thread .github/workflows/js-pr-validation.yml
Comment thread src/security/socket-app-gate/action.yml Outdated
socket-app-gate: a deadline expiring while the check set is still unstable
now writes timed_out=true. The previous commit stopped the loop there but
recorded a decided, clean wait, so a set that never produced the second
stable snapshot evaluated to pass — reintroducing the exact race the
stability check exists to close. BAD keeps priority, so an adverse check
already observed is still findings.

js-pr-validation: the dry-run notice printed 'Blocking findings: 0' for a
layer that does not run under dry_run, rendering an unset output as a clean
result. It now states the count is not computed and why, and the workflow
doc records that this layer is not previewable.
@bedatty
bedatty temporarily deployed to create_release August 7, 2026 20:12 — with GitHub Actions Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
.github/workflows/js-pr-validation.yml (4)

673-688: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Print the resolved Socket configuration in dry-run mode.

This step prints the layer outcomes and the intentionally uncomputed API count. It does not print the resolved Socket inputs that control the preview, including run_socket, socket_enable_firewall, socket_enable_app_gate, socket_enable_api_report, and the failure policies. Map non-secret inputs through env and print them with ::notice::. Never print SOCKET_SECURITY_API_KEY.

As per path instructions, dry-run mode must print every resolved input and computed variable.

Suggested dry-run output
         env:
+          RUN_SOCKET: ${{ inputs.run_socket }}
+          SOCKET_ENABLE_FIREWALL: ${{ inputs.socket_enable_firewall }}
+          SOCKET_ENABLE_APP_GATE: ${{ inputs.socket_enable_app_gate }}
+          SOCKET_ENABLE_API_REPORT: ${{ inputs.socket_enable_api_report }}
+          SOCKET_FAIL_ON_BLOCK: ${{ inputs.socket_fail_on_block }}
+          SOCKET_API_FAIL_ON_ACTIONS: ${{ inputs.socket_api_fail_on_actions }}
           FIREWALL_OUTCOME: ${{ steps.firewall.outcome }}
           APP_GATE_OUTCOME: ${{ steps.app-gate.outcome }}
           API_BLOCKING: ${{ steps.api-report.outputs.blocking-count }}
         run: |
           echo "::notice::DRY RUN — Socket gate not enforced"
+          echo "::notice::Socket inputs: run_socket=$RUN_SOCKET firewall=$SOCKET_ENABLE_FIREWALL app_gate=$SOCKET_ENABLE_APP_GATE api_report=$SOCKET_ENABLE_API_REPORT fail_on_block=$SOCKET_FAIL_ON_BLOCK api_fail_on_actions=$SOCKET_API_FAIL_ON_ACTIONS"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/js-pr-validation.yml around lines 673 - 688, Update the
“Gate - Socket findings (dry run)” step to expose every resolved non-secret
Socket configuration input and computed variable required by the workflow,
including run_socket, socket_enable_firewall, socket_enable_app_gate,
socket_enable_api_report, and all failure policies. Map these values through the
step’s env and print each with ::notice:: alongside the existing outcomes and
API status; never expose SOCKET_SECURITY_API_KEY.

Source: Path instructions


546-688: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add titled sections inside the Socket job.

The job contains separate checkout, Firewall, App Gate, scan-ID resolution, API report, PR report, enforced gate, and dry-run gate groups. Separate each group with a comment using the required # ----------------- Title ----------------- format.

As per coding guidelines, jobs with more than one logical group must use titled section comments.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/js-pr-validation.yml around lines 546 - 688, Add titled
section comments throughout the Socket job using the required “#
----------------- Title -----------------” format. Separate the Checkout, Socket
Firewall, Socket App Gate, diff-scan resolution, API report, PR report, enforced
gate, and dry-run gate groups, placing each title immediately before its
corresponding step group.

Source: Coding guidelines


592-610: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Security Misconfiguration (CWE-693)

Reachability: External

Select the latest Socket App comment across all pages.

gh api --paginate --jq emits each page separately, so last is page-local. Because grep ... | head -1 selects the first matching ID, an older page can provide a stale diff-scan baseline. Use --slurp and flatten all pages before applying last.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/js-pr-validation.yml around lines 592 - 610, Update the JQ
query in the “Resolve Socket diff scan id” step to use gh api’s --slurp option
and flatten the paginated comment results before selecting the last Socket App
comment. Preserve the existing body extraction and ID parsing flow so the latest
matching comment across all pages supplies ID.

614-630: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Security Misconfiguration (CWE-693)

Reachability: External · Exploitability: Moderate

Preserve enforcement when Socket diff attribution is unavailable.

When diff_scan_id is absent or unresolved, socket-api-report classifies findings as pre-existing and emits no blocking count. The workflow converts the missing count to 0, so socket_api_fail_on_actions cannot reject a pull request that introduces an actioned finding.

Return an explicit attribution-unavailable state and apply the configured block-or-warn policy. Update docs/js-pr-validation.md to document this policy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/js-pr-validation.yml around lines 614 - 630, Update the
Socket API report flow in the “Socket API Report” step to preserve enforcement
when diff attribution is absent or unresolved: return an explicit
attribution-unavailable state instead of converting the missing blocking count
to zero, then apply the configured block-or-warn policy based on
socket_api_fail_on_actions. Update docs/js-pr-validation.md at line 268 to
document this attribution-unavailable behavior and the resulting configured
policy.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/workflows/js-pr-validation.yml:
- Around line 673-688: Update the “Gate - Socket findings (dry run)” step to
expose every resolved non-secret Socket configuration input and computed
variable required by the workflow, including run_socket, socket_enable_firewall,
socket_enable_app_gate, socket_enable_api_report, and all failure policies. Map
these values through the step’s env and print each with ::notice:: alongside the
existing outcomes and API status; never expose SOCKET_SECURITY_API_KEY.
- Around line 546-688: Add titled section comments throughout the Socket job
using the required “# ----------------- Title -----------------” format.
Separate the Checkout, Socket Firewall, Socket App Gate, diff-scan resolution,
API report, PR report, enforced gate, and dry-run gate groups, placing each
title immediately before its corresponding step group.
- Around line 592-610: Update the JQ query in the “Resolve Socket diff scan id”
step to use gh api’s --slurp option and flatten the paginated comment results
before selecting the last Socket App comment. Preserve the existing body
extraction and ID parsing flow so the latest matching comment across all pages
supplies ID.
- Around line 614-630: Update the Socket API report flow in the “Socket API
Report” step to preserve enforcement when diff attribution is absent or
unresolved: return an explicit attribution-unavailable state instead of
converting the missing blocking count to zero, then apply the configured
block-or-warn policy based on socket_api_fail_on_actions. Update
docs/js-pr-validation.md at line 268 to document this attribution-unavailable
behavior and the resulting configured policy.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9b614fcd-6de0-4595-959e-9f1392f3aac9

📥 Commits

Reviewing files that changed from the base of the PR and between c0cced3 and a47239b.

📒 Files selected for processing (3)
  • .github/workflows/js-pr-validation.yml
  • docs/js-pr-validation.md
  • src/security/socket-app-gate/action.yml

@bedatty
bedatty merged commit 4ae8104 into main Aug 7, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

composite Changes to any composite action manifest (src/**/*.yml) dependencies Dependency updates (usually opened by Dependabot) documentation Improvements or additions to documentation github-config Changes to repository configuration (templates, CODEOWNERS, labeler, etc.) golang Changes to Go-related workflows security Changes to security workflows or vulnerability reporting policy size/XL PR changes ≥ 1000 lines — consider splitting typescript Changes to TypeScript or Frontend workflows workflow Changes to one or more reusable workflow files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants