From 49ebce093bef956d7c6622920ef36010d159ee1b Mon Sep 17 00:00:00 2001 From: Scott Gerlach Date: Wed, 1 Apr 2026 10:36:32 -0600 Subject: [PATCH 1/4] security: add environment gate and tag validation to update-main-version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses Finding 1 from the TeamPCP/GitHub Actions security audit (March 2026): - Add `environment: tag-release` to require human approval before any force-push runs. Create this environment in Settings → Environments with required reviewers. - Add preflight validation step that rejects any `target` input that is not an existing named tag in refs/tags/. This closes the exact attack vector used in the Trivy compromise — an attacker cannot point v2 at an arbitrary commit SHA or branch ref. --- .github/workflows/update-main-version.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/update-main-version.yml b/.github/workflows/update-main-version.yml index c53cb1c..dcdd7d6 100644 --- a/.github/workflows/update-main-version.yml +++ b/.github/workflows/update-main-version.yml @@ -16,17 +16,34 @@ on: jobs: tag: runs-on: ubuntu-latest + # SECURITY: Require human approval via a protected Environment before the + # force-push runs. Create a "tag-release" environment in: + # Settings -> Environments -> New environment -> add Required Reviewers + environment: tag-release permissions: contents: write steps: - uses: actions/checkout@v5 with: fetch-depth: 0 + + # SECURITY: Validate that target is an existing named tag. + # Prevents pointing v2 at an arbitrary commit SHA or branch ref. + - name: Validate target is an existing tag + run: | + if ! git rev-parse --verify "refs/tags/${{ github.event.inputs.target }}" > /dev/null 2>&1; then + echo "::error::Input 'target' must be an existing tag. '${{ github.event.inputs.target }}' was not found in refs/tags/." + exit 1 + fi + echo "Validated: '${{ github.event.inputs.target }}' is an existing tag." + - name: Git config run: | git config user.name hawkdeploy git config user.email hawkdeploy@stackhawk.com + - name: Tag new target run: git tag -f ${{ github.event.inputs.main_version }} ${{ github.event.inputs.target }} + - name: Push new tag run: git push origin ${{ github.event.inputs.main_version }} --force From bec712b9cb58cef4929e81174240516616b0bcc4 Mon Sep 17 00:00:00 2001 From: bwvolleyball Date: Thu, 2 Apr 2026 11:17:31 -0600 Subject: [PATCH 2/4] =?UTF-8?q?Bump=20version:=202.4.0=20=E2=86=92=202.5.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- README.md | 24 ++++++++++++------------ package.json | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 95136a8..41862f8 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2.4.0 +current_version = 2.5.0 commit = True tag = False diff --git a/README.md b/README.md index d60e077..08c49b4 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stackhawk/hawkscan-action@v2.4.0 + - uses: stackhawk/hawkscan-action@v2.5.0 with: apiKey: ${{ secrets.HAWK_API_KEY }} ``` @@ -45,7 +45,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stackhawk/hawkscan-action@v2.4.0 + - uses: stackhawk/hawkscan-action@v2.5.0 with: args: | --hawk-mem 1g @@ -62,7 +62,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stackhawk/hawkscan-action@v2.4.0 + - uses: stackhawk/hawkscan-action@v2.5.0 with: command: rescan ``` @@ -78,7 +78,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stackhawk/hawkscan-action@v2.4.0 + - uses: stackhawk/hawkscan-action@v2.5.0 with: apiKey: ${{ secrets.HAWK_API_KEY }} dryRun: true @@ -95,7 +95,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stackhawk/hawkscan-action@v2.4.0 + - uses: stackhawk/hawkscan-action@v2.5.0 with: apiKey: ${{ secrets.HAWK_API_KEY }} configurationFiles: stackhawk.yml stackhawk-extra.yml @@ -112,7 +112,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stackhawk/hawkscan-action@v2.4.0 + - uses: stackhawk/hawkscan-action@v2.5.0 with: installCLIOnly: true - name: Run CLI Scan @@ -132,7 +132,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stackhawk/hawkscan-action@v2.4.0 + - uses: stackhawk/hawkscan-action@v2.5.0 with: apiKey: ${{ secrets.HAWK_API_KEY }} codeScanningAlerts: true @@ -155,7 +155,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stackhawk/hawkscan-action@v2.4.0 + - uses: stackhawk/hawkscan-action@v2.5.0 with: apiKey: ${{ secrets.HAWK_API_KEY }} verbose: true @@ -172,7 +172,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stackhawk/hawkscan-action@v2.4.0 + - uses: stackhawk/hawkscan-action@v2.5.0 with: workspace: ./app/config/ ``` @@ -187,7 +187,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stackhawk/hawkscan-action@v2.4.0 + - uses: stackhawk/hawkscan-action@v2.5.0 with: version: 2.7.0 ``` @@ -209,7 +209,7 @@ jobs: pip3 install -r requirements.txt nohup python3 app.py & - name: Scan my app - uses: stackhawk/hawkscan-action@v2.4.0 + uses: stackhawk/hawkscan-action@v2.5.0 with: apiKey: ${{ secrets.HAWK_API_KEY }} ``` @@ -233,7 +233,7 @@ jobs: APP_HOST: 'http://localhost:5000' APP_ID: AE624DB7-11FC-4561-B8F2-2C8ECF77C2C7 APP_ENV: Development - uses: stackhawk/hawkscan-action@v2.4.0 + uses: stackhawk/hawkscan-action@v2.5.0 with: apiKey: ${{ secrets.HAWK_API_KEY }} dryRun: true diff --git a/package.json b/package.json index 8bc0ad3..d09752c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hawkscan-action", - "version": "2.4.0", + "version": "2.5.0", "description": "StackHawk HawkScan Action", "main": "src/index.js", "type": "module", From 09f888d6bffa5cd650f955694b3a32b8e16d11e6 Mon Sep 17 00:00:00 2001 From: bwvolleyball Date: Thu, 2 Apr 2026 11:18:40 -0600 Subject: [PATCH 3/4] docs: clarify that version bump is required for releases in CLAUDE.md Without a bump2version call, the CI "Create Release" step is silently skipped because version-check.sh finds the existing tag. Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 906dcc9..6550bb0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,13 +25,23 @@ Use the version in `.nvmrc` (currently v24). Run `nvm use` before any npm comman ## Release Process -See `.github/CONTRIBUTING.md` for full details. Summary: +**Every PR that should result in a new release MUST include a version bump.** Without it, the CI "Create Release" step will be skipped on merge because `scripts/version-check.sh` sees the existing tag and produces no output. -1. Use `./scripts/release-pr.sh -b ` to create a release PR (requires `bump2version` and `gh`) -2. The script bumps versions, runs `npm run all`, rebuilds dist/, commits, pushes, and creates a PR -3. On merge to `main`, CI auto-creates a GitHub Release with tag `v{version}` -4. Manually edit the release to publish to GitHub Marketplace -5. Manually run the "Update Main Version" workflow dispatch to move the `v2` tag to the new release +Bump the version using `bump2version`: + +```bash +bump2version # updates .bumpversion.cfg, package.json, README.md and creates a commit +``` + +Alternatively, use the release PR script which handles the full flow: + +```bash +./scripts/release-pr.sh -b # requires bump2version and gh CLI +``` + +On merge to `main`, CI auto-creates a GitHub Release with tag `v{version}`. After that: +1. Manually edit the release to publish to GitHub Marketplace +2. Manually run the "Update Main Version" workflow dispatch to move the `v2` tag to the new release ## Project Structure From 11923a356d112ae11c8ec11ea30bb1af4134da8a Mon Sep 17 00:00:00 2001 From: bwvolleyball Date: Thu, 2 Apr 2026 11:20:01 -0600 Subject: [PATCH 4/4] docs: add CONTRIBUTING.md reference back to release section Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 6550bb0..424ba4d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -39,7 +39,7 @@ Alternatively, use the release PR script which handles the full flow: ./scripts/release-pr.sh -b # requires bump2version and gh CLI ``` -On merge to `main`, CI auto-creates a GitHub Release with tag `v{version}`. After that: +See `.github/CONTRIBUTING.md` for full release details. On merge to `main`, CI auto-creates a GitHub Release with tag `v{version}`. After that: 1. Manually edit the release to publish to GitHub Marketplace 2. Manually run the "Update Main Version" workflow dispatch to move the `v2` tag to the new release