Production Capstone: Govern a GitHub Organization and Build a Secure End-to-End Delivery System: Final Operational Review and Handoff
Operate the complete disposable delivery system, prove critical invariants independently, assemble the final evidence and runbook handoff, clean up safely, and assess operational maturity.
Learning objectives
- Run the end-to-end issue-to-release model as an operator handoff and prove critical invariants with independent evidence.
- Complete at least four controlled failures spanning access, CI/security, release/provenance, and automation, then verify recovery.
- Assemble architecture, policy, workflow, credential, provenance, evidence, runbook, cost, and cleanup deliverables for another operator.
- Hash the evidence packet and state precisely what each proof establishes and what remains outside its scope.
- Assess operational maturity and identify the boundaries where deeper GitHub Actions, CI/CD, DevSecOps, cloud, Kubernetes, and GitOps study continues.
1. Final mission and preflight
The final checkpoint is not “create the repository again.” It is an operator handoff: another engineer should be able to understand the architecture, identify the allowed change/release paths, reproduce verification, respond to the four mandatory failure classes, and know what must be cleaned up.
-
Required local tools: Git, GitHub CLI, Python 3,
Node.js/npm,
sha256sum, and GNUtar/gzipfor the demonstrated deterministic archive. - GitHub account: GitHub.com personal account able to create a disposable public repository and use Actions/security features available to public repositories.
- Safety: no real credential, production repository, employer organization, self-hosted runner, cloud account, or private package is needed.
- Optional organization extension: use only an organization you own for training; do not invite real coworkers merely to satisfy the lab.
- Before destructive cleanup: export final evidence first. Repository deletion, tag force-update, history rewrite, package deletion, token creation, and policy bypass are not required.
2. Handoff architecture and threat model
flowchart TD REQ[Issue / requirement] --> PR[PR + review] PR --> GATE[Ruleset + verify] GATE --> MAIN[main SHA] MAIN --> REL[Manual release-evidence] REL --> BYTES[artifact + SHA-256] REL --> PROV[attestation / OIDC identity] BYTES --> RELEASE[GitHub Release] PROV --> VERIFY[consumer verification] RELEASE --> VERIFY SEC[Dependabot / CodeQL / secret protection] --> PR API[Read-only API evidence] --> EVID[Evidence packet] PR --> EVID GATE --> EVID REL --> EVID VERIFY --> EVID OPS[Runbooks / owners / exceptions] --> EVID
The operating model has one normal change path and one release path. Security automation feeds change decisions; it does not silently merge or deploy. Release bytes and provenance converge only at consumer verification. Evidence is collected from each control plane, and the runbook/owner layer explains how humans operate exceptions and incidents.
Threats considered include malicious/unreviewed source, workflow privilege escalation, compromised dependency, leaked credential, bypass abuse, runner/network compromise, artifact substitution, stale access after offboarding, incomplete API inventory, and cost pressure that encourages bypass. No single GitHub feature eliminates these threats; the model uses layered prevention, detection, verification, and recovery.
3. Required handoff inventory
| Deliverable | Minimum contents |
|---|---|
| Architecture | Diagram, repository/organization assumptions, trust boundaries, external systems, release flow. |
| Repository/team policy | Ownership model, roles/teams or free-path fixture, ruleset target/check, review and emergency rules. |
| Workflow design | Pinned actions, triggers, concurrency, job-level permissions, hosted-runner rationale, no implicit long-lived credential. |
| Credential design | GITHUB_TOKEN scope, attestation OIDC use, optional external OIDC trust requirements, real-secret incident procedure. |
| Security baseline | Dependabot policy, CodeQL state, secret scanning/push protection path, ownership for findings/dismissals. |
| Release/provenance | Source SHA, tag, artifact SHA-256, attestation verification policy, optional package digest strategy. |
| Runbooks | Ruleset deadlock, credential leak, runner compromise, failed release/provenance mismatch, access residual, automation partial inventory. |
| Evidence inventory | Repository/ruleset/PR/workflow/release/attestation evidence plus evidence-manifest hashes and capture time. |
| Cost notes | Runner class, run duration/concurrency approach, cache/artifact retention, review cadence and owner. |
| Cleanup | Local files/branches, synthetic issues, optional settings rollback, archive/delete decision, confirmation no lab credential exists. |
4. Run at least four controlled failures
| Mandatory class | Injection | Expected diagnosis/recovery proof |
|---|---|---|
| Access | Synthetic former maintainer retains direct write after team removal. | Access checker fails → direct grant removed in fixture → checker passes; enumerate additive paths. |
| CI/security |
Ruleset requires verify while path filter
prevents it from being created.
|
No bypass; preserve PR/ruleset evidence → repair trigger/gate contract → same ruleset succeeds. |
| Release/provenance | Append bytes to copied artifact. |
SHA differs and gh attestation verify fails;
legitimate original still verifies.
|
| Automation | API inventory requests only first item/page. | Independent issue list disproves completeness → paginated query returns full scope. |
Optionally add the runner-authority and credential-response fixtures from Lesson 4. Record actual detection/containment/recovery timestamps and residual risk for each drill.
5. Prove critical invariants independently
A production handoff should not say “the pipeline was green.” Prove at least these five invariants from different evidence surfaces:
# Invariant 1 — release tag resolves to the exact source commit.
TAG="v0.1.0-capstone"
RELEASE_SHA="$(gh api -H "X-GitHub-Api-Version: 2026-03-10" "repos/$FULL/git/ref/tags/$TAG" --jq .object.sha)"
printf 'tag_sha=%s\n' "$RELEASE_SHA"
# Invariant 2 — the expected ruleset is active and has no unintended bypass actor.
gh api -H "X-GitHub-Api-Version: 2026-03-10" "repos/$FULL/rulesets" --jq '.[] | select(.name=="capstone-main") | {id,name,enforcement,bypass_actors,rules}'
# Invariant 3 — workflow at release SHA is deny-by-default with job-local authority.
gh api -H "X-GitHub-Api-Version: 2026-03-10" -H 'Accept: application/vnd.github.raw+json' "repos/$FULL/contents/.github/workflows/capstone.yml?ref=$RELEASE_SHA"
# Invariant 4 — artifact bytes match recorded digest and trusted attestation policy.
cd release-download
sha256sum -c capstone.tar.gz.sha256
gh attestation verify capstone.tar.gz --repo "$FULL" --signer-workflow "$FULL/.github/workflows/capstone.yml" --source-ref refs/heads/main --deny-self-hosted-runners --format json
cd ..
# Invariant 5 — the release record exposes the expected tag/assets.
gh release view "$TAG" -R "$FULL" --json tagName,targetCommitish,url,assets
# Invariant 6 — no repository-scoped Actions secret was created for this lab.
# This does NOT prove absence of org/environment/Dependabot/Codespaces secrets.
gh secret list -R "$FULL"
The sixth check is intentionally scoped: an empty repository secret list is not a universal “no secrets exist” proof. Evidence must describe what it can and cannot establish.
6. Assemble the final evidence packet
mkdir -p handoff/final
printf '%s\n' "$RELEASE_SHA" > handoff/final/release-source-sha.txt
sha256sum release-download/capstone.tar.gz > handoff/final/release-artifact.sha256
gh repo view "$FULL" --json nameWithOwner,visibility,defaultBranchRef,url > handoff/final/repository.json
gh api -H "X-GitHub-Api-Version: 2026-03-10" "repos/$FULL/rulesets" > handoff/final/rulesets.json
gh pr list -R "$FULL" --state all --limit 100 --json number,title,state,headRefOid,mergeCommit,url > handoff/final/pull-requests.json
gh run list -R "$FULL" --limit 100 --json databaseId,workflowName,event,headSha,status,conclusion,createdAt > handoff/final/workflow-runs.json
gh release view "$TAG" -R "$FULL" --json tagName,targetCommitish,url,assets > handoff/final/release.json
gh attestation verify release-download/capstone.tar.gz --repo "$FULL" --signer-workflow "$FULL/.github/workflows/capstone.yml" --source-ref refs/heads/main --deny-self-hosted-runners --format json > handoff/final/attestation.json
python - <<'PY'
from pathlib import Path
import hashlib, json, datetime
root=Path('handoff/final')
rows=[]
for f in sorted(root.glob('*')):
if f.is_file():
rows.append({'file':f.name,'bytes':f.stat().st_size,'sha256':hashlib.sha256(f.read_bytes()).hexdigest()})
out={'captured_at_utc':datetime.datetime.now(datetime.timezone.utc).isoformat(), 'files':rows}
Path('handoff/final-manifest.json').write_text(json.dumps(out,indent=2)+'\n')
PY
cat handoff/final-manifest.json
For an eligible organization, add a narrowly time-bounded audit-log export/API query and store it outside the account under investigation according to retention policy. In this personal free lab, the packet remains honest about the absence of enterprise audit evidence.
7. Final incident runbook index
| Incident | First containment | Recovery evidence |
|---|---|---|
| Credential leak | Revoke/rotate first; preserve alert/source evidence. | Old credential unusable; consumers migrated; exposed surfaces removed; rewrite decision recorded. |
| Ruleset deadlock | Freeze merge; inspect rule/check interaction. | Normal required check restored; no lingering bypass; ruleset Active. |
| Runner/workflow compromise | Stop affected execution; isolate authority/network; revoke reachable credentials. | Trusted rerun; permission/network repair; artifact identities compared. |
| Failed release | Stop promotion; identify last known-good source/artifact. | New coherent release or rollback points to verified digest/provenance. |
| Residual access | Enumerate every additive path. | Effective access independently shows intended role; direct/team/app/key paths reviewed. |
| Automation corruption | Stop mutation client; preserve request/response/idempotency evidence. | Complete paginated inventory; duplicate protection/idempotence verified. |
8. Cleanup and rollback
The mandatory exercise did not create a PAT, App key, cloud credential, self-hosted runner, or private package, so there is no hidden credential cleanup step. Finish with evidence export, local cleanup, and repository disposition.
# Close only synthetic open issues you created for the automation drill.
gh issue list -R "$FULL" --state open --limit 100 --json number,title --jq '.[] | select(.title | startswith("automation-fixture-")) | .number' | while read -r n; do gh issue close "$n" -R "$FULL" --comment "Disposable capstone cleanup"; done
# Verify no repository-scoped Actions secrets were created by this lab.
gh secret list -R "$FULL"
# Preserve the local handoff outside the repository if desired, then remove temp files.
rm -f /tmp/capstone-tampered.tar.gz /tmp/access-fixture.json
# Safe default: archive the disposable hosted repository instead of deleting it immediately.
gh repo archive "$FULL" --yes
gh repo view "$FULL" --json nameWithOwner,isArchived,visibility,url
9. Operator handoff checklist
- Architecture diagram names every trust boundary and optional external system.
- Repository ownership, team/role model, review rule, ruleset target, required check name, and emergency authority are documented.
- Workflow triggers, runner class, action pins, job permissions, OIDC usage, concurrency, and retention are documented.
- Release policy names source SHA, tag/version semantics, artifact digest, attestation policy, and rollback identity.
- Security findings have owners, severity/remediation rules, dismissal authority, and exception expiry.
- Credential incident runbook starts with revoke/rotate and covers non-Git exposure surfaces.
- At least four failure-drill records contain times, evidence, correction, verification, residual risk, and preventive owner.
- Evidence packet is hashed and stored according to retention/chain-of-custody needs.
- Cost/performance review has metrics and a responsible owner; optimization cannot remove the stable required gate invisibly.
- Cleanup confirms no lab credential exists and records archive/deletion disposition.
10. Operational maturity review and course bridge
| Maturity level | Observable behavior |
|---|---|
| Configured | Features are enabled, but owners/evidence/recovery assumptions are unclear. |
| Controlled | Normal paths have least privilege, review, required checks, and release identity. |
| Observable | Critical controls emit structured evidence; inventories are complete/paginated; consumers verify provenance. |
| Recoverable | Failure drills are timed, containment order is correct, rollback and emergency procedures are tested. |
| Evolving | Metrics, incidents, cost, policy drift, and platform changes feed a prioritized improvement backlog. |
Completing this capstone does not replace deeper specialist study. The dedicated GitHub Actions, GitLab, CI/CD, artifact management, DevSecOps, cloud, Kubernetes, and GitOps courses go further into their own execution models and operational depth. What this GitHub course adds is the platform-level mental model needed to connect those systems safely.
Capstone review questions
A PR is blocked because the required verify check
never appears after adding path filters. Which two controls are
interacting, and what is the preferred repair?
The ruleset requires a named check while the workflow trigger prevents that check from being created. Preserve evidence, keep the ruleset, restore an always-created aggregate verify check, and put selective expensive work inside the workflow.
A release tag points to SHA A, the package digest is B, and the attestation subject is C. What should the release operator do?
Stop promotion and reconcile identities. Do not move the old tag or waive verification. Establish which bytes were built from which source and publish a new coherent version or roll back to a known-good source/artifact pair.
A real API token is found in history. The security engineer proposes rewriting Git immediately. What is missing?
Immediate revocation/rotation and usage assessment. History cleanup cannot invalidate a credential already copied, so containment starts at the credential provider.
An offboarded user was removed from the engineering team but can still push. What should be inspected?
All additive access paths: direct collaborator role, other/nested teams, base permission, App installations, deploy keys/tokens, and enterprise identity state. Team removal alone is not proof of effective access removal.
Why does the capstone verify attestations at the consumer boundary instead of only generating them in CI?
Unverified attestations do not constrain consumption. Consumer-side policy proves the bytes match a trusted repository/workflow/ref/runner identity at the point the artifact is accepted.
Would switching every job to a large runner be a valid reliability fix for slow CI?
Not by default. Measure the bottleneck first. Larger runners can increase cost without fixing dependency, matrix, cache, queue, or path-selection problems and can create pressure to weaken controls later.
The repository secret list is empty. Can the handoff claim “there are no secrets”?
No. That command proves only the repository-scoped Actions secret inventory it queried. Environment, organization, Dependabot, Codespaces, external provider, or machine credentials require separate evidence.
Which five independent proofs most directly demonstrate the final delivery invariant?
Exact release tag/source SHA, active intended ruleset/no unintended bypass, workflow least-privilege definition at the source SHA, artifact digest plus trusted attestation verification, and release metadata/assets matching the intended release identity. Additional evidence strengthens the case.
Final summary
The GitHub course closes with an operating system, not a checklist of features: requirements precede controls; identities have bounded authority; source change, execution, release, provenance, and evidence are separate planes; public/free capabilities provide a complete learning path; enterprise controls are labeled rather than fabricated; and recovery is tested under interacting failures. The final handoff gives the next operator enough evidence to secure, audit, recover, and evolve the platform.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.