Back to path
ExpertLedgerline · Project 12 of 12 ~11h· 6 milestones

Ship it hardened and keep it that way

Continues from the last build: You can detect and respond to attacks, and every layer has automated gates.

Every gate from the last eleven rungs works in isolation. You can run gitleaks by hand and get zero secrets.

GitHub Actions pipeline orchestration and job dependenciesLeast-privilege GITHUB_TOKEN and per-job permissionsCosign keyless signing and signature verification before deployBreak-glass approval design and incident rollback drillsSTRIDE and OWASP Top 10 threat modeling closureVulnerability disclosure process and SLA designSecurity portfolio writing and live demonstration

What you'll build

A single GitHub Actions workflow gates every commit through secret scanning, SAST, dependency scanning, policy-as-code, image build and scan, SBOM and keyless signing, a DAST pass against a live preview, and a signature-verified deploy, in that order, with no path around it except a scoped, approved, audited break-glass lane. The app runs on a managed host that only ever pulls a Cosign-verified image by digest, behind TLS with real security headers, with a rehearsed rollback that restores the last-good signed digest in minutes. The threat model is closed: every original risk is mapped to the control that mitigates it and the CI job that enforces it, with an honest residual-risk list instead of a false all-clear. A security.txt and disclosure policy with a real SLA turn outside reports into gated fixes instead of dead inbox threads. And a README makes the whole thing demonstrable: a pipeline diagram, a before-and-after finding count for every prior rung, an OWASP Top 10 and CI/CD Top 10 coverage matrix, and a script that pushes a known-bad commit and shows it die in CI in under ninety seconds.

See how we teach, before you sign up

You don't just get code dumped on you. Every starter file and every solution is explained line-by-line, in plain English. Here's one real file from this project:

.github/workflows/ship.ymlyaml
name: ship
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  contents: read

jobs:
  secret-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@<PIN_TO_SHA>
      # TODO: gitleaks

  build-scan-sign:
    needs: [secret-scan]
    runs-on: ubuntu-latest
    permissions:
      packages: write
      id-token: write
    steps:
      # TODO: build, trivy image, syft, push, cosign sign

  verify-and-deploy:
    needs: [build-scan-sign]
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
      # TODO: cosign verify then run deploy.sh

Reading this file

  • permissions: contents: readthe least-privilege default every job inherits unless it explicitly asks for more
  • needs: [secret-scan]the build job cannot start until the secret scan has passed, not just run
  • if: github.ref == 'refs/heads/main'restricts the deploy job so no fork or PR can ever reach it
  • packages: writewrite access to the registry granted only on the job that actually needs it

This is intentionally incomplete, add sast, dep-scan, policy, preview-deploy and dast as their own needs-chained jobs before treating this as done.

That's 1 of 9 explained code blocks in this single project.

The build, milestone by milestone

  1. 1

    The end-to-end secure pipeline

    6 guided steps

    Right now each gate runs as its own workflow with no guarantee of order, a developer can merge past a failing SAST job while a separate secret-scan workflow is still green, or push straight to production while the DAST workflow was never wired to the deploy decision at all. Sequencing them into one dependency graph is what turns eight independent scripts into one enforced gate.

  2. 2

    Deploy the signed image

    6 guided steps

    Signing an image is theater if nothing ever checks the signature at the point it matters. Anyone with registry push access, or a leaked long-lived token, can still land an unsigned or tampered image on the host if the deploy path doesn't fail closed on a bad signature, and secrets baked into a layer survive in every registry mirror and every image history forever, long after you rotate the credential.

  3. 3

    Break-glass and rollback

    6 guided steps

    Gates will occasionally block a legitimate emergency fix, a payment outage that needs a hotfix faster than a full DAST pass can run. If there's no approved way to move fast in that moment, people eventually disable the whole pipeline instead, quietly, and it never gets turned back on. And if rollback has never been rehearsed, the first time it's needed for real is the worst possible time to be improvising commands under pressure.

  4. 4

    The full threat model, closed

    6 guided steps

    A threat model written once at the start of the project and never revisited only documents intentions. The whole point of eleven rungs of gates is to close the loop, row by row, and prove which promise is actually enforced by running code today versus which one is still just aspirational from week one.

  5. 5

    A vulnerability disclosure + patch SLA

    5 guided steps

    Scanners only catch the bug classes they were built to catch. Business logic flaws, novel chains, and anything outside a ruleset are far more likely to surface from a report, either a teammate or, on a real product, an outside researcher. Without a published process and a timed SLA, reports have nowhere defined to go and quietly die in an inbox.

  6. 6

    The portfolio writeup

    6 guided steps

    None of the automation from the previous eleven rungs matters as a portfolio piece if nobody can see it work quickly. An interviewer will not read twelve rungs of history, they will watch you push a bad commit and watch it die in CI, that ninety seconds is the entire pitch.

What's inside when you start

3 starter files, ready to clone
6 guided milestones
6 full reference solutions
9 code blocks explained line-by-line
6 "is it working?" checks
6 interview questions it prepares you for

You'll walk away with

.github/workflows/ship.yml, one end-to-end gated pipeline from secret scan through verified deploy
A deployed, signature-verified container on a managed host with TLS and security headers confirmed live
A documented and drilled break-glass path plus a rollback script with an audit log
security/threat-model.md updated with every risk mapped to control, enforcing gate, and an honest residual-risk list
security.txt and disclosure-policy.md with a severity-based SLA table and one simulated report closed end to end
README.md with the pipeline diagram, before/after finding counts, an OWASP/CI-CD Top 10 coverage matrix, and a 90-second demo script

This is portfolio-grade. Build it free.

Sign up to unlock every milestone step-by-step, the code skeletons, full reference solutions, and checkable tasks, with your progress saved as you build.

Start building