diff --git a/certifications/github/gh-100/admin-playbook.md b/certifications/github/gh-100/admin-playbook.md
new file mode 100644
index 0000000..f5138b7
--- /dev/null
+++ b/certifications/github/gh-100/admin-playbook.md
@@ -0,0 +1,482 @@
+---
+title: "GH-100 - Admin Playbook"
+description: "Real-world GitHub administration scenarios, troubleshooting steps, and decision frameworks for enterprise admins"
+head:
+ - - meta
+ - name: keywords
+ content: gh-100, admin playbook, scenarios, troubleshooting, decision framework, github administration, enterprise
+---
+
+# GH-100: Admin Playbook
+
+[← Overview](./index.md) · [Concept Map →](./concept-map.md) · [Tools Reference →](./tools-reference.md) · [Exam Guide →](./exam-guide.md)
+
+::: info Real-World Scenarios for Enterprise Admins
+These scenarios test your ability to **synthesize knowledge across domains** and make decisions under pressure. Each walkthrough shows the decision tree, troubleshooting steps, and links to relevant study material.
+:::
+
+---
+
+## Scenario 1: SAML SSO Enforcement Breaks Team Access
+
+**Situation**: You enforce SAML SSO on your enterprise account. The next morning, 15% of your workforce cannot log in. You have 30 minutes to restore access before the daily standupd.
+
+### Symptom
+- Users see: "SAML authentication failed" or "Your identity provider rejected the authentication request"
+- Some users can log in; others cannot
+- Team sync shows green, but users claim they can't access repos
+
+### Diagnosis Checklist
+- [ ] **Step 1: Check IdP health** — Is your SAML provider (Okta, Azure AD, etc.) online? Check status page.
+- [ ] **Step 2: Verify SAML assertion format** — Does your IdP send the `NameID` field? GitHub requires it.
+- [ ] **Step 3: Check GitHub's SAML log** — Go to Enterprise Settings → Authentication & Authorization → View SAML log. Look for assertion errors.
+- [ ] **Step 4: Confirm ACS URL** — Is the Assertion Consumer Service (ACS) URL correct? Typo = silent rejection.
+- [ ] **Step 5: Review user attributes** — Are users linked to existing GitHub accounts? New SAML users need pre-existing GitHub accounts (unless EMU).
+
+### Quick Fixes (in order of likelihood)
+1. **Wrong ACS URL**: Regenerate SAML certificate, copy the correct ACS URL from GitHub, update IdP
+2. **Missing NameID**: Configure IdP to send NameID in SAML assertion (not just email)
+3. **Certificate expired**: Regenerate SAML certificate in GitHub (Enterprise Settings → SAML)
+4. **IdP assertion size too large**: Some IdP attribute mappings bloat the assertion → remove unused attributes
+
+### Decision Tree
+```
+All users failing? → Check IdP status + ACS URL
+Only new/recent hires failing? → Check user account linking
+Some users specific to a team failing? → Check team sync + IdP group membership
+```
+
+### Mitigation
+- **Disable SAML enforcement temporarily** (uncheck "Require SAML authentication") to unblock users while you investigate
+- **Use a test user account** to replicate the error and debug
+- **Escalate to GitHub Support** if SAML log shows "Assertion invalid" with no clear reason
+
+### Related Study Material
+- [Domain 2: User Identities & Authentication](./domain-2.md) — SAML SSO configuration
+- [Exam Guide: Identity Decision Trees](./exam-guide.md#which-identity--authentication-approach)
+
+---
+
+## Scenario 2: Secrets Leaked in a Public Repository (Brand Damage Control)
+
+**Situation**: A developer accidentally commits a GitHub Personal Access Token (PAT) to a public repo. The commit is already on main for 2 hours. You need to minimize exposure.
+
+### Immediate Actions (First 5 Minutes)
+1. **Revoke the token immediately** — GitHub Personal Settings → Tokens → delete the exposed token
+2. **Alert the organization** — Notify security team, don't announce publicly yet
+3. **Check if GitHub detected it** — Go to repo → Security → Secret scanning alerts. If GitHub's partner network detected it, GitHub may have already notified the token issuer to revoke it
+
+### Remediation Steps
+
+#### Step 1: Scrub History (Choose One Approach)
+```bash
+# Option A: BFG Repo Cleaner (RECOMMENDED - faster)
+bfg --replace-text passwords.txt my-public-repo.git
+# OR
+# Option B: git filter-branch (legacy but works)
+git filter-branch --force --index-filter \
+ 'git rm --cached --ignore-unmatch ghp_xxxxx' \
+ --prune-empty --tag-name-filter cat -- --all
+```
+
+**Why BFG over filter-branch?**
+- BFG is 10-100x faster on large repos
+- Simpler syntax, lower risk of mistakes
+- GitHub Support recommends it
+
+#### Step 2: Force-Push Cleaned History
+```bash
+git push origin --force-with-lease
+git push origin --force-with-lease --tags
+```
+
+::: warning Coordination Required
+Everyone who cloned the repo must re-clone after the force-push. Notify your team in advance.
+:::
+
+#### Step 3: Verify the Secret Is Gone
+```bash
+# Search repo history for any remaining trace
+git log -p --all -S "ghp_" | head -20
+# Result should be empty
+```
+
+#### Step 4: Audit & Recover
+- **Check audit logs**: Enterprise Settings → Audit log. Search for token creation/deletion. Who had access?
+- **Review recent deployments**: Did this token deploy anything? Audit those environments.
+- **Rotate related secrets**: If the PAT accessed AWS keys or databases, rotate those too.
+
+### Decision Tree
+```
+Secret is < 1 hour old?
+ → Revoke + BFG + force-push (likely minimal exposure)
+Secret is > 24 hours old?
+ → Revoke + BFG + assume compromise (audit all systems the token touched)
+Secret is in a private repo (not public)?
+ → Revoke + BFG (lower urgency, check audit logs for who accessed it)
+```
+
+### Prevention for Future
+- Enable **push protection** to block commits with secrets *before* they enter the repo (enabled at org level)
+- Enable **secret scanning** to alert on detected secrets
+- Use **environment secrets** for production deployments (scoped, require approvals)
+- Prefer **GitHub Apps** over PATs for machine accounts (Apps have short-lived tokens, no expiry gotchas)
+
+### Related Study Material
+- [Domain 5: Secret Scanning & History Scrubbing](./domain-5.md#scrubbing-sensitive-data-from-git-history)
+- [Domain 5: Push Protection vs Secret Scanning](./domain-5.md#push-protection)
+- [Cheatsheet: Token Types](./cheatsheet.md#token-types)
+
+---
+
+## Scenario 3: Migrating from GitHub Enterprise Server (GHES) to GitHub Enterprise Cloud (GHEC)
+
+**Situation**: Your organization is sunsetting on-premises GHES and migrating to GHEC. You have 100 repos, 500 users, and 3 months to complete the migration without downtime.
+
+### Pre-Migration Assessment (Week 1)
+
+#### Inventory & Dependencies
+- [ ] List all repos, their size, and recent commit activity
+- [ ] Document all self-hosted runners — will these migrate to GitHub-hosted or new self-hosted?
+- [ ] Audit all GitHub Apps and OAuth apps — check if they're GHES-compatible on GHEC
+- [ ] Identify any GHES-only configuration (e.g., custom authentication, appliance-specific features)
+
+#### Identity Strategy Decision
+```
+Question: How should users authenticate on GHEC?
+
+If current GHES uses LDAP:
+ → GHEC doesn't support LDAP directly
+ → Options:
+ (A) Migrate to SAML SSO + SCIM + Team Sync
+ (B) Enable EMU (Enterprise Managed Users) for full company-control
+ (C) Switch to OAuth with existing IdP
+
+Recommendation: SAML + SCIM (most common, most control)
+```
+
+#### Capacity Planning
+- **License seats**: GHEC is metered by user. Audit inactive users and remove them before migration.
+- **Data volume**: GHEC has limits on repo size and API rate limits. Test with largest repos first.
+- **Network egress**: Moving large repos off-premises = data transfer costs. Plan for this.
+
+### Migration Plan (Phased Approach)
+
+#### Phase 1: Pilot (Week 2-3)
+- Migrate 3 small repos and 50 volunteers to GHEC
+- Test SAML SSO with a subset of users
+- Verify CI/CD workflows run on GitHub-hosted runners
+- Validate team structure and permissions mapping
+
+#### Phase 2: Parallel Run (Week 4-8)
+- Migrate 40% of repos to GHEC
+- Mirror activity between GHES and GHEC (optional: use GitHub Sync tool or custom scripts)
+- Monitor performance, API usage, rate limits
+- Collect user feedback on workflows
+
+#### Phase 3: Cutover (Week 9-12)
+- Final sync of remaining repos
+- Turn off GHES (or put in read-only mode)
+- Celebrate! 🎉
+
+### Key Decisions During Migration
+
+| Decision Point | GHES Approach | GHEC Approach | Recommendation |
+|---|---|---|---|
+| **User accounts** | LDAP + local users | SAML + SCIM (or EMU) | SAML + SCIM for smooth transition |
+| **CI/CD runners** | Self-hosted (on-prem) | GitHub-hosted or new self-hosted | Evaluate: GitHub-hosted faster? Or keep self-hosted for security? |
+| **Webhooks/Integrations** | Update each app's endpoint | Re-register webhooks on GHEC | Plan webhook re-registration |
+| **Data storage** | On-premises (AWS/Azure for large) | GitHub-hosted (no alternative) | Accept GitHub hosting; audit compliance needs |
+
+### Troubleshooting Common Issues
+
+**Issue**: "Users can't log in after SAML setup"
+- **Cause**: ACS URL misconfiguration, missing NameID in assertion, or users don't exist on GHEC yet
+- **Fix**: See [Scenario 1](#scenario-1-saml-sso-enforcement-breaks-team-access)
+
+**Issue**: "Repo history is incomplete after migration"
+- **Cause**: Shallow clone during migration, or large file filtering
+- **Fix**: Re-push with full history: `git push --mirror` instead of selective push
+
+**Issue**: "CI/CD pipeline slower on GitHub-hosted runners"
+- **Cause**: GitHub-hosted runners are shared; on-prem runners had dedicated hardware
+- **Fix**: Test runner class (macOS, Windows, Linux with different specs) or use self-hosted runners
+
+### Related Study Material
+- [Domain 3: Deployment & Licensing (GHEC vs GHES)](./domain-3.md)
+- [Domain 2: Identity Management (SAML + SCIM)](./domain-2.md)
+- [Domain 6: Runners (GitHub-hosted vs self-hosted)](./domain-6.md)
+
+---
+
+## Scenario 4: Enforcing a Least-Privilege Permission Model Across 50 Teams
+
+**Situation**: Your enterprise has grown to 8 organizations, 50 teams, and 200 repositories. Permission creep is real — many people have `admin` access who only need `write`. You need to audit and enforce least privilege without disrupting teams.
+
+### Step 1: Audit Current State
+
+#### Repository Permissions Audit
+```bash
+# Using GitHub CLI (gh)
+for org in org1 org2 org3; do
+ gh repo list $org --limit 1000 --json name,repositoryTopics --template '{{range .}}{{.name}}{{"\t"}}{{end}}{{"\n"}}'
+done
+# Then manually inspect each repo's Manage Access tab
+# OR use GitHub API to export via Python/Script
+```
+
+#### Find Over-Privileged Users
+1. Go to Organization Settings → Members
+2. Sort by role (Owner, Member)
+3. Identify **Owners who should be Members** (only product leads and principal engineers should be Owners)
+4. Document which users have admin access on repos (check each repo's Manage Access tab)
+
+#### Check Outside Collaborators
+- Outside Collaborators should have **repo-level access only**, not org-level access
+- Verify they're linked to specific repos, not blanket org membership
+
+### Step 2: Define Permission Levels
+
+Create a policy document:
+
+| Team | Repo Access | Permission | Rationale |
+|---|---|---|---|
+| Developers (IC) | Feature repo | `write` | Can merge own PRs, cannot delete repo |
+| Developers (Senior/Lead) | Feature repo | `maintain` | Can manage branch protection, deploy, but cannot delete repo |
+| DevOps / Release | Deployment repo | `admin` | Can configure CI/CD, manage deployments, rotate secrets |
+| Security | All repos | `maintain` (audit-only) | Can view, comment, audit; cannot merge/push |
+| Product | Feature repo | `triage` | Can label, assign, close issues; cannot push |
+
+::: tip Principle
+**Read** < **Triage** < **Write** < **Maintain** < **Admin**
+
+Default to Read; elevate only when necessary.
+:::
+
+### Step 3: Implement the Model
+
+#### Option A: Team-Based Access (Recommended for Scaling)
+1. Create teams aligned to **function**, not project:
+ - `@backend-core` (write to backend repo)
+ - `@devops-core` (admin on deployment repos)
+ - `@security-audit` (maintain on all repos)
+
+2. Grant teams permissions at repo level (not per-user)
+
+3. Use **branch protection rules** to enforce code review even if user has write access
+
+#### Option B: Role-Based Access Control (RBAC) Using Custom Roles (Enterprise Only)
+Enterprise accounts can define custom repository roles:
+1. Go to Enterprise Settings → Roles
+2. Create roles: `Backend Engineer`, `Release Manager`, `Security Reviewer`
+3. Assign users to roles; roles grant specific permissions
+
+#### Automate Role Assignment
+Use **GitHub API** to:
+```bash
+# Add user to team
+gh api -X POST /orgs/$ORG/teams/$TEAM/memberships/$USERNAME --input -
+
+# Assign team to repo with permission level
+gh api -X PUT /repos/$ORG/$REPO/teams/$TEAM --input '{"permission":"write"}'
+```
+
+### Step 4: Audit & Enforce
+
+#### Monthly Permission Review
+```bash
+# Export org members and permissions
+gh org-permissions export --org $ORG --output members.csv
+
+# Identify outliers: users with admin who shouldn't
+```
+
+#### Implement Governance
+- **Branch protection rules**: Require PR review even for repo maintainers (prevents accidental force-push)
+- **Enterprise policy**: Set org-level policies (e.g., "only owners can create new teams")
+- **Audit logging**: Monitor `Repository role changed` events in org audit log
+
+### Decision Tree
+```
+User asks for repo admin access?
+ → Verify: Is this a deployment automation? (Yes → maintainer OK)
+ → Verify: Is this a one-time need? (Yes → provide temporary access)
+ → Default: Offer write or maintain instead
+
+Team consistently needs admin on multiple repos?
+ → Create a dedicated DevOps/Platform team
+ → Grant that team admin on shared repos
+```
+
+### Related Study Material
+- [Domain 4: Access & Permissions](./domain-4.md)
+- [Domain 4: Repository Permission Levels](./domain-4.md#repository-permission-levels)
+- [Cheatsheet: Least Privilege](./cheatsheet.md#admin-core-principles-slg)
+- [Exam Guide: Enterprise vs Org Policies](./exam-guide.md#what-should-be-done-first)
+
+---
+
+## Scenario 5: GitHub Actions Security Lockdown (Secrets, Runners, and Deployment Gates)
+
+**Situation**: Your CI/CD pipeline runs 500+ workflows daily. You've had two incidents:
+1. A script accidentally logged a database password to build logs (caught by secret scanning, but scary)
+2. A self-hosted runner was used by a malicious PR, exposing AWS credentials to an external contributor
+
+You need to enforce guardrails without breaking the development experience.
+
+### Step 1: Secrets Security
+
+#### Audit Current Secrets
+```bash
+# List all secrets in an org (requires REST API call)
+curl -H "Authorization: token $GH_TOKEN" \
+ "https://api.github.com/orgs/$ORG/actions/secrets" | jq '.secrets[].name'
+```
+
+#### Implement Secret Rotation Policy
+- **Database passwords**: Rotate every 90 days
+- **API keys**: Rotate every 30 days
+- **Cloud credentials (AWS, GCP, Azure)**: Rotate every 15 days
+- **GitHub PATs**: Rotate every 90 days
+
+#### Use OIDC Federation (Preferred for Cloud Credentials)
+Instead of storing AWS_ACCESS_KEY_ID as a GitHub secret:
+```yaml
+# Workflow with OIDC (no stored credentials)
+- name: Configure AWS credentials
+ uses: aws-actions/configure-aws-credentials@v4
+ with:
+ role-to-assume: arn:aws:iam::$ACCOUNT:role/GitHubActionsRole
+ aws-region: us-east-1
+```
+
+**Benefit**: GitHub generates short-lived (1 hour) STS tokens. No long-lived secrets to rotate.
+
+#### Restrict Secret Access
+1. Go to Organization Settings → Secrets
+2. For sensitive secrets (database passwords), restrict to **specific repos only** or **specific environments only**
+3. Do NOT use organization-level secrets for prod credentials (too broad)
+
+### Step 2: Self-Hosted Runner Security
+
+#### Risk Assessment
+- **Public repos**: NEVER use self-hosted runners (external PRs can access secrets + runner hardware)
+- **Private repos**: OK to use self-hosted runners, but isolate them
+
+#### Implementation
+1. **Create runner groups** (Organization Settings → Actions → Runners):
+ - `prod-runners` (restricted to deployment repos only)
+ - `internal-runners` (available to all internal repos)
+ - Do NOT allow public repos to use any self-hosted runner
+
+2. **Use machine-type filtering**:
+ ```yaml
+ # Workflow file
+ runs-on: [self-hosted, prod, linux] # Only runs on labeled self-hosted runners
+ ```
+
+3. **Keep runners updated**:
+ ```bash
+ # Self-hosted runner machines
+ sudo apt update && sudo apt upgrade -y # Weekly
+ ```
+
+4. **Monitor runner usage**:
+ - Go to Organization Settings → Actions → Runners
+ - Check "Recent workflow runs" — identify unusual activity
+ - Alert on: unexpected external PR using self-hosted runner
+
+### Step 3: Deployment Gates
+
+#### Use GitHub Environments
+```yaml
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ environment:
+ name: production
+ url: https://example.com
+ steps:
+ - run: echo "Deploying to production"
+```
+
+#### Configure Environment Protection Rules
+1. Go to Repository Settings → Environments → Add "production"
+2. Set **Required Reviewers**: 2 senior engineers (deploys require approval)
+3. Set **Deployment Branches**: Only main can deploy to production
+4. Set **Deployment Protection Rules**: "Previous deployment must succeed before deploying"
+
+#### Use Deployment Keys (Not PATs)
+For automated deployments, create a **Deploy Key** (repository-scoped SSH key):
+```bash
+# Generate deploy key
+ssh-keygen -t ed25519 -f deploy_key -C "deployment"
+
+# Add to repo (Settings → Deploy keys)
+# Use in workflow:
+- name: Deploy
+ env:
+ DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
+ run: |
+ mkdir -p ~/.ssh
+ echo "$DEPLOY_KEY" > ~/.ssh/id_ed25519
+ chmod 600 ~/.ssh/id_ed25519
+ git clone git@github.com:org/repo.git
+```
+
+**Why Deploy Keys?**
+- Scoped to one repo only (not org-wide like PAT)
+- Cannot access organization resources
+- Easier to audit (search repo → Deploy keys)
+
+### Step 4: Audit Logging
+
+#### Monitor Actions Activity
+```bash
+# Check if OIDC was used vs secrets
+# Audit log entry: "Workflow run deployed" with "token_type": "oidc" vs "secret"
+```
+
+#### Red Flags to Monitor
+- [ ] Self-hosted runner executing pull request from external user
+- [ ] Deployment to production without required approvals (check audit log)
+- [ ] Secret creation/rotation by non-admin user
+- [ ] Runner group permissions expanded to public repos
+
+### Decision Tree
+```
+Cloud authentication in Actions?
+ → Use OIDC (no stored secrets)
+
+Deployment to production?
+ → Use GitHub Environment + Required Reviewers
+
+Need runner for heavy compute?
+ → Self-hosted runner + runner groups + restrict to private repos only
+
+Secret needed in public repo workflow?
+ → STOP. Restructure: use OIDC or separate private deployment repo
+```
+
+### Related Study Material
+- [Domain 5: Access Tokens & GitHub Apps](./domain-5.md#access-token-types-and-github-apps)
+- [Domain 5: Enterprise Managed Users (EMU)](./domain-5.md#enterprise-managed-users)
+- [Domain 6: Self-Hosted Runners](./domain-6.md#self-hosted-runners)
+- [Domain 6: Encrypted Secrets Scope](./domain-6.md#encrypted-secrets-and-scope)
+- [Cheatsheet: OIDC Federation](./cheatsheet.md#terminology-check)
+
+---
+
+## Key Takeaways for Exam Day
+
+When faced with a scenario question on the exam:
+
+1. **Identify the domain** — Is this about identity (2), access (4), security (5), or actions (6)?
+2. **Ask "what's the risk?"** — What's the security/compliance/operational impact?
+3. **Choose least privilege** — The exam rewards answers that minimize access, exposure, or complexity
+4. **Think governance first** — Before implementing anything technical, define the *policy*
+5. **Know the tradeoffs** — Every choice (GitHub-hosted vs self-hosted, SAML vs SCIM, PAT vs GitHub App) has pros/cons; know them both
+
+---
+
+[← Overview](./index.md) · [Concept Map →](./concept-map.md) · [Tools Reference →](./tools-reference.md) · [Exam Guide →](./exam-guide.md)
diff --git a/certifications/github/gh-100/cheatsheet.md b/certifications/github/gh-100/cheatsheet.md
index 1ac1c15..6698d03 100755
--- a/certifications/github/gh-100/cheatsheet.md
+++ b/certifications/github/gh-100/cheatsheet.md
@@ -9,7 +9,7 @@ head:
# GH-100: Cheatsheet
-[← Overview](./index.md) · [← Exam Guide](./exam-guide.md)
+[← Overview](./index.md) · [← Admin Playbook](./admin-playbook.md) · [← Concept Map](./concept-map.md) · [← Tools Reference](./tools-reference.md) · [← Exam Guide](./exam-guide.md)
::: danger Exam Day Reference
Review this page 5 minutes before the exam.
@@ -73,6 +73,8 @@ Review this page 5 minutes before the exam.
| **BFG Repo Cleaner** | Removes secrets from Git history (recommended) |
| **filter-branch** | Git-native history rewrite (slower, legacy) |
| **Deploy Key** | Repo-scoped SSH key for server/CI access |
+| **Environment** | Deployment-scoped approvals, secrets, and branch controls |
+| **OIDC** | Short-lived cloud auth without storing long-lived cloud secrets |
---
@@ -115,6 +117,12 @@ Review this page 5 minutes before the exam.
**Need to access on-prem resources in CI?**
→ Self-hosted runner
+**Need approval gates or protected production secrets?**
+→ GitHub Environment
+
+**Need cloud authentication without storing long-lived credentials?**
+→ OIDC federation
+
**Secret committed to history?**
→ Revoke first → BFG to purge → GitHub Support if public
@@ -144,6 +152,8 @@ Review this page 5 minutes before the exam.
- **Runner group**: Access control layer for self-hosted runners — restricts which orgs/repos can use them.
- **Reusable workflow**: A `workflow_call`-triggered workflow callable from other workflows to share CI logic.
- **Deploy Key**: An SSH key scoped to a single repository. Preferred for read-only server access.
+- **Environment**: A deployment target with its own protection rules, secrets, and branch restrictions.
+- **OIDC**: OpenID Connect federation for getting short-lived cloud credentials in Actions without storing static secrets.
---
diff --git a/certifications/github/gh-100/concept-map.md b/certifications/github/gh-100/concept-map.md
new file mode 100644
index 0000000..ac84d7c
--- /dev/null
+++ b/certifications/github/gh-100/concept-map.md
@@ -0,0 +1,311 @@
+---
+title: "GH-100 - Cross-Domain Concept Map"
+description: "Visual guide showing how GitHub administration concepts interweave across domains"
+head:
+ - - meta
+ - name: keywords
+ content: gh-100, concept map, cross-domain, architecture, github administration
+---
+
+# GH-100: Cross-Domain Concept Map
+
+[← Overview](./index.md) · [Admin Playbook →](./admin-playbook.md) · [Tools Reference →](./tools-reference.md) · [Exam Guide →](./exam-guide.md)
+
+::: info Understanding Domain Relationships
+The GH-100 exam tests **individual domains**, but **real-world scenarios** require understanding how domains interact. This map shows the critical connections.
+:::
+
+---
+
+## The Big Picture: How Domains Connect
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ ENTERPRISE FOUNDATION │
+│ Domain 3: Products (GHEC/GHES), Licensing, Deployment │
+└──────────────────────┬──────────────────────────────────────┘
+ │
+ ┌──────────────┼──────────────┐
+ ↓ ↓ ↓
+ ┌─────────┐ ┌────────────┐ ┌──────────┐
+ │Domain 2 │ │ Domain 4 │ │ Domain 5 │
+ │Identity │→ │Access & │→ │Security &│→ Domain 6
+ │& Auth │ │Permissions │ │Compliance│ (Actions)
+ └────┬────┘ └────┬───────┘ └────┬─────┘
+ │ │ │
+ └────────────┼──────────────┘
+ ↓
+ ┌─────────────────────────┐
+ │ Domain 1: Support & │
+ │ Governance (Cross-all) │
+ └─────────────────────────┘
+```
+
+---
+
+## Domain-by-Domain Relationships
+
+### Domain 2 (Identity) → The Gatekeeper
+
+**What it controls**: Who can log in and which GitHub account they use.
+
+**Flows to Domain 4 (Access)**:
+- SAML SSO authenticates users
+- Team Sync mirrors IdP groups into GitHub teams
+- Teams grant repository permissions (Domain 4)
+
+```
+IdP (Okta, Azure AD)
+ ↓
+SAML SSO (Domain 2: Authentication)
+ ↓
+User is now logged in as @alice
+ ↓
+Team Sync (Domain 2) mirrors IdP group "Backend-Team"
+ ↓
+@alice is added to "Backend-Team" GitHub team
+ ↓
+"Backend-Team" has "write" access to backend-repo
+ ↓
+@alice can now push to backend-repo (Domain 4)
+```
+
+**Flows to Domain 5 (Security)**:
+- SAML enforcement (Domain 2) ensures only IdP users can access
+- EMU (Enterprise Managed Users) locks accounts to company-managed only
+- These restrictions prevent unauthorized access to sensitive resources
+
+---
+
+### Domain 4 (Access) → The Gatekeeper of Permissions
+
+**What it controls**: Who can do what to repos, teams, and organizations.
+
+**Connects to Domain 2**:
+- Permission structure depends on user identity (SAML, EMU, etc.)
+- Outside collaborators (Domain 4) bypass org membership but still need identity
+
+**Flows to Domain 5 (Security)**:
+- Repository permission levels determine secret access scope
+- Org owners (Domain 4: highest permission) can configure security features (Domain 5)
+- Branch protection rules (Domain 4) enforce code review before secrets/sensitive code lands
+
+```
+Domain 4: Repository Roles
+├─ Admin role → Can manage branch protection & enable secret scanning
+├─ Maintain role → Can enable CodeQL, configure environments
+├─ Write role → Can create/commit but not change permissions
+└─ Read role → View-only (lower security risk)
+ ↓
+ Domain 5: Security Features
+ These features are only as good as the
+ permissions you grant to who can access them.
+```
+
+**Flows to Domain 6 (Actions)**:
+- Environment protection rules (Domain 4 + Domain 6) require approvals before deployment
+- Runner groups (Domain 6) restrict which repos/orgs can use self-hosted runners
+- Permission levels determine who can manage GitHub Actions secrets (Domain 6)
+
+---
+
+### Domain 5 (Security) → The Locksmith
+
+**What it controls**: Detection and prevention of vulnerabilities and secrets.
+
+**Depends on Domain 4**:
+- Secret scanning alerts are viewable only by users with appropriate repo permissions (Domain 4)
+- CodeQL results visibility tied to repo access level
+- Audit logs (Domain 5) show **who changed permissions** (Domain 4)
+
+**Flows to Domain 6 (Actions)**:
+- GitHub Actions workflows **run** code (Domain 6)
+- Secret scanning (Domain 5) detects secrets in commits *before* they reach Actions
+- OIDC federation (Domain 5 + Domain 6) eliminates long-lived secrets in workflows
+- Push protection (Domain 5) blocks secrets before CI/CD even starts (Domain 6)
+
+```
+Development Flow:
+Developer writes code
+ ↓
+Push to GitHub
+ ↓
+Push Protection (Domain 5) blocks if secret detected
+ ↓
+Workflow triggers (Domain 6) only if push succeeds
+ ↓
+Workflow needs cloud credentials for deployment
+ ↓
+OIDC (Domain 5 + Domain 6) provides short-lived token
+ ↓
+Deployment succeeds without storing long-lived secrets
+```
+
+**Flows to Domain 2 (via Audit)**:
+- Audit logs (Domain 5) record identity changes (SAML updates, user provisioning via SCIM — Domain 2)
+- Audit logs show who enabled/disabled security features
+- EMU (Domain 2) + Audit logs (Domain 5) = complete identity + action trail
+
+---
+
+### Domain 6 (Actions) → The Executor
+
+**What it controls**: Automation, CI/CD pipelines, and deployment.
+
+**Depends on Domain 4**:
+- Only users with repo `write` or higher can write workflows
+- Runner groups (Domain 6) restricted by org/repo access (Domain 4)
+
+**Depends on Domain 5**:
+- Secrets scope (Domain 5 + Domain 6) controls which workflows can access sensitive data
+- Push protection (Domain 5) prevents malicious workflows from committing secrets
+- Dependabot security updates (Domain 5) trigger PRs with automated fixes
+
+**Depends on Domain 2**:
+- GitHub App tokens (Domain 6 workflows) use GitHub identity (Domain 2)
+- SCIM-provisioned users (Domain 2) can trigger workflows
+
+```
+Workflow Execution Chain:
+User pushes code
+ ↓
+SAML validates identity (Domain 2)
+ ↓
+Push protection scans for secrets (Domain 5)
+ ↓
+Workflow is triggered (Domain 6)
+ ↓
+Workflow runs on GitHub-hosted or self-hosted runner
+ ↓
+Workflow accesses org secret (Domain 6) with permission level (Domain 4)
+ ↓
+Secret scope (Domain 6) determines which repos can use this secret
+ ↓
+Audit log records "Workflow deployed to production" (Domain 5)
+```
+
+---
+
+## Critical Intersection Points (High Exam Probability)
+
+These are scenarios where **multiple domains interact**:
+
+### 1. **Identity + Security + Audit (Domains 2 + 5 + Admin)**
+**Scenario**: "A contractor's SAML account was deprovisioned via SCIM (Domain 2). How do you audit what they accessed?"
+
+**Answer Flow**:
+- Check audit log (Domain 5) with filter: `user:contractor-name action:repo.access`
+- Verify SCIM deprovisioning (Domain 2) happened correctly
+- Review secret access logs (Domain 5) to see if contractor accessed any org secrets
+- Related: Domain 1 (governance) — define contractor access review process
+
+### 2. **Permissions + Secrets + Workflows (Domains 4 + 5 + 6)**
+**Scenario**: "A junior dev accidentally has `admin` on the production repo. They can see the database password stored there. What's wrong?"
+
+**Answer Flow**:
+- **Domain 4 issue**: Junior dev should have `write` not `admin`
+- **Domain 5 issue**: Database password shouldn't be stored in repo secret; use OIDC + cloud vault (Domain 6)
+- **Domain 6 issue**: Production workflows should not run on commits from junior devs
+- **Fix**: Reduce permission (Domain 4) + migrate to OIDC (Domain 5/6) + environment protection rules (Domain 4/6)
+
+### 3. **Authentication Enforcement + Access Control (Domains 2 + 4)**
+**Scenario**: "We enforced SAML SSO last night. 30% of teams can't access their repos today."
+
+**Answer Flow**:
+- **Domain 2 diagnosis**: SAML enforcement blocks non-SAML users
+- **Domain 4 impact**: Outside collaborators (who bypass org SAML) are now blocked from non-member repos
+- **Domain 2 fix**: Review which accounts are SAML-linked; outside collaborators need special handling
+- **Domain 4 mitigation**: Temporarily remove outside collaborators from SAML enforcement or migrate them
+
+### 4. **Deployments + Identity + Secrets (Domains 6 + 2 + 5)**
+**Scenario**: "We want production deployments to only work for core team members, with no stored secrets."
+
+**Answer Flow**:
+- **Domain 2**: EMU or SCIM ensures only company-managed accounts exist
+- **Domain 6**: GitHub Environment with required reviewers (must be core team)
+- **Domain 5**: OIDC federation to get temporary cloud credentials (no secrets stored)
+- **Domain 6**: Self-hosted runner in VPC (isolate from internet)
+- **Result**: Deployment is identity-verified (Domain 2), gated (Domain 6), and credential-safe (Domain 5)
+
+---
+
+## The "Dependency Chain" — Questions You'll See
+
+**Question Type**: "To accomplish X, which must come first?"
+
+### Example 1: Secret Scanning → Audit Logging
+```
+Goal: "We need to prove to auditors that secrets are scanned"
+Step 1 (Domain 5): Enable secret scanning (repo-level)
+Step 2 (Domain 5): Push a test credential, verify alert fires
+Step 3 (Domain 5): Enable audit logging (org-level)
+Step 4 (Domain 5): Query audit log for "secret.push_protection_bypass"
+Exam question: "To audit secret scanning enforcement, which comes first?"
+Answer: Audit logging is useless without secret scanning enabled first.
+```
+
+### Example 2: SAML + Team Sync
+```
+Goal: "Sync Azure AD groups to GitHub teams"
+Step 1 (Domain 2): Enable SAML SSO
+Step 2 (Domain 2): Enable Team Sync
+Step 3 (Domain 2): Ensure IdP sends group claims in SAML assertion
+Exam question: "Team Sync isn't mirroring groups. You've checked IdP. What's next?"
+Answer: Verify SAML is working first; team sync depends on successful SAML authentication.
+```
+
+### Example 3: Runners + Security + Permissions
+```
+Goal: "Use self-hosted runners for production, safely"
+Step 1 (Domain 4): Create runner group, restrict to production repo only
+Step 2 (Domain 6): Deploy self-hosted runner in private VPC (not internet-accessible)
+Step 3 (Domain 5): Disable public workflows from using this runner
+Step 4 (Domain 6): Use OIDC to avoid storing cloud credentials in GitHub Secrets
+Exam question: "Self-hosted runner was compromised. Which protection failed first?"
+Answer: If it was exposed to the internet, Step 2 failed. If public PR used it, Step 3 failed.
+```
+
+---
+
+## Study Strategy: Using the Concept Map
+
+### By Domain Weight
+
+| Domain | Weight | Key Connections | Study Priority |
+|--------|--------|---|---|
+| **5** | 36% | Hub connecting to 2, 4, 6 | Master thoroughly; see how it touches other domains |
+| **4** | 18% | Gateway between 2, 5, 6 | Understand permission scope deeply |
+| **6** | 16% | Executor; depends on 2, 4, 5 | Know security requirements *before* deploying |
+| **2** | 11% | Gatekeeper; upstream of 4 | Understand identity flow impact on access |
+| **1, 3** | 9% | Support + governance (cross-domain) | Use these to frame other domains |
+
+### By Study Method
+
+**If you're a visual learner**:
+- Trace the flow: Identity → Access → Security → Actions
+- For each scenario, follow the chain of command/dependencies
+
+**If you're a logical learner**:
+- Learn Domain 2 first (who can log in?)
+- Then Domain 4 (what can they do?)
+- Then Domain 5 (how do we protect it?)
+- Then Domain 6 (how do we automate it?)
+
+**If you're a practical learner**:
+- Work through [Admin Playbook scenarios](./admin-playbook.md)
+- Pause at each step and ask: "Which domain handles this?"
+
+---
+
+## Key Takeaway: Domains Don't Exist in Isolation
+
+- **Domain 2 without Domain 4** = Identity but no access control (useless)
+- **Domain 4 without Domain 5** = Permissions but no security (vulnerable)
+- **Domain 5 without Domain 6** = Security but no automation (manual and error-prone)
+- **Domain 6 without Domains 2+4+5** = Automation but no governance (dangerous)
+
+**Exam tip**: If an answer isolates a single domain and ignores dependencies, it's likely wrong. Real admin decisions require thinking across domains.
+
+---
+
+[← Overview](./index.md) · [Admin Playbook →](./admin-playbook.md) · [Tools Reference →](./tools-reference.md) · [Exam Guide →](./exam-guide.md)
diff --git a/certifications/github/gh-100/domain-4.md b/certifications/github/gh-100/domain-4.md
index fff93ca..9a86391 100644
--- a/certifications/github/gh-100/domain-4.md
+++ b/certifications/github/gh-100/domain-4.md
@@ -142,6 +142,19 @@ The **most permissive** permission that applies wins.
When a question asks how to give a user "the minimum required permissions," the answer involves checking their team memberships and only granting what's needed for the task — never defaulting to Admin or Write if Read or Triage suffices.
:::
+### Custom Organization Roles and Custom Repository Roles
+
+On **GitHub Enterprise Cloud**, admins can go beyond the built-in roles:
+
+- **Custom organization roles** let you delegate selected administrative capabilities without making someone a full owner
+- **Custom repository roles** let you create a more granular role by extending a base repository role with additional capabilities
+
+This is useful when the built-in roles are either too weak or too broad.
+
+::: tip Exam Tip
+If the scenario is "delegate one narrow admin capability without full ownership," think **custom organization role**. If it is "grant repo access that sits between built-in repo roles," think **custom repository role**.
+:::
+
---
## Least Privilege in Practice
diff --git a/certifications/github/gh-100/domain-5.md b/certifications/github/gh-100/domain-5.md
index f962437..dff8ab2 100644
--- a/certifications/github/gh-100/domain-5.md
+++ b/certifications/github/gh-100/domain-5.md
@@ -228,6 +228,18 @@ GitHub supports multiple token types. The exam tests your knowledge of when and
- **GitHub App Installation Token**: 5,000 requests/hour per installation + 15,000 requests/hour at enterprise level
- **Unauthenticated**: 60 requests/hour
+### PAT Policies and Approval Controls
+
+Organizations can place guardrails around PAT usage:
+
+- Require approval for **fine-grained PATs** before they can access organization resources
+- Restrict or block **classic PAT** access to org-owned resources
+- Use shorter lifetimes for user-scoped credentials where policy allows
+
+::: warning Trap
+Fine-grained PATs are safer than classic PATs, but for machine identity the exam still prefers **GitHub Apps** over either PAT model.
+:::
+
---
## GitHub Apps vs OAuth Apps
diff --git a/certifications/github/gh-100/domain-6.md b/certifications/github/gh-100/domain-6.md
index af32773..855906a 100644
--- a/certifications/github/gh-100/domain-6.md
+++ b/certifications/github/gh-100/domain-6.md
@@ -210,6 +210,44 @@ For high-security environments, secrets can be stored externally and retrieved a
secret/data/prod db_password | DB_PASSWORD
```
+---
+
+## Environments and Deployment Protection Rules
+
+GitHub **Environments** add policy controls around deployments.
+
+### What Environments Can Enforce
+
+- **Required reviewers** before deployment jobs continue
+- **Wait timers** before deployment begins
+- **Branch and tag restrictions** so only approved refs can deploy
+- **Custom deployment protection rules** via GitHub Apps
+
+### Environment Secrets
+
+- Environment secrets are available only to jobs that target that environment
+- If approvals are required, the job does not receive those secrets until the protection gate passes
+
+::: tip Exam Tip
+If the question is about protecting production deployments, adding approval gates, or scoping secrets to production only, the answer often involves a **GitHub Environment**, not just a repository secret.
+:::
+
+---
+
+## OIDC for Cloud Authentication
+
+GitHub Actions can use **OpenID Connect (OIDC)** to authenticate to cloud providers without storing long-lived cloud credentials in GitHub.
+
+- The workflow requests an identity token from GitHub
+- The cloud provider trusts GitHub as an identity provider
+- The workflow exchanges that token for short-lived credentials
+
+Common examples include AWS, Azure, GCP, Vault, and package registries that support trusted publishing.
+
+::: tip Exam Tip
+If the question is "how do we avoid storing long-lived cloud secrets in GitHub Actions?", the strongest answer is usually **OIDC federation**.
+:::
+
diff --git a/certifications/github/gh-100/exam-guide.md b/certifications/github/gh-100/exam-guide.md
index 2c60e2c..67e5395 100755
--- a/certifications/github/gh-100/exam-guide.md
+++ b/certifications/github/gh-100/exam-guide.md
@@ -9,7 +9,7 @@ head:
# GH-100: Exam Guide
-[← Overview](./index.md) · [Cheatsheet →](./cheatsheet.md)
+[← Overview](./index.md) · [Admin Playbook →](./admin-playbook.md) · [Cheatsheet →](./cheatsheet.md)
---
@@ -45,6 +45,8 @@ The GH-100 exam is for **GitHub Administrators** (system administrators, IT prof
| "Isolate runner access by team or org" | **Runner groups** |
| "Store secrets outside GitHub" | **Third-party vault** (HashiCorp Vault, etc.) |
| "Enforce policy across all organizations" | **Enterprise policy** (not org policy) |
+| "Approval gate before production deployment" | **GitHub Environment** |
+| "Cloud auth without long-lived secrets" | **OIDC federation** |
---
@@ -58,6 +60,8 @@ The GH-100 exam is for **GitHub Administrators** (system administrators, IT prof
- **filter-branch vs BFG**: Both remove sensitive data from Git history. **BFG Repo Cleaner** is faster, simpler, and recommended for large repositories. `git filter-branch` is the older built-in Git approach — correct but slow.
- **Org-level vs Enterprise-level policies**: Enterprise policies **override** org-level settings. If the question asks how to enforce a rule across all organizations in an enterprise, the answer is an enterprise policy — not configuring each org individually.
- **PAT vs GitHub App for machine accounts**: The exam prefers **GitHub Apps** for machine/bot accounts — they have installable, scoped permissions, don't expire by default, and aren't tied to a specific user's account lifecycle.
+- **Repository secret vs Environment secret**: Environment secrets sit behind deployment controls like required reviewers and branch restrictions. Use them when the scenario is specifically about protected deployments.
+- **Stored cloud credential vs OIDC**: If the goal is to avoid long-lived cloud credentials in Actions, prefer **OIDC federation** over storing another secret in GitHub.
:::
---
@@ -93,6 +97,13 @@ Custom hardware, on-prem resources, IP restrictions → Self-hosted runner
Restrict runner access by team or org → Runner groups
```
+### "How should I secure a deployment?"
+```
+Need approval before production deploys → GitHub Environment with required reviewers
+Need to limit which branches can deploy → Environment branch/tag restrictions
+Need cloud auth without long-lived credentials → OIDC federation
+```
+
### "What should be done first?"
```
Always: Define enterprise policy, assess org structure, establish governance
@@ -117,4 +128,4 @@ Unauthorized app access → OAuth/GitHub App approval policy
---
-[← Overview](./index.md) · [Cheatsheet →](./cheatsheet.md)
+[← Overview](./index.md) · [Admin Playbook →](./admin-playbook.md) · [Concept Map →](./concept-map.md) · [Tools Reference →](./tools-reference.md) · [Cheatsheet →](./cheatsheet.md)
diff --git a/certifications/github/gh-100/index.md b/certifications/github/gh-100/index.md
old mode 100755
new mode 100644
index 5319dea..e9804e1
--- a/certifications/github/gh-100/index.md
+++ b/certifications/github/gh-100/index.md
@@ -14,7 +14,11 @@ An intermediate-level certification for system administrators, software develope
**Exam**: 100 min · Intermediate level · Pearson VUE (proctored) · Valid 2 years
::: info This is a governance and administration exam
-Think like a GitHub Enterprise Admin. Questions focus on access control, security policy, compliance, identity management, and automation — not day-to-day developer workflows.
+Think like a GitHub Enterprise Admin. Questions focus on access control, security policy, compliance, identity management, and automation, not day-to-day developer workflows.
+:::
+
+::: tip Official blueprint note
+These notes follow the **live GH-100 certification page**. As of **March 17, 2026**, the official exam page lists **6 measured domains** under "Assessed on this exam."
:::
-
+
+
+
---
@@ -42,67 +46,76 @@ A podcast-style walkthrough of key exam tactics — generated using [NotebookLM]
{
id: 'domain-1',
label: 'Domain 1: Support GitHub Enterprise (9%)',
+ link: 'https://docs.github.com/github/working-with-github-support/about-github-support',
children: [
- { id: 'd1-admin-support', label: 'Admin vs GitHub Support boundaries' },
- { id: 'd1-diagnostics', label: 'Support bundles & diagnostics' },
- { id: 'd1-workflows', label: 'Developer workflow standards' },
- { id: 'd1-marketplace', label: 'GitHub Marketplace & App vs Action' },
- { id: 'd1-api', label: 'GitHub APIs for admin tasks' }
+ { id: 'd1-admin-support', label: 'Admin vs GitHub Support boundaries', link: 'https://docs.github.com/github/working-with-github-support/about-github-support' },
+ { id: 'd1-diagnostics', label: 'Support bundles & diagnostics', link: 'https://docs.github.com/en/enterprise-server%403.20/support/contacting-github-support/providing-data-to-github-support' },
+ { id: 'd1-workflows', label: 'Developer workflow standards', link: 'https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches' },
+ { id: 'd1-marketplace', label: 'Marketplace Apps vs Actions', link: 'https://docs.github.com/en/actions/get-started/actions-vs-apps' },
+ { id: 'd1-api', label: 'GitHub APIs for admin tasks', link: 'https://docs.github.com/en/rest' }
]
},
{
id: 'domain-2',
label: 'Domain 2: Manage User Identities & Authentication (11%)',
+ link: 'https://docs.github.com/articles/about-authentication-with-saml-single-sign-on',
children: [
- { id: 'd2-saml', label: 'SAML SSO (org vs enterprise)' },
- { id: 'd2-2fa', label: '2FA enforcement' },
- { id: 'd2-scim', label: 'SCIM provisioning & providers' },
- { id: 'd2-teamsync', label: 'Team synchronization vs SCIM' }
+ { id: 'd2-saml', label: 'SAML SSO (org vs enterprise)', link: 'https://docs.github.com/github/setting-up-and-managing-your-enterprise/configuring-identity-and-access-management-for-your-enterprise-account' },
+ { id: 'd2-2fa', label: '2FA enforcement', link: 'https://docs.github.com/articles/about-two-factor-authentication-and-saml-single-sign-on' },
+ { id: 'd2-scim', label: 'SCIM provisioning & providers', link: 'https://docs.github.com/admin/identity-and-access-management/provisioning-user-accounts-for-enterprise-managed-users' },
+ { id: 'd2-teamsync', label: 'Team synchronization vs SCIM', link: 'https://docs.github.com/en/organizations/managing-saml-single-sign-on-for-your-organization/managing-team-synchronization-for-your-organization' }
]
},
{
id: 'domain-3',
label: 'Domain 3: Deployment, Distribution & Licensing (9%)',
+ link: 'https://docs.github.com/en/billing/managing-billing-for-your-products/about-billing-for-github-actions',
children: [
- { id: 'd3-products', label: 'GHEC vs GHES vs GHAE' },
- { id: 'd3-pricing', label: 'Actions & Packages pricing' },
- { id: 'd3-licenses', label: 'License usage statistics' }
+ { id: 'd3-products', label: 'GHEC vs GHES vs managed isolation', link: 'https://learn.microsoft.com/en-us/credentials/certifications/github-administration/?practice-assessment-type=certification' },
+ { id: 'd3-pricing', label: 'Actions & Packages pricing', link: 'https://docs.github.com/en/billing/managing-billing-for-your-products/about-billing-for-github-actions' },
+ { id: 'd3-licenses', label: 'License usage statistics', link: 'https://docs.github.com/github/setting-up-and-managing-your-enterprise-account/managing-users-in-your-enterprise-account' }
]
},
{
id: 'domain-4',
label: 'Domain 4: Access & Permissions (18%)',
+ link: 'https://docs.github.com/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization',
children: [
- { id: 'd4-orgs', label: 'Single org vs multiple orgs' },
- { id: 'd4-roles', label: 'Org roles & outside collaborators' },
- { id: 'd4-teams', label: 'Team permissions & AD sync' },
- { id: 'd4-repo', label: 'Repository permission levels' }
+ { id: 'd4-orgs', label: 'Single org vs multiple orgs', link: 'https://docs.github.com/en/enterprise-cloud%40latest/admin/managing-accounts-and-repositories/managing-repositories-in-your-enterprise/configuring-the-repository-visibility-policy-in-your-enterprise' },
+ { id: 'd4-roles', label: 'Org roles & outside collaborators', link: 'https://docs.github.com/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization' },
+ { id: 'd4-teams', label: 'Team permissions & repo roles', link: 'https://docs.github.com/organizations/organizing-members-into-teams/about-teams' },
+ { id: 'd4-repo', label: 'Repository permission levels', link: 'https://docs.github.com/organizations/managing-user-access-to-your-organizations-repositories/repository-roles-for-an-organization' }
]
},
{
id: 'domain-5',
- label: 'Domain 5: Secure Software Development & Compliance (36%)',
+ label: 'Domain 5: Secure Development & Compliance (36%)',
+ link: 'https://docs.github.com/en/code-security',
children: [
- { id: 'd5-scanning', label: 'Secret scanning & code scanning (CodeQL)' },
- { id: 'd5-dependabot', label: 'Dependabot & dependency graph' },
- { id: 'd5-auditlog', label: 'Audit log APIs (REST & GraphQL)' },
- { id: 'd5-tokens', label: 'Access tokens & GitHub Apps vs OAuth Apps' },
- { id: 'd5-emu', label: 'Enterprise Managed Users (EMU)' },
- { id: 'd5-scrub', label: 'Scrubbing sensitive data (BFG/filter-branch)' }
+ { id: 'd5-scanning', label: 'Secret scanning & code scanning (CodeQL)', link: 'https://docs.github.com/en/code-security/secret-scanning/working-with-secret-scanning-and-push-protection' },
+ { id: 'd5-dependabot', label: 'Dependabot & dependency graph', link: 'https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph' },
+ { id: 'd5-auditlog', label: 'Audit log APIs', link: 'https://docs.github.com/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/reviewing-the-audit-log-for-your-organization' },
+ { id: 'd5-tokens', label: 'Access tokens & GitHub Apps vs OAuth Apps', link: 'https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/deciding-when-to-build-a-github-app' },
+ { id: 'd5-emu', label: 'Enterprise Managed Users (EMU)', link: 'https://docs.github.com/admin/authentication/managing-your-enterprise-users-with-your-identity-provider/about-enterprise-managed-users' },
+ { id: 'd5-scrub', label: 'Scrubbing sensitive data from history', link: 'https://docs.github.com/code-security/secret-scanning/working-with-secret-scanning-and-push-protection' }
]
},
{
id: 'domain-6',
label: 'Domain 6: Manage GitHub Actions (16%)',
+ link: 'https://docs.github.com/en/actions/concepts/runners',
children: [
- { id: 'd6-runners', label: 'GitHub-hosted vs self-hosted runners' },
- { id: 'd6-runnergroups', label: 'Runner groups & IP allow lists' },
- { id: 'd6-secrets', label: 'Encrypted secrets scope & access' },
- { id: 'd6-reusable', label: 'Reusable workflows & enterprise distribution' },
- { id: 'd6-packages', label: 'GitHub Packages (types, workflows, vs releases)' }
+ { id: 'd6-runners', label: 'GitHub-hosted vs self-hosted runners', link: 'https://docs.github.com/en/actions/concepts/runners' },
+ { id: 'd6-runnergroups', label: 'Runner groups & IP allow lists', link: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-access-to-self-hosted-runners-using-groups' },
+ { id: 'd6-secrets', label: 'Encrypted secrets scope & access', link: 'https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions' },
+ { id: 'd6-reusable', label: 'Reusable workflows & enterprise distribution', link: 'https://docs.github.com/en/actions/using-workflows/reusing-workflows' },
+ { id: 'd6-packages', label: 'GitHub Packages in workflows', link: 'https://docs.github.com/packages/learn-github-packages/introduction-to-github-packages' }
]
},
{ id: 'exam-guide', label: 'Reviewed exam guide & traps' },
+ { id: 'admin-playbook', label: 'Worked through admin playbook scenarios' },
+ { id: 'concept-map', label: 'Studied cross-domain relationships' },
+ { id: 'tools-reference', label: 'Reviewed CLI & API reference' },
{ id: 'cheatsheet', label: 'Reviewed cheatsheet' },
{ id: 'ready', label: 'Ready for exam' }
]"
@@ -112,9 +125,8 @@ A podcast-style walkthrough of key exam tactics — generated using [NotebookLM]
## Official Resources
-- [GH-100 Exam Page](https://learn.microsoft.com/en-us/credentials/certifications/github-administration/)
+- [GH-100 Exam Page](https://learn.microsoft.com/en-us/credentials/certifications/github-administration/?practice-assessment-type=certification)
- [GH-100 Study Guide](https://learn.microsoft.com/en-us/credentials/certifications/resources/study-guides/gh-100)
-- [Exam Sandbox Demo](https://GHCertDemo.starttest.com)
- [GitHub Enterprise Documentation](https://docs.github.com/en/enterprise-cloud@latest)
## External Resources
@@ -122,7 +134,9 @@ A podcast-style walkthrough of key exam tactics — generated using [NotebookLM]
- [GitHub Skills](https://skills.github.com/)
- [GitHub Learning Pathways](https://resources.github.com/learn/pathways/)
- [Microsoft Learn: GitHub Administration Path](https://learn.microsoft.com/en-us/training/browse/?products=github)
+- [ExamTopics GH-100](https://www.examtopics.com/exams/microsoft/gh-100/) — offers a set of free verified practice questions (note: some questions beyond the free tier require login)
+- [EduSum GH-100 Sample Questions](https://www.edusum.com/microsoft/microsoft-github-administration-gh-100-certification-sample-questions) — free sample questions representing the real exam style
---
-[Start Study Notes →](./domain-1.md) · [Cheatsheet →](./cheatsheet.md)
+[Start Study Notes →](./domain-1.md) · [Admin Playbook →](./admin-playbook.md) · [Concept Map →](./concept-map.md) · [Tools Reference →](./tools-reference.md) · [Cheatsheet →](./cheatsheet.md)
diff --git a/certifications/github/gh-100/tools-reference.md b/certifications/github/gh-100/tools-reference.md
new file mode 100644
index 0000000..886cf55
--- /dev/null
+++ b/certifications/github/gh-100/tools-reference.md
@@ -0,0 +1,589 @@
+---
+title: "GH-100 - Tools & CLI Reference"
+description: "Command-line tools, APIs, and scripts for GitHub administration tasks"
+head:
+ - - meta
+ - name: keywords
+ content: gh-100, tools, cli, rest api, graphql, github enterprise, administration, commands
+---
+
+# GH-100: Tools & CLI Reference
+
+[← Overview](./index.md) · [Admin Playbook →](./admin-playbook.md) · [Concept Map →](./concept-map.md) · [Exam Guide →](./exam-guide.md)
+
+::: info Hands-On Reference for Exam Prep
+This page documents real commands and APIs you'll use as a GitHub administrator. Familiarity with these tools strengthens exam confidence.
+:::
+
+---
+
+## GitHub CLI (gh) — The Modern Admin Tool
+
+The **GitHub CLI** is the recommended way to manage GitHub from the command line.
+
+### Installation
+```bash
+# macOS (Homebrew)
+brew install gh
+
+# Linux (Debian/Ubuntu)
+sudo apt-get install gh
+
+# Verify installation
+gh --version
+```
+
+### Authentication
+```bash
+# Authenticate with GitHub
+gh auth login
+
+# Select: GitHub.com
+# Select: HTTPS or SSH (HTTPS recommended)
+# Paste your Personal Access Token (PAT) when prompted
+# Select: GitHub CLI
+
+# Verify authentication
+gh auth status
+```
+
+---
+
+## Essential gh Commands for Admins
+
+### Organization Management
+
+```bash
+# List all org members
+gh org-members list --org $ORG
+
+# Export org members to CSV
+gh api -X GET /orgs/$ORG/members --paginate --jq '.[] | [.login, .id, .type]' > members.csv
+
+# Promote user to org owner
+gh api -X PUT /orgs/$ORG/members/$USERNAME/role -f role=admin
+
+# Demote owner to member
+gh api -X PUT /orgs/$ORG/members/$USERNAME/role -f role=member
+
+# Remove user from org
+gh api -X DELETE /orgs/$ORG/members/$USERNAME
+```
+
+### Repository Management
+
+```bash
+# List all repos in an org
+gh repo list $ORG --limit 1000 --json name,url,isPrivate
+
+# Export repos with permission info
+gh repo list $ORG --limit 1000 --json name,visibility,pushedAt
+
+# Enable secret scanning on a repo
+gh api -X PATCH /repos/$ORG/$REPO -f security_and_analysis='{"secret_scanning":{"status":"enabled"}}'
+
+# Enable push protection
+gh api -X PATCH /repos/$ORG/$REPO -f security_and_analysis='{"secret_scanning_push_protection":{"status":"enabled"}}'
+
+# Require pull request reviews on main branch
+gh api -X PUT /repos/$ORG/$REPO/branches/main/protection \
+ -f required_pull_request_reviews='{"required_approving_review_count":2}'
+
+# Add team to repo with permission level
+gh api -X PUT /repos/$ORG/$REPO/teams/$TEAM_SLUG -f permission=write
+```
+
+### Team Management
+
+```bash
+# List all teams in an org
+gh api -X GET /orgs/$ORG/teams --paginate
+
+# Add user to team
+gh api -X PUT /orgs/$ORG/teams/$TEAM_SLUG/memberships/$USERNAME -f role=member
+
+# List team members
+gh api -X GET /orgs/$ORG/teams/$TEAM_SLUG/members
+
+# Grant team repo access
+gh api -X PUT /repos/$ORG/$REPO/teams/$TEAM_SLUG -f permission=write
+
+# Remove team from repo
+gh api -X DELETE /repos/$ORG/$REPO/teams/$TEAM_SLUG
+```
+
+### Audit Log Queries
+
+```bash
+# Export org audit log (last 90 days)
+gh api -X GET /orgs/$ORG/audit-log --paginate -f include=all > audit-log.json
+
+# Filter audit log with jq (see below)
+gh api -X GET /orgs/$ORG/audit-log --paginate -f include=all | \
+ jq '.[] | select(.action=="repo.destroy") | {actor: .actor.login, timestamp: .created_at, repo: .data.repository}'
+
+# Search for secret scanning bypasses
+gh api -X GET /orgs/$ORG/audit-log --paginate | \
+ jq '.[] | select(.action | contains("secret"))'
+
+# Identify users who changed permissions
+gh api -X GET /orgs/$ORG/audit-log --paginate | \
+ jq '.[] | select(.action | contains("member")) | {user: .actor.login, action: .action, target: .user.login}'
+```
+
+---
+
+## REST API — Core Admin Operations
+
+### Base URL
+```
+https://api.github.com
+```
+
+### Authentication
+```bash
+# Using curl with PAT
+curl -H "Authorization: token $GH_TOKEN" https://api.github.com/user
+
+# Using gh CLI (handles auth automatically)
+gh api
+```
+
+### Organization Endpoints
+
+| Endpoint | Method | Purpose |
+|----------|--------|---------|
+| `/orgs/$ORG/members` | GET | List org members |
+| `/orgs/$ORG/members/$USERNAME` | PUT/DELETE | Add/remove member |
+| `/orgs/$ORG/audit-log` | GET | Query audit log |
+| `/orgs/$ORG/teams` | GET/POST | List/create teams |
+| `/orgs/$ORG/teams/$TEAM_SLUG/members` | GET/PUT/DELETE | Manage team membership |
+| `/orgs/$ORG/secrets` | GET | List org secrets |
+
+### Repository Endpoints
+
+| Endpoint | Method | Purpose |
+|----------|--------|---------|
+| `/repos/$ORG/$REPO/vulnerability-alerts` | GET | List Dependabot alerts |
+| `/repos/$ORG/$REPO/secret-scanning/alerts` | GET | List secret scanning alerts |
+| `/repos/$ORG/$REPO/code-scanning/alerts` | GET | List CodeQL alerts |
+| `/repos/$ORG/$REPO/branches/BRANCH/protection` | GET/PUT | Manage branch protection |
+| `/repos/$ORG/$REPO/teams` | GET | List teams with repo access |
+
+### Example: Exporting All Repos with Their Security Status
+
+```bash
+gh api -X GET /orgs/$ORG/repos --paginate \
+ --jq '.[] | {name: .name, secret_scanning: .security_and_analysis.secret_scanning.status, push_protection: .security_and_analysis.secret_scanning_push_protection.status}' \
+ | jq -s 'sort_by(.name)' > security-status.json
+```
+
+---
+
+## GraphQL — Advanced Queries
+
+GitHub's **GraphQL API** allows complex, nested queries in a single request.
+
+### Basic Query Structure
+```graphql
+query {
+ organization(login: "your-org") {
+ name
+ members(first: 100) {
+ edges {
+ node {
+ login
+ name
+ }
+ }
+ }
+ }
+}
+```
+
+### Running GraphQL Queries
+
+```bash
+# Using gh CLI
+gh api graphql -f query='
+ query {
+ organization(login: "'$ORG'") {
+ name
+ members(first: 10) {
+ edges {
+ node {
+ login
+ }
+ }
+ }
+ }
+ }
+'
+
+# Save to file for reuse
+cat > query.graphql << 'EOF'
+query {
+ organization(login: "your-org") {
+ teams(first: 100) {
+ edges {
+ node {
+ name
+ members(first: 100) {
+ totalCount
+ }
+ }
+ }
+ }
+ }
+}
+EOF
+
+gh api graphql --input query.graphql
+```
+
+### Example: Audit Log via GraphQL
+
+```graphql
+query {
+ organization(login: "your-org") {
+ auditLog(first: 100, query: "action:repo.destroy") {
+ edges {
+ node {
+ action
+ actor {
+ login
+ }
+ createdAt
+ ... on AuditLogEvent {
+ resourcePath
+ }
+ }
+ }
+ }
+ }
+}
+```
+
+---
+
+## jq — JSON Processing for Audit Logs & API Responses
+
+**jq** is a powerful JSON query tool. Essential for parsing audit logs and API responses.
+
+### Installation
+```bash
+# macOS
+brew install jq
+
+# Linux
+sudo apt-get install jq
+```
+
+### Common Patterns for Admin Tasks
+
+#### Filter audit log for specific action
+```bash
+# Find all "repo.destroy" events
+gh api /orgs/$ORG/audit-log --paginate | jq '.[] | select(.action=="repo.destroy")'
+
+# Find secret scanning bypasses
+gh api /orgs/$ORG/audit-log --paginate | jq '.[] | select(.action | contains("secret_scanning"))'
+```
+
+#### Extract specific fields
+```bash
+# Get login, action, and timestamp
+gh api /orgs/$ORG/audit-log --paginate | jq '.[] | {user: .actor.login, action, created_at}'
+```
+
+#### Count events by action
+```bash
+gh api /orgs/$ORG/audit-log --paginate | jq 'group_by(.action) | map({action: .[0].action, count: length}) | sort_by(.count) | reverse'
+```
+
+#### Filter by date
+```bash
+# Events from the last 7 days
+gh api /orgs/$ORG/audit-log --paginate | jq "
+ now as \$now |
+ .[] |
+ select((.created_at | fromdateiso8601) > (\$now - 604800))
+"
+```
+
+#### Identify over-privileged users
+```bash
+# Find users with "owner" role
+gh api /orgs/$ORG/members --paginate | jq '.[] | select(.role=="admin") | .login'
+```
+
+---
+
+## GitHub Enterprise Server (GHES) — Admin Tools
+
+### Support Bundle (Diagnostics)
+
+```bash
+# SSH into GHES appliance
+ssh admin@github.example.com
+
+# Generate support bundle
+ghe-support-bundle -o /tmp/support-bundle.tar.gz
+
+# The bundle includes:
+# - System logs
+# - Configuration files (sanitized)
+# - Diagnostics (disk space, memory, processes)
+# - Database stats
+# - Git operations stats
+
+# SCP bundle to local machine for analysis
+scp admin@github.example.com:/tmp/support-bundle.tar.gz .
+
+# Extract and review
+tar -xzf support-bundle.tar.gz
+ls -la support-bundle/
+cat support-bundle/diagnostics.json
+```
+
+### Common GHES Admin Commands
+
+```bash
+# Check GHES version
+ssh admin@github.example.com ghe-version
+
+# Check system health
+ssh admin@github.example.com ghe-health-check
+
+# Manage services
+ssh admin@github.example.com ghe-service-status
+ssh admin@github.example.com ghe-service-stop
+ssh admin@github.example.com ghe-service-start
+
+# Reindex search
+ssh admin@github.example.com ghe-es-index-rebuild
+
+# Backup GHES
+ssh admin@github.example.com ghe-backup
+
+# Restore from backup
+ssh admin@github.example.com ghe-restore 192.168.1.100 BACKUP_SNAPSHOT
+```
+
+---
+
+## Secret Management & History Scrubbing
+
+### BFG Repo Cleaner (Recommended for Removing Secrets)
+
+```bash
+# Install BFG
+brew install bfg # macOS
+sudo apt-get install bfg # Linux
+
+# Create a list of secrets to remove
+cat > secrets.txt << 'EOF'
+ghp_xxxxxxxxxxxxxxxxxxx
+sk_live_xxxxxxxxxxxxx
+dB_PASSWORD=
+EOF
+
+# Mirror the repo (no working directory, just objects)
+git clone --mirror https://github.com/$ORG/$REPO.git $REPO.git
+
+# Use BFG to remove secrets
+bfg --replace-text secrets.txt $REPO.git
+
+# Remove BFG's reflog to finalize
+cd $REPO.git
+git reflog expire --expire=now --all
+git gc --prune=now --aggressive
+
+# Force-push cleaned history
+git push --force-with-lease
+
+# Everyone must re-clone
+```
+
+### Git Filter-Branch (Legacy but Valid)
+
+```bash
+# Remove a file from all commits
+git filter-branch --force --index-filter \
+ 'git rm --cached --ignore-unmatch config/secrets.yml' \
+ --prune-empty --tag-name-filter cat -- --all
+
+# Remove lines matching a pattern
+git filter-branch --force -f \
+ --tree-filter 'sed -i "/password=/d" config.env' \
+ --prune-empty -- --all
+
+# After filtering, force-push
+git push origin --force-with-lease --all
+```
+
+---
+
+## Audit Log Streaming (Advanced)
+
+### Export Audit Log to SIEM (Splunk, Datadog, etc.)
+
+```bash
+# Fetch and stream audit log to Splunk HTTP Event Collector
+curl -H "Authorization: Splunk $SPLUNK_HEC_TOKEN" \
+ -X POST https://splunk.example.com:8088/services/collector \
+ -d @audit-log.json
+```
+
+### Webhook-Based Audit Log Ingestion
+
+```bash
+# GitHub can send audit log events to a webhook
+# Configure in Enterprise Settings → Audit Log → Webhook configuration
+
+# Example webhook receiver (Node.js)
+const express = require('express');
+const crypto = require('crypto');
+
+app.post('/webhook', (req, res) => {
+ // Verify GitHub signature
+ const signature = req.headers['x-hub-signature-256'];
+ const payload = JSON.stringify(req.body);
+ const hash = 'sha256=' + crypto
+ .createHmac('sha256', WEBHOOK_SECRET)
+ .update(payload)
+ .digest('hex');
+
+ if (signature !== hash) return res.status(401).send('Unauthorized');
+
+ // Process audit log event
+ const auditLog = req.body.audit_log;
+ console.log(`Action: ${auditLog.action}, User: ${auditLog.actor.login}`);
+
+ res.status(200).send('OK');
+});
+```
+
+---
+
+## Useful Admin Scripts
+
+### Bulk Enable Secret Scanning Across Organization
+
+```bash
+#!/bin/bash
+ORG=$1
+
+# Get all repos
+REPOS=$(gh repo list $ORG --limit 1000 -q '.[] | .name')
+
+for REPO in $REPOS; do
+ echo "Enabling secret scanning on $REPO..."
+ gh api -X PATCH /repos/$ORG/$REPO \
+ -f security_and_analysis='{"secret_scanning":{"status":"enabled"}}' 2>/dev/null && \
+ echo "✓ $REPO" || echo "✗ $REPO (might be archived or private)"
+done
+```
+
+### Identify Users with Admin Access on Multiple Repos
+
+```bash
+#!/bin/bash
+ORG=$1
+
+# Get all repos
+REPOS=$(gh repo list $ORG --limit 1000 -q '.[] | .name')
+
+# Store results
+declare -A ADMIN_USERS
+
+for REPO in $REPOS; do
+ # Get collaborators with admin access
+ ADMINS=$(gh api /repos/$ORG/$REPO/collaborators --paginate | \
+ jq -r '.[] | select(.permissions.admin==true) | .login')
+
+ for ADMIN in $ADMINS; do
+ ADMIN_USERS[$ADMIN]=$((${ADMIN_USERS[$ADMIN]:-0} + 1))
+ fi
+done
+
+# Print users with admin on multiple repos
+for USER in "${!ADMIN_USERS[@]}"; do
+ if [ ${ADMIN_USERS[$USER]} -gt 1 ]; then
+ echo "$USER: ${ADMIN_USERS[$USER]} repos"
+ fi
+done | sort -t: -k2 -rn
+```
+
+### Audit Team Permissions Matrix
+
+```bash
+#!/bin/bash
+ORG=$1
+
+echo "Team,Repository,Permission" > permissions.csv
+
+TEAMS=$(gh api /orgs/$ORG/teams --paginate -q '.[] | .slug')
+
+for TEAM in $TEAMS; do
+ REPOS=$(gh api /orgs/$ORG/teams/$TEAM/repos --paginate -q '.[] | .name')
+
+ for REPO in $REPOS; do
+ PERMS=$(gh api /repos/$ORG/$REPO/teams/$TEAM -q '.permission')
+ echo "$TEAM,$REPO,$PERMS" >> permissions.csv
+ fi
+done
+
+echo "Saved to permissions.csv"
+```
+
+---
+
+## Troubleshooting: Common Command Patterns
+
+### Check Authentication
+```bash
+# Verify gh auth
+gh auth status
+
+# Test API access
+gh api /user
+```
+
+### Debug API Calls
+```bash
+# Add verbose flag to see request/response
+gh api --input /repos/$ORG/$REPO -v
+
+# Format JSON output
+gh api /repos/$ORG/$REPO -q '.name, .visibility'
+```
+
+### Handle Rate Limiting
+```bash
+# Check rate limit status
+gh api /rate_limit
+
+# GraphQL queries have separate rate limits
+gh api graphql -f query='{ viewer { login } }' # Shows rate limit in response headers
+
+# Wait before retrying
+sleep 60
+```
+
+---
+
+## Study Tip: Tool-Domain Mapping
+
+| Tool | Relevant Domain | Use Case |
+|------|---|---|
+| `gh repo list` | Domain 4 | Audit repository inventory |
+| `gh api /audit-log` | Domain 5 | Track security and access changes |
+| `ghe-support-bundle` | Domain 1 | Troubleshoot GHES issues |
+| BFG / `git filter-branch` | Domain 5 | Remove secrets from history |
+| `jq` | Domain 5 | Parse audit log for compliance reports |
+| GraphQL audit log | Domain 5 | Complex queries (e.g., "who accessed production secrets?") |
+
+---
+
+[← Overview](./index.md) · [Admin Playbook →](./admin-playbook.md) · [Concept Map →](./concept-map.md) · [Exam Guide →](./exam-guide.md)
diff --git a/public/audio/certifications/gh-100/Exam_Refreshers___GH-100.m4a b/public/audio/certifications/gh-100/Exam_Refreshers___GH-100.m4a
new file mode 100644
index 0000000..d066c5e
Binary files /dev/null and b/public/audio/certifications/gh-100/Exam_Refreshers___GH-100.m4a differ
diff --git a/public/images/certifications/gh-100/infographic.png b/public/images/certifications/gh-100/infographic.png
new file mode 100644
index 0000000..b79d78d
Binary files /dev/null and b/public/images/certifications/gh-100/infographic.png differ