confirming-pentest-authorization

Check ROE metadata types, time windows, an optional signer allowlist, and literal target inclusions and exclusions before a penetration test. This checks structure, not signature authenticity or legal permission. Use when starting an engagement, reviewing a scope change, or checking a target before scanning. Trigger with "confirm authorization", "verify ROE", "check pentest authz", or "pre-flight authorization".

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.33.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

Check a local Rules of Engagement (ROE) file before handing targets to a scanner. Validate required metadata types, offset-aware timestamps, the current window, an optional signer allowlist, and literal target inclusions and exclusions. A malformed input or blocking finding returns nonzero even when a display filter hides that finding.

This is a structural check, not signature verification, ownership proof or legal authorization. Retain separately confirmed approval and signature verification evidence with the ROE. Active scanners still need to enforce resolved targets and redirects; this checker performs no network requests.

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, in_scope_targets, time_window, emergency_contact, 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 time_window.start / time_window.end (legal)
Time window not yet active HIGH current time before time_window.start (legal)
In-scope target list empty HIGH in_scope_targets field present but empty (legal)
Target excluded or outside declared scope CRITICAL an explicit exclusion intersects the requested target, or no inclusion contains it (scope)
Stale ROE (>30 days from sign date) MEDIUM last_signed_at older than 30 days; suggests refresh (operational)
Structural checks passed INFO No blocking metadata or literal-scope finding; authenticity remains unverified (structural result)

Prerequisites

  • Python 3.9+; PyYAML for YAML inputs, or use JSON without PyYAML
  • 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

Required blocks must be mappings and target sections must be lists. Timestamps need an explicit UTC offset; the start must precede the end. A wildcard such as *.acme.example matches descendant labels, not notacme.example or the apex acme.example. Add the apex explicitly if approved. Exclusions take precedence. Use literal, non-credentialed URLs without queries, fragments, encoded paths or dot segments; unsupported entries are rejected.


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/<client>-<date>/roe.yaml.

Step 2 — Run the verification


python3 "${CLAUDE_PLUGIN_ROOT}/skills/confirming-pentest-authorization/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

Save the structural report alongside the ROE and independently verified approval/signature evidence. The report alone does not establish permission; it becomes one part of the engagement evidence chain (see recording-pentest-engagement for the storage pattern).

Examples

Example 1 — Pre-flight check before any scan


python3 "${CLAUDE_PLUGIN_ROOT}/skills/confirming-pentest-authorization/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 "${CLAUDE_PLUGIN_ROOT}/skills/confirming-pentest-authorization/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 "${CLAUDE_PLUGIN_ROOT}/skills/confirming-pentest-authorization/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 means no blocking structural finding, 1 means a blocking finding, and 2 means an input/read error. --min-severity changes display only; it cannot change a blocking exit code.

Each finding uses the shared schema: skill_id, title, severity, target, detail, remediation, and optional evidence/enrichment fields.

Error Handling

  • Missing, unreadable, malformed or non-mapping ROE: nonzero structured result.
  • Wrong block types, invalid/naive timestamps, reversed windows, unsupported targets or exclusions: blocking findings; no positive authorization claim.
  • An explicitly requested or existing signer file must be readable and nonempty. An absent default signer file permits structural checking only and emits an informational limitation.
  • Signature metadata is checked for required text and a valid signing time. It is not cryptographically verified. Run the appropriate independent verification process before treating the underlying attestation as genuine.

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?