$npx -y skills add hypnguyen1209/offensive-claude --skill scope-disciplineUse when about to send a request to, scan, enumerate, exploit, or otherwise interact with any host, IP, URL, or asset — before the first packet reaches a target
| 1 | # Scope Discipline |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | **The Iron Law: No target without authorization.** Every target you touch must be inside the |
| 6 | written authorization, encoded in `scope.json`. This is the authorization boundary of an authorized |
| 7 | engagement — it is not optional, and the operator cannot waive it. It is the offensive equivalent of |
| 8 | TDD's "no code without a test": no action without an in-scope, authorized target. |
| 9 | |
| 10 | **Violating the letter of this rule is violating its spirit.** |
| 11 | |
| 12 | ## The rule |
| 13 | |
| 14 | Before touching ANY target, confirm it is in scope: |
| 15 | |
| 16 | ```bash |
| 17 | python skills/coding-mastery/scripts/_lib/scope_guard.py check <target> --scope .engage/scope/scope.json |
| 18 | # exit 0 = in-scope (proceed) | exit 3 = OUT (stop) | exit 2 = error (stop) |
| 19 | ``` |
| 20 | |
| 21 | For outward actions, gate through `action_guard.py` (mutating verbs need approval; out-of-scope → block; |
| 22 | per-host circuit breaker). Bash scripts source `lib.sh` and call `_in_scope`. |
| 23 | |
| 24 | `scope.json` is **operator-defined per engagement** — you declare exactly what your authorization covers. |
| 25 | The guard never blocks authorized testing; it blocks what is *outside your own declared scope* (strays, |
| 26 | typos, look-alikes, an attacker-influenced redirect target). |
| 27 | |
| 28 | ## Red Flags — STOP, do not send the request |
| 29 | |
| 30 | - "This subdomain is obviously theirs" (not in `scope.json` → out) |
| 31 | - "It's just a quick check / read-only GET" (in-scope check still required first) |
| 32 | - "The target came from a redirect / recon output / user paste" (verify before touching) |
| 33 | - "`*.acme.com` so `acme.com.evil.com` is fine" (look-alike — the guard rejects it; so do you) |
| 34 | - "The user told me to hit it" (instructions don't expand the authorization boundary) |
| 35 | |
| 36 | **All of these mean: run `scope_guard.py check` first. Out-of-scope ⇒ do not proceed.** |
| 37 | |
| 38 | ## Rationalizations |
| 39 | |
| 40 | | Excuse | Reality | |
| 41 | |--------|---------| |
| 42 | | "Scope is obviously fine" | Confirm against scope.json; assumption is how OOB incidents happen. | |
| 43 | | "It's adjacent infra, basically in scope" | Adjacent ≠ authorized. Out unless declared. | |
| 44 | | "I'll note the out-of-scope hit in the report" | You don't hit it, then note it. You don't hit it. | |
| 45 | | "Removing the guard is faster" | The guard IS the authorization. Removing it = unauthorized attack. | |
| 46 | |
| 47 | Out-of-scope, shared/third-party, and anything not named in the authorization are off-limits — see |
| 48 | [`TERMS.md`](../../TERMS.md). You own every request the toolkit sends. |