Chapter 22Lesson 05~210 minutes

Checkpoint Lab — Dependabot Alerts, Security Updates, Version Updates, Dependency Review, and Policy

The checkpoint treats dependency maintenance as an operating system, not a bot demo. You will bind one exact dependency state to update policy, PR identity, dependency-review evidence, vulnerability signal or safe fixture, human decision criteria, and an explicit exception/credential policy—then retire the disposable automation cleanly.

Checkpoint labEvidence packetPolicy SLAException expirySecure automation

Learning objectives

  • Produce an end-to-end dependency-update evidence packet for one exact PR revision.
  • Distinguish live vulnerability evidence from safe synthetic training data.
  • Write a policy for severity SLAs, grouping, ownership, auto-merge, exceptions, and private registries.
  • Diagnose a Dependabot permission failure without granting production credentials.
  • Clean up the disposable repository while preserving audit evidence.
Checkpoint scope. Use the same public disposable repository from Lesson 2 or create a fresh dependabot-policy-checkpoint. Exact command blocks use Bash/Git Bash; Windows learners may use Git Bash for the checkpoint. No known-vulnerable package, paid product, private registry, secret, or auto-merge is required. If Dependabot has not opened an update PR yet, a clearly labeled human-created simulation is accepted.

1. Scenario and production question

You operate a small service that must keep dependencies current without turning bot output into unreviewed production change. Build an evidence packet that answers: what dependency state exists, what update policy generated/proposed the change, what security signal exists, what exact PR revision was reviewed, which checks passed, who owns the decision, and when any exception expires?

2. Required predictions before execution

  1. Committing dependabot.yml schedules version checks; it does not guarantee an immediate PR and does not enable alerts.
  2. Changing is-number 6.0.0→7.0.0 changes package.json/package-lock.json and the PR head SHA; it should not require repository write permission from dependency review.
  3. A Dependabot-authored PR has different Actions token/secrets behavior from the human simulation PR.
  4. No known-vulnerability alert is intentionally created; a synthetic fixture is used if the repository has no legitimate alert.

3. Preflight and baseline evidence

gh auth status --hostname github.com
REPO="OWNER/dependabot-policy-lab"
gh repo view "$REPO" --json nameWithOwner,visibility,viewerPermission,defaultBranchRef

git status --short
git rev-parse HEAD
node -e 'const p=require("./package-lock.json"); console.log(p.packages["node_modules/is-number"].version)'
gh pr list --repo "$REPO" --author app/dependabot --state all --json number,title,state,author,headRefOid

Record the baseline commit SHA and resolved dependency version. If your repository is not disposable/public or you do not have admin rights for security settings, stop and use the fixture-only policy path.

4. Final update policy

Use a small schedule and bounded PR limit. Keep grouping explicit so reviewers can see it in Git history.

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 2
    labels:
      - "dependencies"
    groups:
      routine:
        applies-to: version-updates
        patterns:
          - "*"
      security-fixes:
        applies-to: security-updates
        patterns:
          - "*"

Security-update grouping in this file has higher priority than repository/organization UI grouping settings for the matching ecosystem. Keep policy changes reviewed like application code.

5. Dependency-review gate

name: Dependency review
on:
  pull_request:
permissions:
  contents: read
jobs:
  dependency-review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 line
        with:
          persist-credentials: false
      - uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
        with:
          fail-on-severity: high

Verify the committed workflow exactly before opening the PR:

git show HEAD:.github/workflows/dependency-review.yml
git show HEAD:.github/dependabot.yml

6. Obtain one update PR and pin the evidence

Prefer a real Dependabot PR if available. Otherwise create the documented simulation.

BOT_PR=$(gh pr list --repo "$REPO" --author app/dependabot --state open --json number --jq '.[0].number // empty')
if [ -n "$BOT_PR" ]; then
  PR="$BOT_PR"
else
  git switch "$(gh repo view "$REPO" --json defaultBranchRef --jq .defaultBranchRef.name)"
  git pull --ff-only
  git switch -c checkpoint/is-number-7
  npm install is-number@7.0.0 --package-lock-only --ignore-scripts
  git add package.json package-lock.json
  git commit -m "Checkpoint: simulate dependency version update"
  git push -u origin HEAD
  gh pr create --repo "$REPO" \
    --base "$(gh repo view "$REPO" --json defaultBranchRef --jq .defaultBranchRef.name)" \
    --head checkpoint/is-number-7 \
    --title "Checkpoint: dependency update 6.0.0 to 7.0.0" \
    --body "Human-created simulation because no Dependabot PR was available yet."
  PR=$(gh pr list --repo "$REPO" --head checkpoint/is-number-7 --json number --jq '.[0].number')
fi

gh pr view "$PR" --repo "$REPO" --json number,title,author,baseRefName,headRefName,headRefOid,files,statusCheckRollup
PR_SHA=$(gh pr view "$PR" --repo "$REPO" --json headRefOid --jq .headRefOid)
printf 'reviewed_pr=%s reviewed_sha=%s\n' "$PR" "$PR_SHA"

7. Security signal: inspect live alerts or use the fixture

set +e
gh api --paginate \
  -H "Accept: application/vnd.github+json" \
  -H "X-GitHub-Api-Version: 2026-03-10" \
  "repos/$REPO/dependabot/alerts?state=open&per_page=100" \
  --jq '.[] | {number,package:.dependency.package.name,severity:.security_advisory.severity,state}'
ALERT_RC=$?
set -e
printf 'alert_query_exit=%s\n' "$ALERT_RC"

If the successful result is empty, record “no returned open alerts at inspection time” and use the synthetic fixture from Lesson 2 for policy triage. Do not claim GitHub/Dependabot proves the entire application is vulnerability-free.

8. Evaluate before merge: changelog, tests, security, and ownership

For the sample update, inspect the PR diff and upstream release metadata, then answer:

  • Is the dependency runtime or development scope?
  • Is this SemVer major/minor/patch?
  • Does dependency review report a vulnerability/license concern?
  • What application test would detect a behavior regression?
  • Who owns the affected code path?
  • If the update is postponed, what is the expiry/review date?
gh pr diff "$PR" --repo "$REPO"
gh pr checks "$PR" --repo "$REPO"
gh pr view "$PR" --repo "$REPO" --comments

The checkpoint does not require merge. A justified “do not merge yet” with preserved evidence is a valid operating decision.

9. Write the dependency policy

Create DEPENDENCY_POLICY.md (or an equivalent governance document) with at least these fields:

Policy field Minimum content
Severity SLA Critical/high response targets; who can declare an exception.
Grouping Which ecosystems/families may be grouped and why.
Review ownership Owners for runtime, auth, data, build, and tooling dependencies.
Auto-merge Exact update classes + required checks + explicit exclusions.
Exception expiry Owner, rationale, compensating control, date for re-evaluation.
Private registries Read-only Dependabot secrets, rotation, no credential in YAML/logs.
Alert dismissal Reason/comment/evidence; no cosmetic dismissal.
Evidence retention PR/head SHA, checks, advisory/alert ID, merge/exception decision.

10. Permission/security failure question

A Dependabot PR triggers a workflow that uploads a production package using an ordinary Actions secret and write-scoped token. The workflow fails because the secret is unavailable and token is read-only. Do not “repair” this by granting Dependabot production publishing credentials. The correct architecture keeps dependency-PR validation read-only; publishing occurs only after trusted merge/release conditions through a separate least-privilege workflow.

11. Independent verification checklist

  • Repository is disposable/public and exact default branch recorded.
  • package-lock.json records the baseline and PR target versions.
  • .github/dependabot.yml parses and uses the intended ecosystem/directory/schedule/grouping.
  • Alerts/security updates feature state was inspected separately from version-update config.
  • PR author and immutable head SHA recorded.
  • Dependency-review check result recorded for that SHA.
  • No ordinary secret value, Dependabot secret, PAT, or registry credential appears in logs/source.
  • Policy records owners, SLAs, auto-merge limits, and exception expiry.

12. Cleanup/rollback

Close any disposable human simulation or Dependabot PR that you do not intend to merge, remove temporary branches, and archive the lab repository. Archiving preserves the evidence without leaving active update automation. If you created a Dependabot private-registry secret in an optional extension, remove/revoke it first.

# Close the current checkpoint PR if it remains open.
gh pr close "$PR" --repo "$REPO" --delete-branch || true

# Close remaining disposable Dependabot PRs if this entire repository is being retired.
for n in $(gh pr list --repo "$REPO" --author app/dependabot --state open --json number --jq '.[].number'); do
  gh pr close "$n" --repo "$REPO"
done

gh repo archive "$REPO" --yes

gh repo view "$REPO" --json nameWithOwner,isArchived --jq '{repo:.nameWithOwner,archived:.isArchived}'

Repository deletion is not required. Do not dismiss alerts or rewrite Git history as “cleanup.” Preserve the learning evidence.

13. Production runbook handoff

  1. Inventory: verify graph freshness/default branch/manifest path.
  2. Signal: triage alert severity + scope + relationship + fix availability.
  3. Proposal: identify Dependabot/human PR and exact head SHA.
  4. Admission: dependency review + tests + owner review.
  5. Decision: merge, defer with expiring exception, or reject.
  6. After merge: monitor, release/deploy via normal governed path.
  7. Review policy quarterly or after a dependency incident.

Knowledge check

Your update PR is green but changes an authentication dependency across a major version. What should policy do?

No open alerts are returned. What is the precise claim you may make?

Why record the PR head SHA?

A Dependabot-triggered workflow cannot publish a package because its token is read-only. What is the safe fix?

What makes an alert exception operationally durable?

Why can a human-created simulated update PR not prove Dependabot secret behavior?

Summary

Chapter 22 adds dependency governance to the production GitHub operating model: resolved dependency inventory, advisory correlation, bounded update generation, pull-request admission checks, explicit bot trust boundaries, expiring exceptions, and review ownership. Dependabot can reduce exposure and maintenance drift only when its proposals remain testable, attributable, and governed.

Chapter 23 moves from dependency risk to repository source-code analysis with CodeQL, code scanning, SARIF, query scope, autofix, and security gates.

Next chapter

CodeQL, Code Scanning, SARIF, Custom Queries, Autofix, and Security Gates: Concepts, Architecture, and Mental Model

Official references

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.