Engagement, RoE & kill switch

Machine-readable Rules of Engagement, fail-closed start, global deny-list, approvals, time windows and the kill switch — how Rank authorizes and stops a run.

Rules of Engagement

A Rules of Engagement (RoE) is the legal and operational scope of a pentest. Assets are inventory; the RoE is what agents are allowed to do to that inventory. You create versions with POST / PUT /pentests/{id}/roe and promote one by sending activate: true.

At least one of allowed_cidrs or allowed_domains must be non-empty. Activation fails if any pentest asset sits outside that allow-list.

{
  "allowed_domains": ["example.com"],
  "allowed_cidrs": ["203.0.113.0/24"],
  "denied_cidrs": ["203.0.113.7"],
  "denied_domains": ["intranet.example.com"],
  "allowed_techniques": ["T1190"],
  "forbidden_techniques": ["T1486"],
  "time_windows": [{"start": "20:00", "end": "06:00", "days": ["mon", "tue", "wed", "thu"]}],
  "timezone": "Europe/Madrid",
  "max_rps": 20,
  "max_concurrency": 4,
  "source_ips": ["198.51.100.10"],
  "asset_criticality": {"api.example.com": "critical"},
  "authorization_ref": "ENG-2026-0042",
  "escalation_contacts": [{"type": "email", "value": "security@example.com"}],
  "requires_approval_for": ["exploit", "destructive"],
  "auto_approve": false,
  "activate": true
}
FieldRole
allowed_cidrs, allowed_domainsAuthorized reach. At least one list must be non-empty.
denied_cidrs, denied_domainsExclusions. They win over the allow-lists.
allowed_techniques, forbidden_techniquesATT&CK techniques (T1190 or T1190.001).
time_windows, timezoneWhen work is allowed. start / end are HH:MM (24 h); days is "all" or mon…sun. A window whose end is earlier than start crosses midnight. timezone is an IANA identifier and is required when windows are set. No windows means 24/7.
max_rps, max_concurrencyRate limits. null means the RoE does not declare one.
source_ipsDeclarative source addresses so the client can allow-list the audit. They do not constrain reach.
asset_criticalityHost → critical | high | medium | low | info.
authorization_refRequired. Reference to the signed authorization (max 255 characters).
escalation_contactsRequired, non-empty. Each entry has type (email, slack or webhook) and value.
requires_approval_forAction classes that wait for a human (see below).
auto_approveIf true, listed classes (except scope_expansion) are recorded as auto-approved instead of waiting. Default false.
activatePromote this version now.

CIDR width

Public IPv4 allow-list CIDRs must be /16 or narrower; public IPv6 /32 or narrower. A bare host (no prefix) is always accepted. Private ranges are exempt (a whole 10.0.0.0/8 or fc00::/7 is valid; /0 is not). Deny-lists and source_ips have no width cap — 0.0.0.0/0 as a denial is legitimate.

Fail-closed start

There is no implicit “everything is in scope.” Without an active RoE the pentest does not start. The orchestrator treats that as no_active_roe, not as a retryable error. Saving a version without activate: true does not authorize a run.

A Rank-operated global deny-list (administrations, critical infrastructure, third-party domains) is merged into the denied CIDR and domain lists the runtime sees. You cannot edit it. Deny always wins, including deny-list TLD patterns and keywords that have no RoE equivalent.

Approvals

Restricted actions pause until someone decides them. Classes:

ClassWhat waits
shellInteractive or one-shot shell (shell_tool)
scriptInterpreter scripts (script_tool)
destructiveShell or script whose payload looks destructive
exploitActive exploitation tools (sqlmap, hydra, Metasploit, and similar)
scope_expansionWidening the active RoE of a pentest that is already running
low_scope_confidenceAn action whose target could not be matched confidently to the authorized scope

scope_expansion is never auto-approved. Tightening a running RoE does not need approval; widening it (new allow entries, removing a deny or a forbidden technique, dropping time windows) does. List pending items with GET /pentests/{id}/approvals and decide with POST /pentests/{id}/approvals/{approvalId}/decide.

Kill switch

POST /pentests/{id}/kill
{"reason": "Out of authorized window"}

Kill is a terminal control flag: the orchestrator must stop, evidence is preserved, and the pentest cannot return to an active state. It is not a lifecycle status of its own.

Cancel is different: it asks the Go streaming backend to stop the current stream (POST https://aleex.aleex-rank.ai/pentest/{id}/cancel). Use cancel to detach a run you started; use kill for an emergency halt.

Window warnings

If the RoE declares time_windows, the running stream emits window warnings as the close time approaches. When the window is closed, the orchestrator stops fail-closed — it does not keep working “just a bit longer.” A RoE with no windows is 24/7.

Go deeper