Chapter 41 — Authorized offensive security and red team: system optimization
Lesson map
Lesson 41 published. Map, example, EX121.
flowchart TD
N0["Learning outcomes"]
N1["41.1 Profile first"]
N2["41.2 Constraint-preserving"]
N3["41.3 Safety veto"]
N4["41.2b Load shedding"]
N5["41.3b Capacity headroom"]
N6["41.1b N+1 queries"]
N7["Practice note"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
N7 --> EX["Worked example"]
EX --> Q["Exercise EX121"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["41.1 Profile first"]
N2["41.2 Constraint-preserving"]
N3["41.3 Safety veto"]
N4["41.2b Load shedding"]
N5["41.3b Capacity headroom"]
N6["41.1b N+1 queries"]
N7["Practice note"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX121"]
[Learning outcomes]
|
v
[41.1 Profile first]
|
v
[41.2 Constraint-preserving]
|
v
[41.3 Safety veto]
|
v
[41.2b Load shedding]
|
v
[41.3b Capacity headroom]
|
v
[41.1b N+1 queries]
|
v
[Practice note]
|
v
[Worked example] --> [Exercise EX121]
Learning outcomes
You will (1) profile assessment pipelines ethically; (2) optimize under ROE constraints; (3) reject optimizations that weaken safety.
41.1 Profile first
Measure where time goes: DNS, TLS handshake, predicate eval, ticket write. Optimize the dominant term. Synthetic load only.
Optimizing ticket writes when TLS handshake dominates wastes the week and can tempt unsafe shortcuts. A profile on synthetic load that names the dominant term keeps the team honest. Sam posts the flame graph next to the change proposal so reviewers see why a cache was chosen over a faster JSON library. Without that graph, debates about caches become taste contests. Sam rejects optimisation PRs that lack a dominant-term citation from a fresh profile.
41.2 Constraint-preserving
Caching ScopeVersion is fine if invalidation on publish is correct. Caching allow decisions across hosts is not — hosts differ.
A cached ScopeVersion that survives a publish is a fail-open bug with a performance excuse. Invalidation must be part of the publish path and tested. Caching allow decisions across hosts is worse, because deny-lists and hours differ. Sam's cache tests include a publish mid-load that must flip a previously allowed target to deny within the stop bound. A cache that cannot pass that mid-load publish test never ships.
41.3 Safety veto
Any optimization that skips deny-list checks, shortens audit fields or fails open is rejected regardless of speedup.
"""Rank synthetic assets for authorized engagement scoping."""
assets = [
("public-web-portal", 3, 3, 3), # exposure, data_sensitivity, blast_radius 1-3
("staging-admin-ui", 2, 3, 2),
("corp-vpn-edge", 3, 2, 3),
("internal-wiki", 1, 2, 1),
("printer-fleet", 2, 1, 1),
("lab-jump-host", 1, 1, 2),
]
print(f"{'asset':20} score exposure data blast")
for name, e, d, b in sorted(assets, key=lambda x: -(x[1]+x[2]+x[3])):
print(f"{name:20} {e+d+b:5} {e:8} {d:4} {b:5}")
Expected output:
asset score exposure data blast
public-web-portal 9 3 3 3
corp-vpn-edge 8 3 2 3
staging-admin-ui 7 2 3 2
internal-wiki 4 1 2 1
printer-fleet 4 2 1 1
lab-jump-host 4 1 1 2
Synthetic case — Riverstone Transit. Caching signed policy in memory cut latency 40%; invalidation on publish kept safety. A proposal to skip deny-list for "known good" hosts was vetoed.
The forty percent latency cut from caching signed policy was accepted only because publish invalidation was proven. A proposal to skip deny-list checks for "known-good" scanners was rejected with this veto, regardless of the speedup slide. Sam's ADR for the cache quotes both the gain and the invalidation test id.
41.4 Errors and limits
Benchmarks on laptops do not predict depot links (Chapter 3).
A laptop gigabit link hides serialisation costs that a 10 Mb/s depot uplink makes obvious. Benchmarks used for ROE headroom must use the physics chapter's link assumptions or measured client rates. Sam refuses a pool-size increase justified only by laptop numbers. The same rule blocked a burst increase that would have saturated a depot uplink in the physics worked example. Headroom math that ignores the 1.2 ms serialisation example from the depot uplink is sent back.
41.2b Load shedding
Under overload, shed discovery work before shedding deny evaluation. Users can wait for a scan; they cannot wait for a deny that never comes. Implement priority queues accordingly.
Priority queues that drop deny evaluation under load invert the safety model. Sam's shed tests push synthetic load until discovery queues grow, then assert every predicate still runs and returns within the latency budget. Shedding discovery shows up as a planned-not-seen rise in PulseMap, which is preferable to a silent allow. The shed order is written in the ADR, so a later tuning change cannot quietly reverse it.
41.3b Capacity headroom
Keep headroom under the ROE limit so a retry storm (Chapter 32) does not breach it. If the ROE allows 5 req/s, engineer for 3–4 sustained. Document the headroom assumption.
Engineering for 3–4 req/s under a 5 req/s ROE leaves room for the retry storms measured in the reliability work. Documenting that assumption stops a later engineer from "using the unused 20 percent" in a speed project. Sam's capacity sheet shows ROE limit, engineered sustained rate and retry budget on one line. Using the unused twenty percent requires a ROE edit, not a performance ticket.
41.1b N+1 queries
Chatty ticket updates during bulk import crush FindingsDesk. Batch writes and measure. Performance work often starts as an integration bug, not as a need for exotic caches.
Bulk import that updates tickets one HTTP call at a time will look like a need for exotic caches when the real fix is batching. Measure FindingsDesk write patterns before adding Redis. Sam's import path sends chunks of fifty and failed a review that reintroduced per-row upserts for "simpler code." The simpler code argument lost to a profile that showed ninety percent of time in per-row HTTP.
Practice note
Optimization proposals require a safety paragraph: which checks still run, which are skipped, how fail-closed is preserved. Proposals without that paragraph are returned unread. Speed reviews that ignore safety paragraphs have caused more ROE breaches than slow scanners ever did.
Reject optimization PRs that remove reason codes from logs even if latency improves.
Benchmarks cite the ROE limit next to the achieved rate so unconstrained benches are obvious.
41.4b Recording optimisation decisions
Each optimisation is recorded with the profile that justified it, the measured gain and any safety check it touched. When a later change slows a path, the record shows whether the earlier speed-up depended on an assumption that no longer holds.
Without the profile and the safety checks beside the gain, a regression looks like bad luck instead of a broken assumption. Sam's optimisation log for the policy cache notes the 40% cut, the invalidation test and the vetoed deny-list skip, so a future slowdown is diagnosed against facts.
Exercises
- EX121 — Veto. Give an optimization that must be rejected. Rubric: 3 = safety-weakening example; 2 = vague; 1 = okays it; 0 = none.
- EX122 — Cache. When is decision caching safe? Rubric: 3 = same ScopeVersion+target+context, short TTL, invalidate on publish; 2 = partial; 1 = always; 0 = none.
- EX123 — Inventory. Why optimize scheduling with scores? Rubric: 3 = limited window → highest exposure first; 2 = vague; 1 = random; 0 = none.
Synthesis
Speed under constraints; safety has veto power.
Continue studying — chapter 41 of 50
← Chapter 40 (draft) · Course chapter index · Chapter 42 (draft) →