From 94b29fe1392aac57ef12c83d1d75393a5b4a6db4 Mon Sep 17 00:00:00 2001 From: znrac137 Date: Thu, 10 Sep 2026 08:54:24 +1000 Subject: [PATCH 1/5] ci: add dependency review workflow --- .github/workflows/ci.dependency-review.yml | 32 +++++++++ docs/DevSecOps/dependency-review.md | 77 ++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 .github/workflows/ci.dependency-review.yml create mode 100644 docs/DevSecOps/dependency-review.md diff --git a/.github/workflows/ci.dependency-review.yml b/.github/workflows/ci.dependency-review.yml new file mode 100644 index 000000000..3de628a4b --- /dev/null +++ b/.github/workflows/ci.dependency-review.yml @@ -0,0 +1,32 @@ +name: Dependency Review + +on: + pull_request: + +permissions: + contents: read + +jobs: + dependency-review: + name: Dependency review + runs-on: ubuntu-latest + permissions: + contents: read + # Used only for failure summaries on PRs with a writable token. + pull-requests: write + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Review dependency changes + uses: actions/dependency-review-action@v5 + with: + fail-on-severity: high + fail-on-scopes: runtime, development, unknown + vulnerability-check: true + license-check: false + show-patched-versions: true + # Fork and Dependabot PR tokens normally cannot write comments. + comment-summary-in-pr: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && 'on-failure' || 'never' }} diff --git a/docs/DevSecOps/dependency-review.md b/docs/DevSecOps/dependency-review.md new file mode 100644 index 000000000..aeaa458a2 --- /dev/null +++ b/docs/DevSecOps/dependency-review.md @@ -0,0 +1,77 @@ +# Dependency review + +`.github/workflows/ci.dependency-review.yml` checks dependency changes introduced +by pull requests using GitHub's dependency graph and Advisory Database. It runs +when a PR is opened, reopened, or updated with new commits, for all target branches +and paths. It does not install dependencies or execute application code. + +## Policy and feedback + +The check fails when an introduced dependency has a known high or critical +vulnerability. Runtime, development, and unknown scopes are included. License +enforcement is disabled. Low and moderate findings do not fail this policy. + +Read the **Dependency review** check logs and Actions job summary for affected +packages and advisory details. Patched versions are shown when available. Failure +summaries are also posted on same-repository PRs when the token permits comments. +Fork and Dependabot PR comments are disabled because their tokens are normally +read-only; dependency checking and job summaries still run. First-time contributor +workflows may need maintainer approval to start. + +If the check fails, update or remove the affected dependency, regenerate the +relevant lockfile, run the affected project's tests, and push the fix. For a +transitive dependency, update the parent package or discuss a safe resolution with +maintainers. Review API/configuration errors separately from vulnerability +findings; do not disable the check to hide a failure. + +## Relationship to Grype + +Dependency review compares the PR's dependency changes. Grype in +`.github/workflows/ci.grype.yml` scans the repository's broader dependency state +and uploads security findings. Neither replaces the other. This change leaves +Grype unchanged. + +## Testing + +Local validation passed: actionlint checked workflow syntax and expressions, +configured inputs were verified against the v5 action definition, and Git diff +whitespace checks passed. Grype has no diff. Live GitHub pass/fail and PR-comment +behavior have not yet been tested; use the plan below. No vulnerable dependencies +were added to the implementation branch. + +1. Open the implementation PR. Confirm the workflow starts and that a change + without new vulnerable dependencies passes. Save the run URL and job summary. +2. Create a separate temporary branch from the implementation branch and open a + clearly labelled **DO NOT MERGE: dependency review test** PR targeting the + implementation branch (or main after the implementation is merged). +3. Only on that temporary branch, add a dependency version covered by a current + high/critical GitHub advisory and update its manifest/lockfile consistently. + Record the advisory ID and affected version. Do not run application code with + the vulnerable dependency; disable install scripts when generating test data. +4. Confirm the check fails with the package/advisory and a patched version where + available. On a same-repository PR, confirm the failure comment appears. +5. Repeat with the dependency in development scope to verify that scope is gated. + Upgrade to a patched version and confirm the check passes on the next push. +6. Use a separate temporary fork PR if available to verify that review and job + summaries work without a comment or comment-permission error. Obtain any + required workflow approval from a maintainer. +7. Close all temporary test PRs without merging and delete their branches. Keep + the run URLs as evidence. Never merge vulnerable test changes. + +## Limitations and maintainer setup + +- Dependency graph access must be enabled. Coverage depends on GitHub-supported + manifests/lockfiles, resolved versions, and available dependency snapshots. + A passing check does not prove every Python or JavaScript dependency was seen; + inspect the dependency diff when validating coverage. +- Only known advisories and dependencies introduced by the PR are reviewed. This + is not a full-repository scan, runtime test, or guarantee of exploitability. +- Organization token policies can restrict comments even on same-repository PRs. + No personal token or `pull_request_target` is used to bypass restrictions. +- To block merges, maintainers must make the **Dependency review** check required + in branch protection/rulesets. Adding a failing workflow alone does not enforce + that setting. Changes to the workflow itself also need normal code review. +- Actions use the GitHub-hosted `ubuntu-latest` runner. API outages or unavailable + dependency graph data may fail a run independently of this severity policy. + +Reference: [GitHub dependency-review-action documentation](https://github.com/actions/dependency-review-action). From 1ef027b50ef5d00bb18365b01e0eb95f33405cfd Mon Sep 17 00:00:00 2001 From: znrac137 Date: Thu, 10 Sep 2026 09:27:11 +1000 Subject: [PATCH 2/5] ci: simplify dependency review checkout --- .github/workflows/ci.dependency-review.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.dependency-review.yml b/.github/workflows/ci.dependency-review.yml index 3de628a4b..705987b5a 100644 --- a/.github/workflows/ci.dependency-review.yml +++ b/.github/workflows/ci.dependency-review.yml @@ -17,8 +17,6 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v6 - with: - persist-credentials: false - name: Review dependency changes uses: actions/dependency-review-action@v5 @@ -29,4 +27,4 @@ jobs: license-check: false show-patched-versions: true # Fork and Dependabot PR tokens normally cannot write comments. - comment-summary-in-pr: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && 'on-failure' || 'never' }} + comment-summary-in-pr: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && 'on-failure' || 'never' }} \ No newline at end of file From 73321b9157e05b14f6e14afdab97983d0bb19119 Mon Sep 17 00:00:00 2001 From: znrac137 Date: Thu, 10 Sep 2026 09:31:19 +1000 Subject: [PATCH 3/5] ci: remove checkout from dependency review --- .github/workflows/ci.dependency-review.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/ci.dependency-review.yml b/.github/workflows/ci.dependency-review.yml index 705987b5a..3c843f093 100644 --- a/.github/workflows/ci.dependency-review.yml +++ b/.github/workflows/ci.dependency-review.yml @@ -12,12 +12,8 @@ jobs: runs-on: ubuntu-latest permissions: contents: read - # Used only for failure summaries on PRs with a writable token. pull-requests: write steps: - - name: Checkout repository - uses: actions/checkout@v6 - - name: Review dependency changes uses: actions/dependency-review-action@v5 with: @@ -26,5 +22,4 @@ jobs: vulnerability-check: true license-check: false show-patched-versions: true - # Fork and Dependabot PR tokens normally cannot write comments. comment-summary-in-pr: ${{ github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' && 'on-failure' || 'never' }} \ No newline at end of file From fbeb76c22b7842476cd641b854d28cfbb8112e68 Mon Sep 17 00:00:00 2001 From: znrac137 Date: Mon, 14 Sep 2026 09:31:19 +1000 Subject: [PATCH 4/5] docs: update dependency review testing results --- docs/DevSecOps/dependency-review.md | 38 +++++++++++------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/docs/DevSecOps/dependency-review.md b/docs/DevSecOps/dependency-review.md index aeaa458a2..cf48f74e4 100644 --- a/docs/DevSecOps/dependency-review.md +++ b/docs/DevSecOps/dependency-review.md @@ -33,30 +33,20 @@ Grype unchanged. ## Testing -Local validation passed: actionlint checked workflow syntax and expressions, -configured inputs were verified against the v5 action definition, and Git diff -whitespace checks passed. Grype has no diff. Live GitHub pass/fail and PR-comment -behavior have not yet been tested; use the plan below. No vulnerable dependencies -were added to the implementation branch. - -1. Open the implementation PR. Confirm the workflow starts and that a change - without new vulnerable dependencies passes. Save the run URL and job summary. -2. Create a separate temporary branch from the implementation branch and open a - clearly labelled **DO NOT MERGE: dependency review test** PR targeting the - implementation branch (or main after the implementation is merged). -3. Only on that temporary branch, add a dependency version covered by a current - high/critical GitHub advisory and update its manifest/lockfile consistently. - Record the advisory ID and affected version. Do not run application code with - the vulnerable dependency; disable install scripts when generating test data. -4. Confirm the check fails with the package/advisory and a patched version where - available. On a same-repository PR, confirm the failure comment appears. -5. Repeat with the dependency in development scope to verify that scope is gated. - Upgrade to a patched version and confirm the check passes on the next push. -6. Use a separate temporary fork PR if available to verify that review and job - summaries work without a comment or comment-permission error. Obtain any - required workflow approval from a maintainer. -7. Close all temporary test PRs without merging and delete their branches. Keep - the run URLs as evidence. Never merge vulnerable test changes. +Local validation passed: actionlint checked workflow syntax and expressions, configured inputs were verified against the v5 action definition, and Git diff whitespace checks passed. Grype has no diff and was not modified. + +Live GitHub testing was completed after opening the implementation PR. + +Testing completed: +1. The Dependency Review workflow passed on the clean implementation PR, confirming that the workflow can run successfully without blocking valid dependency/documentation workflow changes. +2. A separate temporary **DO NOT MERGE** test PR was created in my fork to test failure behaviour. +3. The temporary test PR introduced `lodash 4.17.18` only on the test branch. +4. Dependency Review failed as expected and reported high severity vulnerabilities, affected package details, and patched versions. +5. The vulnerable test PR was used only for validation and must not be merged. + +No vulnerable dependencies were added to the implementation branch. + +PR comment behaviour remains permission-dependent. The workflow is configured to post failure summaries where the GitHub token allows it, but contributors should rely on the Actions job summary and check logs as the consistent source of dependency review results. ## Limitations and maintainer setup From afda8f73ec34ef22ee3556ef874f8151e15703e4 Mon Sep 17 00:00:00 2001 From: znrac137 Date: Tue, 15 Sep 2026 07:45:59 +1000 Subject: [PATCH 5/5] ci: pin dependency review action --- .github/workflows/ci.dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.dependency-review.yml b/.github/workflows/ci.dependency-review.yml index 3c843f093..e32483891 100644 --- a/.github/workflows/ci.dependency-review.yml +++ b/.github/workflows/ci.dependency-review.yml @@ -15,7 +15,7 @@ jobs: pull-requests: write steps: - name: Review dependency changes - uses: actions/dependency-review-action@v5 + uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0 with: fail-on-severity: high fail-on-scopes: runtime, development, unknown