Offline security exercise / source reading
Build a cloud audit evidence timeline
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/cloud-audit-triage/
Lab instructions
labs/cloud-audit-triage/README.md
# Build a cloud audit evidence timeline Correlate identity, session, action and result while preserving uncertainty. Separate a denied attempt from a successful change, recognise missing logging and avoid attributing a session to a person from a label alone. **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:** **Audit event**: a record of an attempted action and its result. **Correlation**: a supported link between records. **Attribution**: identifying who actually acted. **Management event**: a change or identity operation. **Data event**: an object operation. **Coverage gap**: activity types not reliably recorded. ## Evidence and exact semantics This is a **fictional schema**, not provider log JSON. `data` has UTC `window_start`, `window_end`, `logging` (Boolean `management` and `data`), `approved_changes`, and nonempty `events`. Logging is the coverage configuration at the start of the window. Event fragments can still exist for a disabled category; a fragment never proves full coverage. Every event has unique `id`, `at`, `identity`, `session`, `action`, `result`, and `resource`. All IDs are lowercase labels, not real account identifiers. Action is `sign-in`, `read-object`, `change-policy`, or `disable-logging`; result is `success` or `denied`. Sign-in resource must be `identity-service`. Read-object is a data action; the others are management actions. `logging` is reserved for the extra coverage decision. Timestamps use exactly `YYYY-MM-DDTHH:MM:SSZ` and must lie inside the inclusive window. The window must increase. An approval has exactly `identity`, `action`, `resource`, `from`, `to`; only change-policy/disable-logging actions can be approved. Both approval boundaries are inclusive. Correlation requires a successful sign-in with equal identity **and** session at or before the action, at most 15 minutes earlier, inclusive. Input order is not trusted; output observations are sorted by time then ID. Use these exact labels for event IDs, with the first applicable rule winning: | Label | Rule | | --- | --- | | `denied-no-success-evidence` | Result denied; this record does not establish a successful change. | | `authentication-only` | Successful sign-in; no downstream action established by this record alone. | | `successful-action-unattributed` | Successful non-sign-in without the required correlation. | | `successful-read-correlated` | Successful object read with correlation. | | `approved-change-correlated` | Successful correlated change matching identity/action/resource and approval window. | | `unapproved-change-correlated` | Successful correlated change without that approval match. | For the extra `logging` decision use `coverage-configured` when both categories are enabled, otherwise `coverage-gap:ITEMS` where ITEMS is `data`, `management`, or `data,management` in that order. Append `;interruption-observed` whenever any successful disable-logging event appears, regardless of approval or correlation. A denied disable event never adds that suffix. Configured coverage is not proof that every event was delivered. ## Run the exercise From the repository root, enter this folder with `cd labs/cloud-audit-triage`. 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 The model does not parse a real cloud log, validate cryptographic provenance, infer intent, account for every authentication route, restore logging or query a service. The arbitrary 15-minute correlation window is a teaching boundary. Unattributed means insufficient supplied linkage, not proof of malicious activity. ## Primary references The official record reference demonstrates time, identity, action and result-related evidence in real audit records. This lab uses smaller fictional names and deliberately avoids claiming provider parsing or complete event coverage. - [AWS CloudTrail: event record contents](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-event-reference-record-contents.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/cloud-audit-triage/WORKED-EXAMPLE.md
# Worked example: Build a cloud audit evidence timeline Open this after saving a prediction for the guided case. The reference explains these fictional records; it does not assess your independent performance. 1. Sort the timeline. `e01` at 10:00 is a successful sign-in for `operator` and `session-a`: `authentication-only`. 2. `e02` at 10:02 has the same identity/session, but `result=denied`. Use `denied-no-success-evidence`; correlation does not turn failure into success. 3. `e03` changes `poster-bucket` at 10:03. It is three minutes after `e01` and matches the approval's identity, action, resource and 10:00-10:10 window. Use `approved-change-correlated`. 4. `e04` reads `rota-object` at 10:04 and links to `e01`, so use `successful-read-correlated`. It is not evidence that the read was authorised by a data-access approval: this model does not include those approvals. 5. `e05` has a different identity and session with no matching supplied sign-in. It succeeds, so use `successful-action-unattributed`. Do not invent a person. 6. `e06` successfully disables logging, links to `e01` and has no approval. Use `unapproved-change-correlated`. The `logging` decision is `coverage-gap:data;interruption-observed`: initial data coverage was false, and the later successful disable adds interruption evidence. The existing `e04` fragment does not fill the data gap. A sound handover asks for the missing coverage and change-authorisation evidence while distinguishing known successes, denied attempts and uncertainty about unrecorded activity. 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/cloud-audit-triage/DRILLS.md
# Practice progression: Build a cloud audit evidence timeline 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):** make a timeline with ID, identity, session, action, result and possible sign-in link. Predict labels before the worked example. 2. **With prompts (5 minutes):** Is the result success? Is identity as well as session equal? How many minutes elapsed? Does approval match the resource? 3. **Independent (10 minutes):** use `challenge`. Explain the 15-minute vs 16-minute result and why `x04` cannot borrow another identity's session label. 4. **Changed evidence (5 minutes):** use `changed`. Why does denied logging disablement leave `coverage-configured`? In a copy change only `c03.result` to `success` and predict both its event decision and the logging suffix. 5. **Teach back (5 minutes):** explain why successful sign-in, successful object read, and proof of a particular person's action are three different claims. 6. **Later recall (next day, 5 minutes):** reconstruct the correlation rule and state what an absent record can and cannot establish with incomplete logs. 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/`.