Lesson 05 · GitHub platform · security

Security

GitHub watches your dependencies and your diffs for you — for free, on every repo. Two jobs: catch vulnerable packages already in the repo, and stop secrets from ever landing in it.

You've tracked work with issues, automated checks with Actions, organised it with Projects, and published it with Pages. The last piece: the Security tab, which runs a small set of automated checks against the repo without you writing any workflow YAML for them.

Three tools, two jobs

Dependabot alerts Scans your dependency manifests (package.json, requirements.txt, etc.) against a vulnerability database. Flags packages with known CVEs.
Dependabot security updates When an alert fires, opens a PR that bumps the flagged package to a patched version. You review and merge like any other PR.
Secret scanning + push protection Scans commits for known credential patterns (API keys, tokens). Push protection goes further — it blocks the push before a matching secret ever reaches the repo.

First two are one job: known-vulnerable dependencies. Alerts find them, security updates fix them. Third is a different job: leaked credentials — not a dependency problem, a "someone pasted an API key into code" problem.

Alerts vs. updates — don't confuse them

Dependabot alerts

Passive. Just tells you: "this repo depends on [email protected], which has a known prototype-pollution CVE." Shows up in the Security tab. No code changes.

Always on, can't be disabled per-repo on GitHub Free for public repos

Dependabot security updates

Active. Opens an actual PR bumping the version, with the CVE explained in the PR description. You still review and merge it — nothing auto-merges.

Opt-in, toggled separately in repo Settings → Code security

Push protection — the one that runs before the fact

Secret scanning normally works like the others: after the fact, scan what's already in the repo, alert you. Push protection is different in kind — it runs at git push time. If a commit contains something matching a known secret pattern (an AWS key, a Stripe token, a GitHub PAT, dozens more), the push is rejected outright, with the offending line and file named in the error.

Why this matters more than the others A leaked secret is often worse than a vulnerable dependency — it's an immediate, exploitable credential, not a theoretical CVE. And once a secret is pushed, it's in git history forever unless you rewrite it (see the undo playbook — this is exactly the kind of mistake that lesson covers, but prevention beats cleanup). Push protection stops the secret from ever landing, which is strictly better than the best possible cleanup afterward.

What's not covered here

The Security tab also surfaces code scanning (CodeQL — static analysis that finds bugs like SQL injection or XSS in your own code, not just dependencies). It's real and useful, but setup and custom queries are deep enough to be their own lesson — this course covers it at awareness level only: it exists, it's in the same tab, revisit if a real need shows up.

How this connects

Security closes the loop differently than Pages did — it's not a new output, it's a backstop across everything else:

Your win — check the real repo's security posture
  1. Go to the Security tab on this repo.
  2. Open Settings → Code security and confirm Dependabot alerts and secret scanning are enabled (public repos get these on by default).
  3. Toggle on Dependabot security updates and push protection if either is off.
  4. Back on the Security tab, check the alerts list — this workspace has no dependency manifests, so expect it empty. That itself is worth confirming, not assuming.
Nothing to fix today — the win is knowing where to look and having the backstop switched on before you ever need it.

Go deeper

Primary source — read this one: GitHub Docs — GitHub security features. The full map: Dependabot, secret scanning, code scanning, and how they fit together.

Then configure it: GitHub Docs — About secret scanning. Covers push protection setup in detail.