Checkpoint Lab — Secrets, Environments, Variables, Redaction, and Credential Hygiene
The checkpoint assembles Chapter 07 into an auditable synthetic credential lifecycle. You will record ownership and scope, create a repository secret and environment-scoped secret, consume them without printing values, verify that no artifact/log intentionally contains the credential, rotate the repository secret with a non-secret generation marker, delete it, prove a fresh run fails because the secret is absent, and finish with a credential data-flow diagram plus cleanup record.
Learning objectives
- Define owner, purpose, scope, trust boundary, rotation rule, and revocation criteria before creating the fake credential.
- Run repository- and environment-scoped secret consumers that emit only presence and run-identity evidence.
- Inspect logs and staged output paths for accidental exposure without dumping secret-bearing state.
- Rotate and revoke the repository secret, preserving evidence from pre-rotation, post-rotation, and post-revocation runs.
- Produce a data-flow diagram and final operating contract that distinguishes GitHub removal from external issuer revocation.
1. Preflight contract
| Field | Checkpoint value |
|---|---|
| Repository | Learner-owned disposable repository only. |
| Runner | ubuntu-24.04. |
| Permissions |
permissions: {}; no GitHub mutation required.
|
| Repository secret |
LAB_REPO_CREDENTIAL, synthetic and
authority-free.
|
| Environment secret |
LAB_ENV_CREDENTIAL on lab-gate,
synthetic and authority-free.
|
| Configuration |
LAB_STAGE=training;
LAB_SECRET_GENERATION=v1 then v2.
|
| External systems | None. No cloud, registry, database, package, or SaaS request. |
| Abort | Stop if any value has real authority or a credential value appears in logs/files. |
2. Write predictions before execution
-
Run A: repository secret present; environment secret present only
in the job that references
lab-gate. -
Run B after rotation: repository secret still present; non-secret
generation marker is
v2. - Run C after deletion: repository secret resolves empty and the repository job fails before any external action; environment job remains independent.
- No job requires write token permissions, third-party actions, artifacts, caches, or cloud credentials.
3. Checkpoint workflow
name: Chapter 07 credential lifecycle checkpoint
on:
workflow_dispatch:
permissions: {}
env:
LAB_STAGE: ${{ vars.LAB_STAGE }}
LAB_SECRET_GENERATION: ${{ vars.LAB_SECRET_GENERATION }}
jobs:
repository_secret:
runs-on: ubuntu-24.04
env:
LAB_REPO_CREDENTIAL: ${{ secrets.LAB_REPO_CREDENTIAL }}
steps:
- name: Record safe run identity
run: |
printf 'run_id=%s attempt=%s sha=%s stage=%s generation=%s\n' \
"$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" "$GITHUB_SHA" \
"$LAB_STAGE" "$LAB_SECRET_GENERATION"
- name: Require repository secret without printing it
run: |
set -euo pipefail
if [[ -z "$LAB_REPO_CREDENTIAL" ]]; then
echo 'repo_secret_state=missing'
exit 40
fi
echo 'repo_secret_state=present'
- name: Pass the fake credential to a child process through stdin
run: |
set -euo pipefail
printf '%s' "$LAB_REPO_CREDENTIAL" | python3 -c \
'import sys; assert sys.stdin.read(); print("stdin_secret_consumed=true")'
- name: Create only non-sensitive checkpoint evidence
run: |
set -euo pipefail
mkdir -p checkpoint-evidence
printf 'run_id=%s\nrun_attempt=%s\nsource_sha=%s\ngeneration=%s\nsecret_value_recorded=false\n' \
"$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" "$GITHUB_SHA" \
"$LAB_SECRET_GENERATION" > checkpoint-evidence/state.txt
find checkpoint-evidence -type f -printf '%P\n'
environment_secret:
runs-on: ubuntu-24.04
environment: lab-gate
env:
LAB_ENV_CREDENTIAL: ${{ secrets.LAB_ENV_CREDENTIAL }}
steps:
- name: Require environment secret without printing it
run: |
set -euo pipefail
if [[ -z "$LAB_ENV_CREDENTIAL" ]]; then
echo 'environment_secret_state=missing'
exit 41
fi
echo 'environment_secret_state=present'
The checkpoint deliberately does not upload
checkpoint-evidence. The file is local, non-sensitive
state used to practice manifest inspection. Chapter 13 will teach
artifact transport and retention explicitly.
4. Create synthetic state and execute Run A
- Create the two repository variables and repository secret.
-
Create
lab-gateand its environment secret, or use the documented simulation if your private repository/plan does not expose environment secrets. - Dispatch the workflow.
-
Record run ID, attempt, source SHA, job conclusions, environment
association, generation
v1, and the twopresentstates. - Review the log manually for unexpected values; do not search by pasting the actual secret into a browser or script.
5. Produce the credential data-flow diagram
flowchart TD
A[Credential owner creates synthetic value] --> B[Repository secret store]
A --> C[Environment lab-gate secret store]
D[workflow_dispatch] --> E[repository_secret job]
D --> F[environment_secret job]
B --> E
C --> G{Environment rules satisfied?}
G -->|Yes| F
G -->|No / pending| H[Secret unavailable / job waits]
E --> I[Process env then stdin]
F --> J[Process env]
I --> K[Boolean evidence only]
J --> K
K --> L[Rotation / revocation record]
Annotate the diagram with who owns each secret, which job can receive it, what is logged, and which cleanup event closes the lifecycle.
6. Exposure inspection without dumping state
For each run, verify:
-
no step prints
LAB_REPO_CREDENTIALorLAB_ENV_CREDENTIAL; -
no
set -x, verbose HTTP trace, wholeenvdump, or secrets/context dump exists; -
local
checkpoint-evidence/state.txtcontains only run identity, generation, andsecret_value_recorded=false; - no artifact/cache step is present;
- no external service received the fake credential.
7. Rotate and execute Run B
-
Update
LAB_REPO_CREDENTIALto a new synthetic value. - Update
LAB_SECRET_GENERATION=v2. - Dispatch Run B after the settings update.
-
Verify
generation=v2,repo_secret_state=present, and the same source/workflow expectations. - Record the settings/audit change time if available; do not record either secret value.
8. Revoke and execute Run C
- Delete
LAB_REPO_CREDENTIAL. - Dispatch a fresh Run C.
-
Preserve the expected
repo_secret_state=missingand exit 40 evidence. - Do not “repair” Run C by weakening the presence check; its failure is the proof of GitHub-side revocation.
If this were a real external credential, the checkpoint would also require revocation at the external issuer and provider-side evidence that the old credential can no longer authenticate.
9. Final evidence packet
| Evidence | Required statement |
|---|---|
| Run A | generation v1; repository/environment secrets present; no external side effect. |
| Run B | generation v2; repository secret present after documented rotation event. |
| Run C | repository secret missing after deletion; intentional failure preserved. |
| Workflow SHA | Exact source revision for each run. |
| Trust boundary | Manual dispatch in learner-owned disposable repository; no fork/Dependabot input. |
| Residue review | No secret in logs, local evidence file, artifact/cache, source, or external service. |
| Environment |
lab-gate association/protection result or
simulation note.
|
| Limitations | Presence/rotation are synthetic; no real provider authentication was performed. |
10. Cleanup / rollback
- Delete the environment secret and repository variables.
- Remove
lab-gateif it is lab-only. - Keep or delete the disposable repository according to your study evidence policy.
- Confirm no real credential was ever created, stored, or transmitted.
11. Chapter 07 production operating contract
Chapter 07 adds a credential lifecycle contract: every confidential value has an owner, issuer, purpose, narrow scope, eligible event/job boundary, injection mechanism, residue policy, rotation rule, emergency revocation procedure, and evidence trail. Log masking is defense in depth, not authorization. Secret removal from GitHub is distinct from provider revocation. Untrusted fork/Dependabot code remains outside privileged credential zones, and long-lived cloud keys are candidates for OIDC replacement.
Chapter 08 moves to GitHub-hosted runners, images, labels, hardware, and runtime behavior. That chapter explains the compute environment that receives these values: image mutability, labels, filesystem isolation, preinstalled tools, job boundaries, and runtime evidence.
Knowledge check
What are the three checkpoint runs intended to prove?
Run A proves initial scoped availability, Run B proves a documented rotation boundary while keeping the value opaque, and Run C proves GitHub-side revocation by observing an empty secret and intentional failure.
Why does the checkpoint not upload its evidence directory?
Chapter 07 is about credential lifecycle, and broad artifact handling is a separate retention surface taught later. Keeping evidence local avoids introducing unnecessary transport of potentially sensitive files.
What does
secret_value_recorded=false prove?
Only that the designed evidence file intentionally contains no credential value; it does not replace review of logs, process handling, or other residue surfaces.
If Run C fails after deleting the GitHub secret, is a real provider credential necessarily revoked?
No. GitHub-side unavailability and issuer-side invalidation are separate states; the provider credential must also be revoked or rotated.
What production contract does Chapter 07 add?
A credential lifecycle contract covering owner/issuer, scope, trust/event/job eligibility, injection, residue, rotation, revocation, and auditable evidence.
Official references and version notes
- Secrets concept — current model for repository, organization, and environment Actions secrets and how workflows receive them.
- Secrets reference — current naming, precedence, size/count limits, queue/start read timing, and automatic redaction behavior.
- Using secrets in GitHub Actions — current workflow injection patterns, missing-secret behavior, fork/Dependabot restrictions, masking guidance, CLI setup, and OIDC recommendation.
- Variables concept — current distinction between non-sensitive configuration variables and secrets.
-
Variables reference
— current
varsscope, precedence, limits, and environment-variable semantics. - Deployments and environments — current environment secret availability, protection-rule timing, plan/visibility boundaries, and self-hosted-runner warning.
- Events that trigger workflows — current fork pull-request secret restrictions and read-only token behavior.
- Dependabot on GitHub Actions — current Dependabot-specific token and secret restrictions.
-
Workflow syntax
— current
secrets,environment, reusable-workflow secret passing, and conditional semantics. -
Workflow commands
— current
::add-mask::behavior and environment-file commands. - Secure use reference — current guidance for rotating/removing secrets, approval gates, untrusted input, and credential hygiene.
- OpenID Connect — current model for exchanging GitHub OIDC identity for short-lived provider credentials instead of storing long-lived cloud secrets.
-
Reuse workflows
— current explicit secret passing,
secrets: inherit, and directly-called workflow boundaries.
Version-sensitive secrets/environment behavior was rechecked
against current primary GitHub documentation on
2026-09-09. Mandatory executable workflows use a
learner-owned disposable repository, ubuntu-24.04,
built-in Bash/Python only, synthetic credentials, and
permissions: {}; no third-party action, PAT, real API
key, cloud account, package publication, deployment, or
self-hosted runner is required. At verification time, Actions
secrets can exist at organization, repository, or environment
scope; a lower scope wins on a same-name collision (environment
over repository over organization). Organization/repository
secrets are read when a workflow run is queued, while environment
secrets are read when the job referencing that environment starts.
A secret that is not set resolves to an empty string; normal
Actions secrets are not passed to fork-origin pull-request
workflows (except the special automatic
GITHUB_TOKEN behavior) and are not available to
Dependabot-triggered runs. Secrets are limited to 48 KB; current
counts are up to 1,000 organization, 100 repository, and 100
environment secrets. GitHub log redaction is a safety layer, not a
confidentiality proof; transformed/structured values, artifacts,
caches, process arguments, and third-party systems remain separate
leakage surfaces. For cloud providers that support OIDC, the
course recommends short-lived federation instead of long-lived
provider keys; the full OIDC trust-policy implementation is
deferred to Chapter 20. The checkpoint intentionally contains no
artifact upload, third-party action, provider authentication, real
secret, or repository mutation. It practices lifecycle evidence
while keeping all credential values opaque.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.