Chapter 21 — Authorized offensive security and red team: requirements
Lesson map
Lesson 21 published. Map, example, EX061.
flowchart TD
N0["Learning outcomes"]
N1["21.1 Sources of requirements"]
N2["21.2 Three families"]
N3["21.3 Acceptance criteria"]
N4["21.3b Requirement ids in code"]
N5["21.1b MoSCoW under safety"]
N6["Practice note"]
N7["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
N7 --> EX["Worked example"]
EX --> Q["Exercise EX061"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["21.1 Sources of requirements"]
N2["21.2 Three families"]
N3["21.3 Acceptance criteria"]
N4["21.3b Requirement ids in code"]
N5["21.1b MoSCoW under safety"]
N6["Practice note"]
N7["Synthesis"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX061"]
[Learning outcomes]
|
v
[21.1 Sources of requirements]
|
v
[21.2 Three families]
|
v
[21.3 Acceptance criteria]
|
v
[21.3b Requirement ids in code]
|
v
[21.1b MoSCoW under safety]
|
v
[Practice note]
|
v
[Synthesis]
|
v
[Worked example] --> [Exercise EX061]
Learning outcomes
You will (1) elicit requirements from ROE and operators; (2) separate functional, safety and measurement requirements; (3) write acceptance criteria a tester can run.
21.1 Sources of requirements
Operators want fewer false blocks; counsel wants an audit trail; the client wants clear findings. Elicitation interviews produce shall-statements tagged by source. Conflicts (speed vs approval gates) are recorded, not papered over.
Tagged sources make conflicts discussable: speed versus gates is a recorded trade-off with an owner. Papering over it produces a tool nobody trusts. Sam keeps the conflict log next to the requirements file so a new lead can see old arguments without replaying them. Each conflict entry names who raised it and which shall-statement settled it.
21.2 Three families
Functional: "TrackScope evaluates allowed(host,port) before every action." Safety: "TrackScope fails closed if the policy file does not load." Measurement: "PulseMap reports planned-vs-observed technique counts with denominators." Safety requirements win ties.
Safety winning ties means a fast path that skips policy load is rejected even if testers cheer. Measurement requirements force denominators so coverage cannot be a bare count. Functional requirements name the moment of check, such as before every action. Sam colours safety rows in reviews so they cannot be bargained down quietly.
21.3 Acceptance criteria
Each requirement has a Given/When/Then on synthetic data. Example: Given deny-list {10.20.0.1}, When probe 10.20.0.1:443, Then DENY deny-list and an event is stored. Criteria that need a real client network are rejected at review.
Synthetic case — Riverstone Transit. Safety requirement S-3 "fail closed on missing policy" failed its acceptance test when a typo path returned ALLOW. The fix shipped before any engagement use.
Synthetic Given/When/Then keeps CI honest and keeps client networks out of the test bed. Criteria that need production are redesigns, not stretch goals. The deny-list example is copied into TrackScope's suite as a named test. Sam fails review when a Must requirement lacks such a criterion.
21.4 Errors and limits
Stakeholders invent requirements mid-engagement; park them in a backlog with an authorization ticket, do not hot-patch production TrackScope during a live test window.
Hot-patching TrackScope mid-window risks a fail-open mistake while traffic is flowing. Backlog plus authorization ticket is the only path for new ideas during a test. Sam's on-call script says no production config changes except stop and revoke. Feature ideas raised in the war room go to the ticket queue the same hour, still untouched in production until a signed change lands after the window.
21.3b Requirement ids in code
Put requirement ids in test names and in log fields (req=S-3). When an incident happens, searchability beats a slide that once mapped requirements to modules. Dead requirements without tests should fail CI.
Searchable ids turn an incident channel into an index. Tests named for dead requirements fail CI until someone deletes or replaces them. Log fields carry the same ids so a deny event points at S-3 without a slide deck. Sam greps for req= in incident reviews before assigning blame.
21.1b MoSCoW under safety
Must/Should/Could prioritization still places all safety requirements in Must. A Could that weakens Must (optional deny-list) is reclassified or rejected. Product managers do not outvote fail-closed.
Optional deny-lists are not Could items; they break Must. Product managers who want a demo mode that loads without policy get a recorded refusal. Sam's prioritization board has a hard swimlane for safety Musts that cannot be dragged to Should. Demo modes that skip policy load are closed as wontfix with a link to this rule.
Practice note
Acceptance tests are named after requirement ids and fail CI when skipped. A dashboard of requirements without tests is reviewed weekly in studio. Orphan Must requirements are either tested or formally deferred with an executive owner — silence is not deferral. This habit is what turns a requirements spreadsheet into something that still matters on the Friday before an engagement.
Exercises
- EX061 — Elicit. Write one functional and one safety shall from "we must never hit the gateway." Rubric: 3 = both testable; 2 = one; 1 = vague; 0 = none.
- EX062 — Acceptance. Give Given/When/Then for fail-closed on missing policy. Rubric: 3 = complete with expected DENY/error; 2 = partial; 1 = idea; 0 = none.
- EX063 — Conflict. Speed vs dual approval for scope widening — record the conflict and the chosen rule. Rubric: 3 = conflict named + safety-first rule; 2 = rule only; 1 = picks speed; 0 = none.
Synthesis
Requirements come from people, split into families, and ship with acceptance tests on synthetic fixtures.
Continue studying — chapter 21 of 50
← Chapter 20 (draft) · Course chapter index · Chapter 22 (draft) →