agenticlately · GH-600 Study Prep
Home Phase 0 Lesson 0.8

Secrets + Environments

The lockbox for credentials, and the city-inspector sign-off before real utilities connect. Two tools that together enforce least privilege and keep humans in the loop — core GH-600 safety ideas.

Story

Building-a-house world — same site and crew as every Phase 0 lesson.

The crew runs on codes and keys. There's the alarm code (disarms security each morning), the supply-room key (gets materials from the locked store), and the utility account password (pays the power bill). These never go on the whiteboard — anyone walking through can see that. They live in the lockbox, and you hand a worker only the one key their job actually needs, right when they need it.

That's secrets: sensitive values stored safely, handed out one at a time, never painted on the wall.

But there's a second layer. Before the house goes live — real power connected, water running, people moving in — the city inspector must sign off first. Even if the crew thinks they're done, the utilities don't connect until that sign-off happens. You can require two specific inspectors to both approve. Or add a 10-minute cooling-off timer. The sign-off ceremony is the gate between "built" and "live."

That's environments: a named checkpoint a workflow must pass before it can reach the real world.

Secrets

A secret is a sensitive value — an API key, a password, a deployment token — that GitHub stores encrypted so a workflow can use it without the value ever appearing in your code or logs.

source: docs.github.com — Using secrets in GitHub Actions · fetched 2026-05-28

The three levels — where you store it determines who can use it

Level Stored on Who can access it When to use
Repository One repo Any workflow in that repo Default. Credentials specific to one project.
Environment One environment inside one repo Jobs targeting that environment — but only after the environment's protection rules pass Production deploy tokens. The most locked-down option — pairs with required-reviewer gates.
Organization The org Repos you explicitly allow: all, private only, or a named list Share one token (npm, Docker Hub) across many repos without copying it into each.
Convention (not doc)

If it's a deploy credential for production, use environment-level — it forces the human-gate check before the workflow can even read the secret. Repository-level secrets are readable by any workflow job, no gate required.

Secrets vs variables — one-look contrast

Secret Variable
Sensitive? Yes — API key, password, token No — region name, feature flag, base URL
Masked in logs? Yes. GitHub redacts the value automatically. No. Visible in logs.
Use for Anything that would hurt if leaked Plain config values you're OK exposing

Rule: if you'd be unhappy seeing it in a public log, it's a secret.

Syntax teaser — set a secret, then use it

Set from the terminal (GitHub CLI):

# Repository secret — prompts for the value interactively
gh secret set DEPLOY_TOKEN

# Environment-level secret (ties to "production" environment)
gh secret set DEPLOY_TOKEN --env production

# Org-level secret, accessible to specific repos only
gh secret set DEPLOY_TOKEN --org myOrg --repos repo1,repo2

source: cli.github.com — gh secret set · fetched 2026-05-28

Reference it inside a workflow — the ${{ secrets.NAME }} expression:

jobs:
  deploy:
    environment: production          # ← which lockbox to draw from
    steps:
      - name: Push to registry
        env:
          TOKEN: ${{ secrets.DEPLOY_TOKEN }}   # ← value injected at runtime
        run: ./deploy.sh

${{ secrets.DEPLOY_TOKEN }} is the key tag that tells GitHub "pull this from the lockbox at runtime." The actual token never appears in the YAML file — only this reference does, and GitHub redacts it from logs.

source: docs.github.com — Using secrets in GitHub Actions · fetched 2026-05-28

Environments

An environment is a named deployment target (e.g. production, staging) that you wrap in protection rules. A workflow job that targets an environment must pass all its rules before it can run — or access any of the environment's secrets.

Verbatim from the docs: "A job that references an environment must follow any protection rules for the environment before running or accessing the environment's secrets."

source: docs.github.com — Using environments for deployment · fetched 2026-05-28

Protection rules — what you can add to an environment

  1. Required reviewers"up to 6 people or teams. Only one of the required reviewers needs to approve the job for it to proceed." Optional: "prevent self-review" so the person who triggered the deploy can't approve their own work.
  2. Wait timer — add a delay (in minutes) before the job runs. Gives a window to cancel something triggered by mistake.
  3. Deployment branches and tags — restrict which branch or tag patterns can deploy here. Example: only the main branch can reach production.
  4. Custom rules — via GitHub Apps that add specialized checks (external security scans, compliance systems).
  5. Admin bypass control — optionally disallow even admins from bypassing the rules. Locks the gate completely.
The city-inspector sign-off — in one look

Say your workflow has two jobs: build (runs tests) and deploy (ships to production). Without an environment, deploy runs immediately after build. With a production environment on deploy:

build ✓  →  [required reviewer must click Approve]  →  deploy runs
                    ↑
           city inspector sign-off

The deploy job pauses at the gate. The reviewer sees what's about to happen and approves (or rejects). Only then does the job run — and only then can it read ${{ secrets.DEPLOY_TOKEN }}.

Plan note: environments for private repos require GitHub Team or Pro. Free plans get environments on public repos only. [source · fetched 2026-05-28]

Why this matters for GH-600

Dual relevance

Secrets + Environments → Exam: MED–HIGH · Day-to-day: HIGH. The exam tests "least privilege" and "human-in-the-loop" as core AI-agent safety ideas — secrets and environments are the concrete GitHub implementation of both. You'll also use these on every real project that deploys anything.

This is least privilege + human-in-the-loop made real:

  • Least privilege via secrets: An agent's workflow gets only the credentials its job needs — not every key in the house. Environment-level secrets add an extra lock: the agent can't even read the production token until a human reviewer approves the gate.
  • Human-in-the-loop via environments: The agent can build and test freely. But deploying to production — the step with real consequences — requires a human to explicitly approve. The agent proposes the deploy by triggering the workflow; a person accepts by clicking Approve in the environment gate.

In one line: agent gets scoped secrets (not master keys) + the risky action can't run until a person signs off.

This is exactly the pattern GH-600 cares about: AI does the work; humans control the consequences.

Check-in — three questions

Open-ended. Think first, then peek at the suggested answer.

  1. A teammate says "just put the API key in the workflow YAML as a variable." What's wrong with that, and what should you do instead?

    Suggested answer

    Variables are plain text — they show in logs, in the YAML file, and in the repo history. Anyone who can read the repo (including future contributors or an AI agent) can copy the value. The API key should be stored as a secret at the repository (or environment) level, then referenced as ${{ secrets.API_KEY }} in the workflow. GitHub masks the value from logs automatically.

  2. You have three repos that all push Docker images to the same registry. You're tired of setting the registry token in each repo separately. What secret level solves this — and what command creates it?

    Suggested answer

    An organization-level secret. You store it once at the org, choose which repos can access it, and every allowed repo's workflows can use ${{ secrets.REGISTRY_TOKEN }} without copying the value into each repo.

    gh secret set REGISTRY_TOKEN --org myOrg --repos repo1,repo2,repo3

    source: cli.github.com — gh secret set · fetched 2026-05-28

  3. An AI agent triggers a deploy workflow targeting a production environment with a required-reviewer rule. Walk through what happens between "workflow triggered" and "deploy job actually runs."

    Suggested answer

    The workflow starts and any jobs without the environment (e.g. build) run normally. When execution reaches the deploy job — which references the production environment — GitHub pauses it and notifies the required reviewers. One of those reviewers (up to 6 configured) must click Approve. Only after approval does the deploy job resume and gain access to the environment's secrets (e.g. ${{ secrets.DEPLOY_TOKEN }}). If nobody approves, or a reviewer rejects, the job never runs. The agent proposed; the human accepted.

Mentor marks this lesson verified after you compare answers and say "got it" in chat.

Ticks this lesson done on the home roadmap. Saved in this browser.

phase 0 · lesson 0.8 · classic GitHub

Sources: docs.github.com — Using secrets in GitHub Actions · docs.github.com — Using environments for deployment · cli.github.com — gh secret set · fetched 2026-05-28.

Unofficial study material. Not affiliated with, endorsed by, or sponsored by GitHub or Microsoft. “GH-600” and “GitHub” are trademarks of their respective owners, used for identification only.