confirming-pentest-authorization

Verify that a penetration test has explicit, written, signed authorization before any scanning begins. Reads a Rules-of- Engagement (ROE) attestation file, validates required fields (authorizer, in-scope targets, time window, emergency contact, signature), checks the signer against an allowlist, and emits a CRITICAL finding if anything is missing. Designed as the first skill the orchestrator routes to. Use when: starting a new engagement, after a scope change, or before any cluster 1-4 scan skill runs. Threshold: any missing or unsigned ROE field; any time-window expiry; any in-scope target outside the authorized list. Trigger with: "confirm authorization", "verify ROE", "check pentest authz", "pre-flight authorization".

3 Tools
penetration-tester Plugin
security Category

Allowed Tools

ReadBash(python3:*)Glob

Provided by Plugin

penetration-tester

25-skill pentest pack with engagement governance, network/code/dependency scans, OWASP Top 10 mapping, and exec-readable reporting. Heavy-hitter compliant; chain-of-custody attestable.

security v3.0.0
View Plugin

Installation

This skill is included in the penetration-tester plugin:

/plugin install penetration-tester@claude-code-plugins-plus

Click to copy

Instructions

Confirming Pentest Authorization

Overview

Penetration testing is computer access. Without explicit

authorization from the owner of the system under test, that

access is a crime — Computer Fraud and Abuse Act in the US,

Computer Misuse Act in the UK, equivalent laws everywhere

else. The line between an authorized pentester and an

unauthorized attacker is one signature on one document.

The penetration-tester pack's other skills (TLS analysis, CORS

audit, dependency CVE scan, etc.) all assume that line has been

crossed correctly. This skill is the first gate the orchestrator

routes to. It refuses to declare an engagement authorized until

a Rules of Engagement (ROE) attestation file exists, is signed,

and contains the fields any real-world legal review will look for.

This is not paranoia or paperwork theater. Engagements DO go

sideways: scope creeps mid-test, a tester probes an out-of-scope

adjacent system, an SOC team escalates a "real" attack to legal,

and the question "show us the ROE" comes up. If the ROE is in

order, the answer is "here it is." If not, the conversation gets

expensive fast.

When the skill produces findings

Finding Severity Threshold Affected control
ROE file missing CRITICAL No attestation file at the expected path (legal)
Required field missing CRITICAL authorizer, inscopetargets, timewindow, emergencycontact, or signature absent (legal)
Signature missing CRITICAL No signature_block in ROE (legal)
Signer not in allowlist CRITICAL signer email/key id not in .allowed-authorizers (legal)
Time window expired HIGH current time outside timewindow.start / timewindow.end (legal)
Time window not yet active HIGH current time before time_window.start (legal)
In-scope target list empty HIGH inscopetargets field present but empty (legal)
Out-of-scope override (manual flag) MEDIUM tester requests a target not in the in-scope list (legal)
Stale ROE (>30 days from sign date) MEDIUM lastsignedat older than 30 days; suggests refresh (operational)
ROE present + signed + in window INFO All gates pass; engagement is authorized (positive confirmation)

Prerequisites

  • Python 3.9+
  • ROE attestation file at ./roe.yaml (or pass --roe FILE).
  • Optional .allowed-authorizers file listing email addresses or

GPG key fingerprints permitted to sign ROEs.

ROE attestation file schema


engagement_id: ACME-2026-Q2-PENTEST-001
authorizer:
  name: Jane Doe
  email: jane.doe@acme.example
  role: CISO
  organization: ACME Corp
in_scope_targets:
  - host: app.acme.example
    notes: production web app, full-stack pentest authorized
  - host: api.acme.example
  - cidr: 10.50.0.0/16
    notes: internal corporate range
out_of_scope_targets:
  - host: payments.acme.example
    reason: PCI scope, separate authz required
  - cidr: 10.99.0.0/16
    reason: production database tier, separate authz required
time_window:
  start: 2026-06-01T00:00:00Z
  end: 2026-06-30T23:59:59Z
emergency_contact:
  name: SOC On-Call
  phone: "+1-555-555-5555"
  email: soc@acme.example
rules:
  - No exploitation of confirmed findings without written prompt approval
  - No password cracking against production accounts
  - All testing pauses on declared business-hours blackouts
signature_block:
  signer: jane.doe@acme.example
  signed_at: 2026-05-30T14:22:00Z
  signature: |
    -----BEGIN PGP SIGNATURE-----
    ...
    -----END PGP SIGNATURE-----

Instructions

Step 1 — Locate the ROE

The skill looks for ./roe.yaml by default. Override with

--roe FILE. The ROE file should live with the engagement

artifacts, NOT in the repo under test — typical layout is

engagements/-/roe.yaml.

Step 2 — Run the verification


python3 ./scripts/check_authorization.py --roe engagements/acme-2026-q2/roe.yaml

Options:


Usage: check_authorization.py [OPTIONS]

Options:
  --roe FILE              Path to ROE attestation YAML (default: ./roe.yaml)
  --allowed FILE          Path to allowed-authorizers list (default: .allowed-authorizers)
  --check-target HOST     Verify HOST is in the in-scope list (repeatable)
  --output FILE           Write findings to FILE
  --format FMT            json | jsonl | markdown (default: markdown)
  --min-severity SEV      Default info

Step 3 — Interpret findings

CRITICAL = engagement is NOT authorized. Halt all testing

immediately. Resolve the missing requirement before any further

skill runs.

HIGH = the engagement was authorized at some point but the

current state is out-of-window. Either extend the time window

with a new signature or wait.

MEDIUM = operational concerns that warrant attention but don't

block testing. A stale ROE should be refreshed; a manual

out-of-scope target request needs explicit additional authz.

INFO = positive confirmation that the engagement is authorized.

Step 4 — Save the result

The skill's output IS the authorization record. Save the markdown

report alongside the ROE itself; it becomes part of the engagement

evidence chain (see recording-pentest-engagement for the

storage pattern).

Examples

Example 1 — Pre-flight check before any scan


python3 ./scripts/check_authorization.py --roe engagements/acme-2026-q2/roe.yaml --format markdown
# If exit code != 0, halt testing.

Example 2 — Confirm a specific target is in-scope before probing


python3 ./scripts/check_authorization.py \
    --roe engagements/acme-2026-q2/roe.yaml \
    --check-target app.acme.example \
    --check-target api.acme.example

The skill returns an explicit INFO Finding per target if all

checks pass, and a HIGH/CRITICAL Finding per target if any are

out-of-scope.

Example 3 — Generate authorization evidence for the audit trail


python3 ./scripts/check_authorization.py --roe engagements/acme-2026-q2/roe.yaml \
    --format json \
    --output engagements/acme-2026-q2/evidence/authz-check-$(date +%Y%m%d).json

Output

JSON / JSONL / Markdown per lib/report.py. Exit codes: 0 clean,

1 high/critical (engagement NOT authorized), 2 error.

Each Finding includes:

  • idauthz:: or authz::target::
  • severity — CRITICAL / HIGH / MEDIUM / INFO
  • categoryengagement-authorization
  • summary — what's missing or wrong
  • evidence — engagement_id, authorizer email, time window, target

Error Handling

  • ROE file not found → emits a CRITICAL finding and exits 1.
  • Unparseable YAML → emits a CRITICAL finding with the parser

error and exits 2.

  • Allowed-authorizers file missing → emits an INFO finding

(allowlist is recommended but not required) and proceeds with

field-level verification only.

  • Signature block present but unparseable → emits a CRITICAL

finding flagging the issue; does NOT attempt to verify

cryptographically (separate gpg --verify step recommended for

signature validation; this skill validates the structural

presence and signer-identity claim).

Resources

  • references/THEORY.md — Why pentest authorization is a legal

primitive (CFAA, CMA, equivalent statutes), ROE structure

history (OSSTMM / PTES origins), signature options

(PGP / S/MIME / DocuSign), scope-creep failure modes

  • references/PLAYBOOK.md — ROE templates per engagement type

(external pentest, internal pentest, red team, purple team),

authorization escalation flow, time-window extension procedures,

emergency-stop protocol

Ready to use penetration-tester?