Offline security exercise / source reading
Trace dummy secret exposure through config, diffs and logs
Read the supplied instructions here, then download the complete project to use the Python utilities and training materials. These are guided practice materials; reference checks do not assess independent understanding.
Archive folder: jeremy-bryant-pages/labs/secret-handling/
Lab instructions
labs/secret-handling/README.md
# Trace dummy secret exposure through config, diffs and logs Find an explicit dummy value across current configuration, retained changes and output logs. Explain exposure audiences and why removing a line is not the same as invalidating an exposed credential. **Time:** 30-45 minutes for a first pass; use the later recall task on another day. **Prerequisites:** Basic file navigation, editing a small JSON worksheet, and introductory networking/security vocabulary. No professional security experience, cloud account, coding background or programming changes are required. > **Vocabulary:** **Secret**: a value granting access. **Revocation**: making a credential unusable. **Rotation**: replacing a credential and retiring the old one. **Diff**: lines added or removed by a change. **Redaction**: hiding a value in a displayed copy. **Exposure path**: an artifact and audience through which a value becomes visible. ## Evidence and exact semantics All values are fake and deliberately begin `DEMO_ONLY_TOKEN_`. Do not replace them with real credentials. `data.secrets` contains unique `id`, unique `marker`, and `state` (`active` or `revoked`) for each dummy credential. A marker uses an uppercase letter after the prefix and then uppercase letters, digits or underscores. `data.files` contains unique `id`, `kind` (`config`, `diff`, `log`), `audience` (`local`, `shared`, `public`), and a nonempty `lines` list. Each line has at most 400 characters with no embedded newline; at most 100 lines per file. Readable artifacts are `ID.txt` with the same lines and a final newline. The analyser rejects mismatches between `data.files` and `artifacts`. When editing a practice copy, update both representations; otherwise the evidence is contradictory. Changing just a secret's `state` needs no artifact edit. Only listed exact markers are matched, with no adjoining ASCII letter, digit or underscore. This prevents `DEMO_ONLY_TOKEN_APP` from matching the longer `DEMO_ONLY_TOKEN_APP_LONG`. All diff lines, including removed `-` lines, remain readable exposure evidence. Locations use `filename.txt:Lnumber`, one-based. Repeated occurrences on one line count as one location. Use one exact string per secret ID: | Decision | Meaning and priority | | --- | --- | | `not-seen-in-supplied-artifacts` | The listed value has no exact occurrence in these artifacts. | | `confirm-revocation;clean-copies;review-use` | A listed revoked value remains visible; confirm invalidation, remove unnecessary copies and review prior use. | | `contain;revoke-and-replace;clean-copies;review-use` | An active value appears in shared or public material; stop further exposure, invalidate/replace it with service continuity planning, clean retained copies, review use. | | `relocate-before-sharing` | Active value appears only in local material; move it into the approved secret mechanism and prevent inclusion in shared output. | Apply the first matching row. Real incident work can run several tasks in parallel; the sequence stresses that cosmetic deletion cannot replace revocation. Preserve necessary audit evidence under restricted access without needlessly retaining live credentials. All proposed actions here are notes only. ## Run the exercise From the repository root, enter this folder with `cd labs/secret-handling`. Use Python 3.10 or newer. On Windows, `py` may replace `python` if that is your installed launcher. No package install, account, cloud subscription or billing setup is needed. Commands run entirely offline and change no real service. ```text python lab.py cases python lab.py prepare --scenario guided --out run/attempt-01 python lab.py show --case run/attempt-01/case.json ``` Read the case and any extracted `.txt` evidence. Edit the blank `run/attempt-01/answers.json`: fill every decision with the exact vocabulary below, write your own explanation, and cite record IDs or line references in `evidence`. Keep `notes.txt` for prediction, uncertainty and help used. Only after saving your prediction: ```text python lab.py analyse --case run/attempt-01/case.json python lab.py check --case run/attempt-01/case.json --answers run/attempt-01/answers.json python test_lab.py python lab.py verify ``` The worksheet has exactly `decisions` (object), `explanation` (text), and `evidence` (list of text references). For example, an evidence entry can be a record ID plus its field name. Use your own case IDs, not invented references. `check` compares decision strings and requires nonempty written fields; a person must assess their accuracy. `verify` checks shipped fixtures, not learner skill. Exit codes are 0 for success/match, 1 for differences or incomplete written fields, and 2 for invalid input. Default `--case` is the guided fixture beside the script. Explicit input paths are relative to the working directory; `--out` is relative to this lab and must be a new folder below `run/`. For the next cases, prepare fresh folders: ```text python lab.py prepare --scenario changed --out run/attempt-02 python lab.py prepare --scenario challenge --out run/attempt-03 ``` Replace `attempt-01` in `show`, `analyse` and `check` with the chosen folder. Edit practice copies only. Do not overwrite fixture or reference files. ## Deliverable and handover Save one completed worksheet and a short evidence note for each case. Include your prediction, changed judgment, uncertainty, and one next check you cannot perform from this evidence. Record whether you used the worked example or help. Ask a reviewer: "Can you reproduce my decision from these record IDs, and which claim goes beyond the evidence?" Your independent status remains **unassessed**; matching output is not a qualification, professional experience or proof of mastery. These are original fictional practice cases, not assessment submissions. ## Limits This is an exact listed-marker exercise, not a complete secret scanner. It misses unlisted values, encoding, split values and other formats. A local-only finding may have a wider history not supplied here. No credential works, no endpoint is contacted, and no history or log is actually rewritten. ## Primary references OWASP covers secret lifecycle, rotation, revocation, access control and auditing. The marker grammar and artifact audiences are deliberately small exercise conventions. - [OWASP: Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html) Links are optional further reading, checked 2026-10-23. Running this lab does not fetch them. See [the worked example](WORKED-EXAMPLE.md) after your prediction and [the drills](DRILLS.md) for varied practice.
Worked example
labs/secret-handling/WORKED-EXAMPLE.md
# Worked example: Trace dummy secret exposure through config, diffs and logs Open this after saving a prediction for the guided case. The reference explains these fictional records; it does not assess your independent performance. 1. Read `app-config.txt`, `change-diff.txt` and `debug-log.txt` with their audience fields. Current config uses a store reference for the export value, but this is only one possible copy. 2. `export-token` occurs at `change-diff.txt:L1` in a removed line and at `debug-log.txt:L2`. Their audiences are shared and public. The supplied state is active. Use `contain;revoke-and-replace;clean-copies;review-use`. Deleting the config line did not invalidate the value or erase retained copies. 3. `local-token` occurs only at `app-config.txt:L2` with audience local. Use `relocate-before-sharing`. Do not paste the value into a real report. 4. `unused-token` has no exact listed occurrence: `not-seen-in-supplied-artifacts`. This does not establish it was never exposed or that these files are secret-free. A handover can cite IDs and locations without reproducing credential text. Explain that access restriction and revocation/rotation address ongoing misuse; cleaning history and logs then addresses retained copies. Review use for evidence of earlier access. All these are proposed steps for dummy evidence, not actions performed by the command. After comparison, keep your original prediction and add a correction in `notes.txt`. State the evidence that changed your judgment. Copying the answer without reconstructing the evidence leaves independent understanding unassessed.
Practice drills
labs/secret-handling/DRILLS.md
# Practice progression: Trace dummy secret exposure through config, diffs and logs Use the exact prepare/show/check commands in [README.md](README.md). Save a prediction before running `analyse`. Fresh folders preserve earlier attempts. 1. **Guided (10 minutes):** read all three artifacts, record audience and line number, then save a proposed remediation sequence before viewing the example. 2. **With prompts (5 minutes):** Does a removed diff line remain readable? Does redacting one log revoke a credential? Can you report locations without values? 3. **Independent (10 minutes):** use `challenge`. Distinguish APP from APP_LONG. Manually flag the unlisted dummy value on `package-log.txt:L2`; explain why the analyser does not report it and what that says about scanner coverage. 4. **Changed evidence (5 minutes):** use `changed`. Why does a revoked value still need attention in a retained diff? In a practice copy change only its state back to active, predict the sequence, and check it. Do not edit originals. 5. **Teach back (5 minutes):** explain deletion, redaction, revocation and rotation using the dummy case. State which action actually invalidates access. 6. **Later recall (next day, 5 minutes):** name three exposure paths beyond the current config and two things an exact-marker scan cannot establish. For each pass record: evidence references, decision, reason, uncertainty, help used and one next check. Have another person review the explanation and one unfamiliar case if possible. Until that occurs, independent completion is unassessed even if every decision matches. Keep all attempts below `run/`.