Methodology

An Authorization Gate for Active Scanning: Safe by Construction

Fw
Nick Falshaw
||10 min read

Every active scanner — nmap, httpx, nuclei — is a loaded tool. Pointed at a system you own or are authorized to test, it is reconnaissance. Pointed at one you are not, it is, in most jurisdictions, an offence. The only thing between those two outcomes is authorization, and in most security tooling authorization is a box a human ticked once — not a control the software enforces on every single scan. This post documents a different design: an architecture where “authorized and in scope” is a gate the system refuses to pass unless the conditions actually hold at the moment the scan is launched.

The pattern came out of building a platform where one operator scopes the engagement, runs the recon, and signs the report. That convenience is also the hazard: nothing stops a tired consultant from pasting the wrong host into the right tool at the wrong time. So authorization had to stop being a matter of discipline and become a matter of architecture — something the system can refuse, not just something the operator is supposed to remember.

Authorization has to be a control, not a comment

Rules of engagement usually live in a PDF: a signed scope, an IP range, an exclusion list, a test window. The scanner never reads that PDF. The gap between the document that grants authority and the tool that exercises it is where out-of-scope scans happen — not through malice, but through a fat-fingered hostname, a stale target list, or a scan kicked off after the window closed.

Closing that gap means encoding the rules of engagement as data the software checks, and refusing the scan when the check fails. The scope, the exclusions, and the engagement phase stop being prose and become a precondition. The operator no longer has to remember the boundary; the system will not cross it.

The first control: the app cannot scan

The web application that drives all of this runs with a read-only root filesystem and every Linux capability dropped. That is ordinary container hardening — but here it has a second purpose. A process that cannot write to disk and holds no capabilities cannot meaningfully spawn and operate a port scanner. The app is structurally incapable of scanning, and that is deliberate.

Active scanning is therefore delegated to a separate worker container over a queue. The app validates and enqueues; the worker — which lives on its own egress-only network with no inbound ports — picks the job up and runs the tools. The separation is itself the control: a bug in the web tier, or even a compromised request handler, still cannot reach a scanner directly. The only path to nmap runs through the queue, and the only thing allowed onto the queue has passed the gate.

The gate: four conditions, and exclusions always win

A scan request is refused unless every one of the following holds:

  • In scope.The target matches a scope entry on the engagement — a domain (subdomains included), a CIDR range (CIDR-matched, not string-compared), or a named application.
  • Not excluded. The target matches no exclusion entry. Exclusions always win: if a host is both inside an in-scope range and on the exclusion list, it is out. There is no override.
  • Active engagement.The engagement is in an ACTIVE or REPORTING phase — never while it is still being scoped, or after it has been delivered or closed.
  • Explicit consent. The request carries an explicit authorize flag. A scan is never the incidental result of clicking around; it is an affirmative step.

No scope defined means no scan — the absence of an authorization is treated as a denial, not as a blank cheque. And the matched scope is snapshotted onto the job along with the identity of the user who launched it. The authorization is frozen at launch time, so an engagement edited later cannot retroactively change what a past scan was permitted to touch.

Defense in depth: the worker assumes the gate is wrong

The worker is not a trust boundary. It executes whatever authorized job the gated app hands it — so it is built as if the gate could be wrong. Even with a valid job, it runs nmap as a TCP connect scan (-sT, no raw sockets, no NET_RAW capability), and it excludes the dos, intrusive, and brute-force nuclei template families outright. Hard timeouts bound every tool. The result is two independent layers: the gate decides whether a scan may happen at all, and the worker constrains how much damage a scan can do even if the gate ever let something through.

What the audit trail buys you

Because the gate snapshots the authorizing user, the matched scope, and the timestamp onto every job, the system can answer the one question that matters after the fact: “why did you scan this host?” The answer is a record, not a recollection — the engagement it belonged to, the scope entry that authorized it, the person who launched it, and when. That record is the difference between a defensible engagement and an awkward email.

It also makes the boundary auditable in advance. A reviewer can read the scope and the exclusions and know what the system will and will not do, without trusting that the operator will behave. The control is inspectable, not aspirational.

The same shape generalizes

Active scanning is the sharp example, but the shape is reusable wherever software can take an action with real-world consequences: separate the component that decides from the component that acts; make the deciding component refuse by default; snapshot the authorization onto the action for audit; and build the acting component as if the decision could be wrong. It is the same least-privilege, defense-in-depth discipline that firewall change management has always required — applied to the tooling itself rather than to the rules it manages.

Why it matters

The cheapest place to stop an out-of-scope scan is in the software, before the first packet leaves the host. Relying on the operator to remember the rules of engagement works right up until the one time it doesn’t — and in security testing, that one time is the time that ends up in a lawyer’s inbox. Encoding authorization as an enforced control turns “we were careful” into “the system would not let us,” which is a far better sentence to say to a client, an auditor, or a court.

About the Author

Nick Falshaw is a Principal Security Architect with 17+ years in enterprise firewall and network security across DAX-30 customers, KRITIS-regulated operators, and EU financial-services firms. He is the author of the FwChange methodology, derived from the analysis of 280+ firewall migrations.

Author and Methodology Behind FwChange

FwChange is built and authored by Nick Falshaw, drawing on 17+ years of enterprise firewall experience and 280+ migrations. Read the methodology behind the platform.

Stay Updated

Get firewall management tips, compliance guides, and product updates.

No spam. Unsubscribe anytime.

Fw

Nick Falshaw

Principal Security Architect & AI Systems Engineer. 17+ years of enterprise firewall and network security across DAX-30 and KRITIS-regulated operators. Author of FwChange and the 280-migrations dataset.

Work with the Architect Behind FwChange

Nick Falshaw — 280+ enterprise firewall migrations, AI-assisted change management methodology. Read the methodology or get in touch.