Skip to content

docs: Dependabot security-only update standards#9

Merged
don-petry merged 6 commits intomainfrom
chore/dependabot-security-standards
Apr 4, 2026
Merged

docs: Dependabot security-only update standards#9
don-petry merged 6 commits intomainfrom
chore/dependabot-security-standards

Conversation

@don-petry
Copy link
Copy Markdown
Contributor

@don-petry don-petry commented Apr 3, 2026

Summary

  • Adds standards/dependabot-policy.md defining the org-wide policy: security-only updates for application dependencies, weekly version updates for GitHub Actions only
  • Adds dependabot.yml templates for each ecosystem (npm, Go, Rust, Python, Terraform, full-stack)
  • Adds standard dependabot-automerge.yml workflow (patch/minor auto-approve + squash-merge via GitHub App token)
  • Adds dependency-audit.yml CI workflow that auto-detects ecosystems and runs npm audit / govulncheck / cargo audit / pip-audit, failing the build on known vulnerabilities

Policy change from current state

Before After
Scope GitHub Actions only (broodly, markets) All ecosystems in all repos
Update trigger All version bumps (minor/patch) Security advisories only (app deps); version updates (GH Actions)
Labels None security + dependencies on every PR
Vulnerability CI None Required status check — blocks merge on known CVEs
Auto-merge Exists (broodly, markets) Standardized across all repos

Repo applicability

Repo Ecosystems Template
broodly npm + gomod + terraform + github-actions fullstack
markets npm + gomod + github-actions fullstack
dagger cargo + github-actions backend-rust
context-scribe pip + github-actions backend-python
TalkTerm npm + github-actions frontend
ContentTwin github-actions (empty repo)

Test plan

  • Review policy document for completeness and clarity
  • Validate each dependabot.yml template against GitHub schema
  • Validate dependency-audit.yml workflow syntax
  • Validate dependabot-automerge.yml workflow syntax
  • After merge: apply to each repo (separate PRs)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation

    • Added a repository-wide Dependabot and security policy documenting update cadence, required labels, and audit/merge expectations across ecosystems.
  • New Features

    • Per-ecosystem Dependabot configurations with weekly schedules and label enforcement.
    • Automated vulnerability-audit workflow that runs on PRs and main, failing on known advisories.
    • Auto-merge for eligible patch/minor/security updates; major updates remain for manual review.

Define org-wide policy for dependency management: security-only updates
for application packages, weekly version updates for GitHub Actions,
mandatory labels, auto-merge workflow, and vulnerability audit CI check.

Includes templates for npm, Go, Rust, Python, Terraform, and full-stack
repositories.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 3, 2026 18:34
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

📝 Walkthrough

Walkthrough

Adds repository-wide Dependabot policies and per-ecosystem Dependabot configs, a Dependabot auto-merge workflow that auto-merges eligible Dependabot PRs using a GitHub App token, and a dependency-audit workflow that runs ecosystem-specific vulnerability scans on PRs and pushes to main.

Changes

Cohort / File(s) Summary
Policy Document
standards/dependabot-policy.md
New policy describing security-only app dependency updates, weekly GitHub Actions updates, required security/dependencies labels, auto-merge rules for patch/minor/indirect updates, and mandatory vulnerability-audit CI requirements and config prerequisites.
Dependabot Configs — Language-specific
standards/dependabot/backend-go.yml, standards/dependabot/backend-python.yml, standards/dependabot/backend-rust.yml
New Dependabot v2 configs for Go, Python, and Rust: weekly schedules, security-only for app ecosystems (open-pull-requests-limit: 0), and github-actions entries (weekly, up to 10 PRs). Labels applied: security, dependencies.
Dependabot Configs — Frontend / Fullstack / Infra
standards/dependabot/frontend.yml, standards/dependabot/fullstack.yml, standards/dependabot/infra-terraform.yml
New configs for npm, full-stack multi-ecosystem (npm, gomod, terraform, github-actions), and Terraform infra: weekly schedules, security-only where applicable, github-actions updates allowed up to 10 PRs, security/dependencies labels.
Workflows — Auto-merge & Audit
standards/workflows/dependabot-automerge.yml, standards/workflows/dependency-audit.yml
Adds Dependabot auto-merge workflow (runs on pull_request_target; gates by update type; generates GitHub App token; approves and enables auto-squash merge with gh for eligible PRs) and Dependency audit workflow (detects manifests and conditionally runs npm/pnpm/go/cargo/pip vulnerability checks; fails on known advisories).

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Dependabot
participant Repo as Repository
participant Workflow as "GitHub Actions\n(dependabot-automerge)"
participant App as "GitHub App\n(creates token)"
participant CLI as "gh CLI"
participant CI as "Required CI checks"
Dependabot->>Repo: Open Dependabot PR (labels: security, dependencies)
Repo->>Workflow: trigger pull_request_target (runs on PR)
Workflow->>Repo: read PR metadata (update-type, indirect/semver)
alt Eligible (patch/minor/indirect)
Workflow->>App: request installation token (uses APP_ID, APP_PRIVATE_KEY)
App-->>Workflow: return installation token
Workflow->>CLI: authenticate gh with token; approve PR
Workflow->>Repo: enable auto-merge (squash) via gh --auto --squash
Repo->>CI: run required checks on PR
CI-->>Repo: report statuses (pass/fail)
alt CI passes
Repo->>Repo: auto-merge PR into main
else CI fails
Repo->>Workflow: merge deferred (await fixes)
end
else Ineligible (major/other)
Workflow-->>Repo: no auto-merge; leave for human review
end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'docs: Dependabot security-only update standards' directly and accurately summarizes the main change—establishing organization-wide Dependabot standards with a security-first policy across multiple ecosystem templates and workflows.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/dependabot-security-standards

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

don-petry added a commit to petry-projects/broodly that referenced this pull request Apr 3, 2026
Add npm, gomod, and terraform ecosystems to dependabot.yml with
security/dependencies labels. Add dependency-audit workflow for
CI vulnerability scanning. Aligns with petry-projects/.github#9.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Introduces org-wide Dependabot “security-only” standards by adding a policy document, Dependabot configuration templates for multiple ecosystems, and GitHub Actions workflows for automated dependency vulnerability auditing and Dependabot PR auto-merge.

Changes:

  • Add a Dependabot policy document describing security-only dependency updates and supporting repo requirements.
  • Add dependabot.yml templates for common repo/ecosystem layouts.
  • Add GitHub Actions workflows for dependency vulnerability auditing and Dependabot PR auto-merge.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 18 comments.

Show a summary per file
File Description
standards/dependabot-policy.md Documents the intended security-only policy and how to apply templates/workflows.
standards/workflows/dependency-audit.yml Adds a dependency vulnerability audit workflow with ecosystem auto-detection.
standards/workflows/dependabot-automerge.yml Adds a workflow to auto-approve/squash-merge Dependabot PRs under certain conditions.
standards/dependabot/frontend.yml Dependabot template for npm + GitHub Actions.
standards/dependabot/backend-go.yml Dependabot template for Go modules + GitHub Actions.
standards/dependabot/backend-rust.yml Dependabot template for Cargo + GitHub Actions.
standards/dependabot/backend-python.yml Dependabot template for pip + GitHub Actions.
standards/dependabot/infra-terraform.yml Dependabot template for Terraform + GitHub Actions.
standards/dependabot/fullstack.yml Dependabot template for npm + Go + Terraform + GitHub Actions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +101 to +113
audit-cargo:
name: cargo audit
needs: detect
if: needs.detect.outputs.cargo == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4

- name: Install cargo-audit
run: cargo install cargo-audit

- name: Audit Cargo dependencies
run: cargo audit
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

audit-cargo uses cargo install/cargo audit but the workflow never installs a Rust toolchain. On ubuntu-latest this job will fail because cargo is not available by default. Add a Rust setup step (e.g., install a toolchain) before invoking cargo.

Copilot uses AI. Check for mistakes.
Comment on lines +48 to +53
# Cargo
if [ -f "Cargo.lock" ]; then
echo "cargo=true" >> "$GITHUB_OUTPUT"
else
echo "cargo=false" >> "$GITHUB_OUTPUT"
fi
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

Ecosystem detection for Rust only checks for a root-level Cargo.lock. Repos with a Cargo.toml but no lockfile (libraries) or workspaces with lockfiles in subdirectories will be skipped, so vulnerabilities won’t be audited. Consider detecting Cargo.toml / searching for Cargo.lock recursively and running cargo audit per workspace root.

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +39
# npm
if find . -name 'package-lock.json' -not -path '*/node_modules/*' | grep -q .; then
echo "npm=true" >> "$GITHUB_OUTPUT"
else
echo "npm=false" >> "$GITHUB_OUTPUT"
fi
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

npm detection is based on finding any package-lock.json anywhere in the repo, but the audit job runs npm audit only once at the repository root. In monorepos with multiple lockfiles (or a lockfile not at /), this will miss auditing the other packages or fail if there’s no root package-lock.json. Consider iterating over each lockfile’s directory and auditing each one.

Copilot uses AI. Check for mistakes.
Comment on lines +74 to +75
- name: Audit npm dependencies
run: npm audit --audit-level=moderate
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

npm audit --audit-level=moderate allows "low" severity vulnerabilities to pass. This conflicts with the stated goal of failing the build on known vulnerabilities; use an audit level that fails on any advisory (or an explicit policy-defined threshold) and document it consistently.

Copilot uses AI. Check for mistakes.
go-version: "stable"

- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

Installing govulncheck@latest makes the workflow non-reproducible and can introduce unexpected breakages (or supply-chain risk) when new versions are released. Prefer pinning to a known version (and updating it intentionally) or using a dedicated install action that supports version pinning.

Suggested change
run: go install golang.org/x/vuln/cmd/govulncheck@latest
run: go install golang.org/x/vuln/cmd/govulncheck@v1.1.3

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +13
# pip — security updates only
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
labels:
- "security"
- "dependencies"
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

This template states “security updates only,” but a scheduled updates: entry for the pip ecosystem will generate regular version update PRs unless version updates are explicitly suppressed. Update the template or wording to align with the security-only policy.

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +13
# Terraform — security updates only
- package-ecosystem: "terraform"
directory: "/infra/terraform"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
labels:
- "security"
- "dependencies"
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

This template states “security updates only,” but a scheduled updates: entry for Terraform will run regular version updates for providers/modules unless version updates are explicitly suppressed. Update the template or wording to align with the security-only policy.

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +38
updates:
# npm — security updates only
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
labels:
- "security"
- "dependencies"

# Go modules — security updates only
- package-ecosystem: "gomod"
directory: "/apps/api"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
labels:
- "security"
- "dependencies"

# Terraform — security updates only
- package-ecosystem: "terraform"
directory: "/infra/terraform"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
labels:
- "security"
- "dependencies"
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

This template labels npm/gomod/terraform entries as “security updates only,” but these scheduled updates: entries will generate regular version update PRs unless version updates are explicitly suppressed. Update the template or wording to align with the security-only policy.

Copilot uses AI. Check for mistakes.

See [`workflows/dependency-audit.yml`](workflows/dependency-audit.yml).

This reusable workflow detects the ecosystems present in the repo and runs the
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

standards/workflows/dependency-audit.yml is a copy-paste workflow template, not a reusable workflow invoked via workflow_call. Consider changing the wording here to avoid confusion (or convert it to a reusable workflow if that’s the intent).

Suggested change
This reusable workflow detects the ecosystems present in the repo and runs the
This workflow template detects the ecosystems present in the repo and runs the

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +46
# Go modules
if find . -name 'go.sum' | grep -q .; then
echo "gomod=true" >> "$GITHUB_OUTPUT"
else
echo "gomod=false" >> "$GITHUB_OUTPUT"
fi
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

Go ecosystem detection checks for go.sum, but Go modules are defined by go.mod and some repos/modules may not have a go.sum committed (e.g., very small modules or new modules). This can cause govulncheck to be skipped even when Go code exists. Consider detecting via go.mod (optionally excluding vendor/ and other generated paths).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@standards/dependabot-policy.md`:
- Around line 11-12: The policy text claims "Dependabot opens PRs only when a
vulnerability advisory exists" but the repo's Dependabot configuration enables
scheduled version updates; either update the policy wording in
standards/dependabot-policy.md to describe that dependabot.yml schedules weekly
version updates (and note security updates are automatic), or change the
Dependabot templates to stop scheduled version PRs by disabling version updates
(e.g., set open-pull-requests-limit: 0 or remove the schedule entries) so only
automatic security alerts create PRs; reference the repository's dependabot.yml
and the policy sentence "Dependabot opens PRs only when a vulnerability advisory
exists" when making the change.
- Around line 133-138: The documented npm audit command `npm audit
--audit-level=moderate` requires a package-lock.json and has differing exit-code
behavior between npm 6.x and 7+, so update the policy to (1) state the
prerequisite that a package-lock.json must exist before running `npm audit
--audit-level=moderate` and (2) adjust the CI workflow that runs `npm audit
--audit-level=moderate` to first check for `package-lock.json` and either
generate one (e.g., run `npm i --package-lock-only`) or skip the audit with a
clear message when missing, and to normalize handling of audit exit codes by
running the audit in a mode that emits machine-readable output (e.g., JSON) and
parsing vulnerability counts or by explicitly allowing both npm 6 and 7+ exit
behaviors so the workflow doesn’t fail unexpectedly.
- Around line 144-151: The three consecutive numbered steps (steps 1–3) all
start with "Copy", which harms readability; rephrase them to vary sentence
structure while keeping meaning — e.g., step 1: "Place the appropriate
`dependabot.yml` template at `.github/dependabot.yml`, adjusting `directory`
paths as needed"; step 2: "Add `workflows/dependabot-automerge.yml` to
`.github/workflows/`"; step 3: "Also add `workflows/dependency-audit.yml` to
`.github/workflows/`"; leave steps 4–5 as-is (mentioning `APP_ID`,
`APP_PRIVATE_KEY` and creating `security` and `dependencies` labels) so the
intent and file names (`.github/dependabot.yml`,
`workflows/dependabot-automerge.yml`, `workflows/dependency-audit.yml`) remain
explicit.

In `@standards/dependabot/fullstack.yml`:
- Around line 9-48: The Dependabot config allows up to 10 open PRs per ecosystem
(see open-pull-requests-limit in each package-ecosystem block), which can create
up to ~40 concurrent PRs; reduce the per-ecosystem open-pull-requests-limit (for
example to 5) for the npm, gomod, terraform, and github-actions entries or add
inline comments clarifying why the higher limit is intentional (so reviewers
understand the risk), updating the open-pull-requests-limit value in each
package-ecosystem block (npm, gomod, terraform, github-actions) accordingly.

In `@standards/workflows/dependabot-automerge.yml`:
- Around line 37-51: The workflow currently auto-merges any
semver-patch/semver-minor or indirect update; update both conditional
expressions (the one before the "app-token" step with id "app-token" and the one
for the "Approve and auto-merge" step) to also require that the PR is a
Dependabot security update by adding a check for the security label (e.g. add &&
contains(join(github.event.pull_request.labels.*.name, ','), 'security') or
equivalent contains(...) test on github.event.pull_request.labels) so only
patch/minor security updates are auto-merged; if instead you intend to
auto-merge all non-major updates, update the policy docs accordingly.

In `@standards/workflows/dependency-audit.yml`:
- Around line 132-134: The pip-audit invocation audits the runner environment
because it has no input; update the pyproject.toml branch to export the project
dependencies from pyproject.toml and pass them to pip-audit instead of running
it with no args. For example, use the project tool (e.g., poetry) to export
requirements (poetry export -f requirements.txt --without-hashes) and then call
pip-audit with -r on that exported file (pip-audit -r <exported-requirements>
--require-hashes=false), or otherwise generate a requirements list from
pyproject.toml and pass it via pip-audit --requirement/-r so pip-audit scans the
repository dependencies rather than the runner environment.
- Line 90: The CI step uses unpinned installs (e.g., the go install command for
govulncheck: "go install golang.org/x/vuln/cmd/govulncheck@latest") which makes
audits non-reproducible; replace "@latest" with a specific vetted version (or CI
variable like GOVULNCHECK_VERSION) and similarly pin cargo-audit and pip-audit
invocations referenced elsewhere (lines calling cargo-audit and pip-audit) to
their recommended stable releases, updating the commands to use the pinned
version variables and document the chosen versions in the workflow header so the
dependency-audit.yml consistently installs reproducible tool versions.
- Around line 49-57: The Cargo and Python detection/audit blocks are only
checking the repo root; update them to mirror the recursive pattern used for npm
and Go: change the Cargo detection (the block that writes
"cargo=true"/"cargo=false") to use find to locate nested Cargo.toml files and
set cargo=true if any are found, and adjust the cargo-audit step (currently a
single-run step) to iterate over each found Cargo project directory like the Go
audit loop; similarly change the Python detection (the block writing
"pip=true"/"pip=false") to search recursively for pyproject.toml or
requirements.txt and set pip=true accordingly, and update the pip-audit step to
run pip-audit per discovered Python project directory using the same
multi-directory loop approach used in the Go audit section.
- Line 75: Replace the single-line run step that currently executes "npm audit
--audit-level=moderate" with a command that recursively finds every
package-lock.json and runs "npm audit" from each package directory using the
lower audit level "low" so low-severity issues cause failure; specifically,
change the run step (the line containing npm audit --audit-level=moderate) to:
find all package-lock.json files (excluding node_modules), cd into each parent
directory and run npm audit --audit-level=low (ensuring the shell exits non-zero
on any audit failure).
🪄 Autofix (Beta)

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0a1a19ed-a11b-4ec3-ae6c-9510b364375b

📥 Commits

Reviewing files that changed from the base of the PR and between 531c356 and fab5e78.

📒 Files selected for processing (9)
  • standards/dependabot-policy.md
  • standards/dependabot/backend-go.yml
  • standards/dependabot/backend-python.yml
  • standards/dependabot/backend-rust.yml
  • standards/dependabot/frontend.yml
  • standards/dependabot/fullstack.yml
  • standards/dependabot/infra-terraform.yml
  • standards/workflows/dependabot-automerge.yml
  • standards/workflows/dependency-audit.yml

Comment on lines +37 to +51
if: >-
steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
steps.metadata.outputs.update-type == 'version-update:semver-minor' ||
steps.metadata.outputs.dependency-type == 'indirect'
id: app-token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Approve and auto-merge
if: >-
steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
steps.metadata.outputs.update-type == 'version-update:semver-minor' ||
steps.metadata.outputs.dependency-type == 'indirect'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Implementation doesn't match policy: auto-merges all patch/minor, not just security updates.

The policy document states auto-merge applies to "patch and minor security updates", but this workflow auto-merges any patch/minor/indirect update regardless of whether it's security-related.

To align with the stated policy, the workflow should also check for the security label (which Dependabot security updates automatically apply) or verify the update is from a security advisory:

🔧 Proposed fix to restrict to security updates
      - name: Generate app token
        if: >-
+         contains(github.event.pull_request.labels.*.name, 'security') &&
+         (
          steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
          steps.metadata.outputs.update-type == 'version-update:semver-minor' ||
          steps.metadata.outputs.dependency-type == 'indirect'
+         )
        id: app-token

Apply the same change to the "Approve and auto-merge" step's if condition.

Alternatively, if the intent is to auto-merge all non-major updates (not just security), update the policy documentation to reflect this.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@standards/workflows/dependabot-automerge.yml` around lines 37 - 51, The
workflow currently auto-merges any semver-patch/semver-minor or indirect update;
update both conditional expressions (the one before the "app-token" step with id
"app-token" and the one for the "Approve and auto-merge" step) to also require
that the PR is a Dependabot security update by adding a check for the security
label (e.g. add && contains(join(github.event.pull_request.labels.*.name, ','),
'security') or equivalent contains(...) test on
github.event.pull_request.labels) so only patch/minor security updates are
auto-merged; if instead you intend to auto-merge all non-major updates, update
the policy docs accordingly.

DJ and others added 2 commits April 3, 2026 11:41
- Use open-pull-requests-limit: 0 for app ecosystems to suppress version
  update PRs (security updates bypass this limit)
- Switch auto-merge from --admin to --auto --squash to respect CI checks
- Fix dependency-audit: detect go.mod not go.sum, detect Cargo.toml not
  Cargo.lock, add Rust toolchain setup, handle monorepo npm lockfiles,
  pin tool versions (govulncheck v1.1.4, cargo-audit 0.21.1,
  pip-audit 2.9.0), install Python deps before auditing
- Use npm audit --audit-level=low to fail on any advisory
- Update policy doc wording for clarity

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Auto-merge: restructure eligibility check with explicit step, add
  defense-in-depth comment explaining security model
- dependency-audit: make Cargo and Python detection recursive (matching
  npm/Go pattern), iterate over workspace dirs for cargo audit, use
  pip-audit with project path instead of auditing runner env, use
  process substitution to preserve exit status across subshells
- Policy doc: fix wording (Copy → Add), update audit table for monorepo

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DJ and others added 3 commits April 3, 2026 11:47
Repos like broodly use pnpm instead of npm. The workflow now detects
pnpm-lock.yaml and runs pnpm audit alongside npm audit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cargo-audit 0.21.1 fails parsing RustSec advisories using CVSS 4.0
scores (e.g., RUSTSEC-2025-0138). Version 0.22.1 adds support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The setup-node cache: "pnpm" option fails during post-job cleanup
when the pnpm store path doesn't exist. Caching isn't needed for
a one-off audit run.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@don-petry
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 4, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
standards/workflows/dependabot-automerge.yml (1)

42-61: ⚠️ Potential issue | 🟠 Major

Eligibility gate is too broad for app ecosystems.

Current logic auto-enables merge for any patch/minor/indirect update and does not actually enforce ecosystem/security gating. That can auto-merge non-security app dependency updates if a repo’s dependabot.yml is loosened. Add an explicit allow rule for github-actions, and require security label for non-actions ecosystems.

Suggested hardening
       - name: Determine if auto-merge eligible
         id: eligible
+        env:
+          LABELS: ${{ join(github.event.pull_request.labels.*.name, ',') }}
         run: |
           UPDATE_TYPE="${{ steps.metadata.outputs.update-type }}"
           DEP_TYPE="${{ steps.metadata.outputs.dependency-type }}"
           ECOSYSTEM="${{ steps.metadata.outputs.package-ecosystem }}"
@@
-          # GitHub Actions version updates are always eligible
-          # App ecosystem PRs can only exist as security updates (limit: 0)
+          # For non-actions ecosystems, require explicit security labeling
+          if [[ "$ECOSYSTEM" != "github-actions" && ",$LABELS," != *",security,"* ]]; then
+            echo "eligible=false" >> "$GITHUB_OUTPUT"
+            echo "Skipping: non-security app dependency update"
+            exit 0
+          fi
+
           echo "eligible=true" >> "$GITHUB_OUTPUT"
           echo "Auto-merge eligible: ecosystem=$ECOSYSTEM update=$UPDATE_TYPE"
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@standards/dependabot-policy.md`:
- Line 176: Update item 6 to use the actual check-run name produced by the
workflow: replace the filename token `dependency-audit` with the check-run
string "Dependency audit / detect" so branch protection requires the real
check-run `{workflow-name} / {job-key}` used by the audit workflow.

In `@standards/workflows/dependency-audit.yml`:
- Line 161: The workflow currently references dtolnay/rust-toolchain@stable (a
moving tag); change that to a specific commit SHA to match the rest of the
workflow. Locate the uses: dtolnay/rust-toolchain@stable entry and replace the
`@stable` tag with the exact commit SHA (e.g., @<commit-sha>) you want to pin so
the action is immutable and consistent with other actions like actions/checkout;
ensure you choose a valid commit SHA from the dtolnay/rust-toolchain repository.
- Line 173: Replace the silent stderr suppression on the cargo generate-lockfile
invocation so real errors aren't hidden: instead of redirecting stderr
(2>/dev/null) call cargo generate-lockfile with --quiet and fall back with ||
true so cargo audit still runs; update the command that currently invokes cargo
generate-lockfile 2>/dev/null; cargo audit to use cargo generate-lockfile
--quiet || true; cargo audit so legitimate errors surface while preserving
current behavior.
🪄 Autofix (Beta)

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5d7f528f-4789-4105-9ac2-485595e771c7

📥 Commits

Reviewing files that changed from the base of the PR and between fab5e78 and 8ca31e4.

📒 Files selected for processing (9)
  • standards/dependabot-policy.md
  • standards/dependabot/backend-go.yml
  • standards/dependabot/backend-python.yml
  • standards/dependabot/backend-rust.yml
  • standards/dependabot/frontend.yml
  • standards/dependabot/fullstack.yml
  • standards/dependabot/infra-terraform.yml
  • standards/workflows/dependabot-automerge.yml
  • standards/workflows/dependency-audit.yml

configured for auto-merge.
5. Create the `security` and `dependencies` labels in the repository if they
don't already exist.
6. Add `dependency-audit` as a required status check in branch protection rules.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Locating dependency-audit workflow..."
fd -i '^dependency-audit\.yml$' | while read -r f; do
  echo "== $f =="
  echo "-- top-level workflow name --"
  rg -n '^name:' "$f"
  echo "-- job keys --"
  rg -n '^[[:space:]]{2}[A-Za-z0-9_-]+:' "$f"
done

echo
echo "Expected result: document the exact check name shown in GitHub branch protection UI (workflow/job check run), not just the file name."

Repository: petry-projects/.github

Length of output: 504


🏁 Script executed:

cat -n standards/dependabot-policy.md | sed -n '165,185p'

Repository: petry-projects/.github

Length of output: 728


🏁 Script executed:

cat -n standards/workflows/dependency-audit.yml | head -80

Repository: petry-projects/.github

Length of output: 3418


Use the exact check-run name Dependency audit / detect in branch protection instructions.

dependency-audit is the filename, not the check-run name. GitHub branch protection requires the actual check-run produced by the workflow, which follows the format {workflow-name} / {job-key}. Since the audit jobs are conditional (only run if the ecosystem is detected), use Dependency audit / detect which always runs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@standards/dependabot-policy.md` at line 176, Update item 6 to use the actual
check-run name produced by the workflow: replace the filename token
`dependency-audit` with the check-run string "Dependency audit / detect" so
branch protection requires the real check-run `{workflow-name} / {job-key}` used
by the audit workflow.

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4

- uses: dtolnay/rust-toolchain@stable
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the current SHA for dtolnay/rust-toolchain stable tag
gh api repos/dtolnay/rust-toolchain/git/refs/tags/stable --jq '.object.sha'

Repository: petry-projects/.github

Length of output: 226


🏁 Script executed:

cat -n standards/workflows/dependency-audit.yml | head -200

Repository: petry-projects/.github

Length of output: 8114


Pin dtolnay/rust-toolchain to a specific commit SHA for consistency with other actions.

All other actions in this workflow use SHA-pinned references (e.g., actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683), but line 161 uses the moving @stable tag. Pinning to a specific commit improves supply chain security.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@standards/workflows/dependency-audit.yml` at line 161, The workflow currently
references dtolnay/rust-toolchain@stable (a moving tag); change that to a
specific commit SHA to match the rest of the workflow. Locate the uses:
dtolnay/rust-toolchain@stable entry and replace the `@stable` tag with the exact
commit SHA (e.g., @<commit-sha>) you want to pin so the action is immutable and
consistent with other actions like actions/checkout; ensure you choose a valid
commit SHA from the dtolnay/rust-toolchain repository.

status=0
while IFS= read -r dir; do
echo "::group::cargo audit $dir"
if ! (cd "$dir" && cargo generate-lockfile 2>/dev/null; cargo audit); then
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Silent stderr suppression may hide meaningful errors.

cargo generate-lockfile 2>/dev/null suppresses all stderr, including legitimate errors (e.g., invalid manifest syntax). Consider logging stderr or checking the exit code explicitly.

Suggested fix
-            if ! (cd "$dir" && cargo generate-lockfile 2>/dev/null; cargo audit); then
+            if ! (cd "$dir" && cargo generate-lockfile --quiet 2>&1 || true; cargo audit); then

Using --quiet reduces noise for expected "lockfile exists" cases while still showing actual errors. The || true ensures cargo audit runs even if generate-lockfile fails (preserving current behavior).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@standards/workflows/dependency-audit.yml` at line 173, Replace the silent
stderr suppression on the cargo generate-lockfile invocation so real errors
aren't hidden: instead of redirecting stderr (2>/dev/null) call cargo
generate-lockfile with --quiet and fall back with || true so cargo audit still
runs; update the command that currently invokes cargo generate-lockfile
2>/dev/null; cargo audit to use cargo generate-lockfile --quiet || true; cargo
audit so legitimate errors surface while preserving current behavior.

@don-petry don-petry merged commit 79d2c36 into main Apr 4, 2026
3 checks passed
don-petry added a commit to petry-projects/broodly that referenced this pull request Apr 4, 2026
* chore: align Dependabot config with security-only standards

Add npm, gomod, and terraform ecosystems to dependabot.yml with
security/dependencies labels. Add dependency-audit workflow for
CI vulnerability scanning. Aligns with petry-projects/.github#9.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update to latest security-only standards (limit:0, improved audit)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add pnpm audit support to dependency-audit workflow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve all dependency audit vulnerabilities blocking CI

- Bump go-chi/chi v5.2.1 -> v5.2.2 (GO-2025-3770 host header injection)
- Add pnpm overrides for 5 transitive vulnerabilities:
  @xmldom/xmldom >=0.8.12, lodash >=4.18.0, tmp >=0.2.4,
  @tootallnate/once >=3.0.1
- Strip template "Copy to..." header comments from workflow files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove pnpm cache from audit job (causes path validation error)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants