Offline security exercise / source reading
Trace a storage exposure path
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-storage-review/
Lab instructions
labs/cloud-storage-review/README.md
# Trace a storage exposure path Practise tracing anonymous read access through two grant routes and three blocking controls. Explain the difference between an effective exposure and a dormant grant that could reappear after a setting changes. **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:** **Bucket**: a container of objects. **Policy**: rules granting or denying access. **ACL**: another permission list. **Anonymous read**: reading without signing in. **Dormant grant**: a grant currently blocked by another control. ## Evidence and exact semantics The case envelope is defined in [the shared contract](../FOUNDATION-CONTRACT.md). `data` contains `account_block_public` (Boolean) and a nonempty `buckets` list. Each bucket has a unique lowercase `id`; `purpose` is `internal` or `public-site`; `data_class` is `public`, `internal` or `restricted`; `approval` is `approved` or `none`. The remaining fields are Booleans: `bucket_block_public`, `policy_public_read`, `acl_public_read`, and `explicit_deny_public_read`. Unknown keys, duplicate IDs and non-Boolean flags are rejected. This is a deliberately simplified exercise model, **not an AWS evaluator**. Evaluate in this order: 1. A public grant exists when policy **OR** ACL allows public read. 2. A blocker exists when account block **OR** bucket block **OR** explicit deny is true. Any blocker overrides both grant routes here. 3. Effective public access is approved only when purpose is `public-site`, class is `public`, and approval is `approved` together. Use these exact decision strings for each bucket ID: | Decision | Exact meaning | | --- | --- | | `no-public-grant` | Neither grant exists, whether or not blockers exist. | | `blocked-public-grant` | At least one grant exists, but at least one blocker applies. | | `public-read-approved` | An effective grant and all three publication conditions exist. | | `public-read-unapproved` | An effective grant exists without all publication conditions. | An approval does not override data classification. Removing a policy grant does not remove an ACL grant. This model examines read access only. ## Run the exercise From the repository root, enter this folder with `cd labs/cloud-storage-review`. 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 Real storage services have richer policy languages, conditional access, object ownership and separate public-access settings. Do not paste this Boolean model into a provider account. A blocked grant still deserves review because later configuration changes can expose it. ## Primary references The provider documentation explains that several access routes and blocking settings interact. The exercise collapses them into named Boolean fields; it does not reproduce the four provider settings or their full evaluation rules. - [AWS: blocking public access](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.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-storage-review/WORKED-EXAMPLE.md
# Worked example: Trace a storage exposure path 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 `handover.txt`, then the four records in `data.buckets`. There is no account-wide block in the guided case. 2. `poster-site` has a policy grant, no ACL grant and no blockers. Its purpose is `public-site`, class is `public`, and approval is `approved`, so use `public-read-approved`. This says nothing about content correctness. 3. `volunteer-rota` has an ACL grant even though policy read is false. With no blocker, the internal rota is `public-read-unapproved`. Removing a nonexistent policy grant would not close this route. 4. `archive` has a policy grant and `bucket_block_public=true`, so use `blocked-public-grant`. Cite both fields; calling it grant-free loses the risk that the public grant would return after the block was removed. 5. `receipts` has no public policy or ACL grant: `no-public-grant`. Restricted classification alone is not the control producing this result. Before looking at the answer, write the expression `(policy OR acl) AND NOT (account OR bucket OR deny)` for each record. A sound handover identifies the rota exposure route and proposes checking intended access before changing a control that might also serve the public poster. No actual cloud change occurs. 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-storage-review/DRILLS.md
# Practice progression: Trace a storage exposure path 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):** complete the Boolean expression for each guided bucket. Predict decisions before opening the worked example. 2. **With prompts (5 minutes):** Which route grants the rota? Which field blocks the archive? Which three fields make the poster's exposure acceptable here? 3. **Independent (10 minutes):** use `challenge` without the worked example. Explain why `mislabelled-site` is unapproved despite its approval flag, and why the denied bucket differs from the forgotten ACL. 4. **Changed evidence (5 minutes):** use `changed`. What happens to the approved public site when account blocking is enabled? In a copied case, set only the account flag false and predict which two decisions change. Do not merely rename a bucket. 5. **Teach back (5 minutes):** explain to a teammate why "policy removed" and "public read removed" are different claims. Name one real provider feature this model omits. 6. **Later recall (next day, 5 minutes):** without the reference, reconstruct the three blockers and two grant paths. Revisit one misprediction and cite the exact field you had overlooked. 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/`.