ShakerScan Functionality Reference — DAST + AI + Connected Devices
Status: Canonical exhaustive functional reference for the whole product. This is the "what can ShakerScan actually do" map across DAST, attack-surface management, AI security, evidence, governance, automation, UI, CLI, API, and agent-facing surfaces. The human-readable sections explain the behavior; the generated inventory in §17 enumerates every current public route, registry command, CLI flag, wrapper command, Make target, release gate, runtime configuration key, UI page, skill, agent, adapter, scanner module, and durable table. Reconciled: 2026-08-29 Audience: users, operators, AI coding agents, and engineers who need one place that explains the product's functionality end to end.
Source of truth. This document describes shipped behavior, grounded in the code at the time of writing. As with the sibling architecture docs, the code, DB schema, and tests remain authoritative — file paths drift, so this reference prefers named files/symbols over line numbers. Verify before depending on a detail. For implementation-depth and roadmap material, follow the cross-links in §18.
Table of contents
- What ShakerScan is
- System architecture
- DAST — one Scan, policy, and budgets
- DAST — immutable action plans and continuation
- DAST — discovery and reconnaissance
- DAST — vulnerability checks
- DAST — authentication support
- DAST — scoring, attack chains, coverage, and reports
- Scaling DAST: parallel scanning and Continuous ASM
- Attack-surface management: discovery, CT monitoring, schedules
- AI red teaming
- Cross-cutting: findings, exposure graph, workers, queue
- REST API reference (by area)
- Configuration and integrated tools
- Safety model
- UI, CLI, skills, and agent surfaces
- Generated capability inventory
- Where to go deeper
1. What ShakerScan is
ShakerScan is an open-source security scanner for web applications, APIs, AI systems, and network-connected devices. It runs locally as a Docker stack with a web UI, a REST API, a PostgreSQL database, a Redis job queue, and a scalable pool of scan workers. It is designed to be driven either directly (CLI / UI / REST) or through an AI coding agent (Claude Code, Codex, OpenCode) using plain-English requests.
It covers two complementary pillars:
- DAST — actively probes a running website or API for real vulnerabilities the way an attacker would: injection (XSS, SQLi), broken access control (BOLA/IDOR), exposed secrets and files, misconfigured TLS/headers/CORS, SSRF/LFI/RCE, weak auth/session/JWT, and more — then grades what it finds and correlates findings into attack chains.
- AI red teaming — attacks AI features the same way: chatbots, RAG endpoints, agents, and MCP tools are probed for prompt injection, sensitive-data disclosure, unsafe tool use, approval bypass, and RAG/MCP boundary failures. A separate Model Intake capability statically vets model artifacts before deployment.
The runtime boundary is simpler than the feature catalog: Scan is the one deterministic DAST workflow; Hunt is the one adaptive AI-directed investigation workflow. Hunt may choose among server-advertised semantic capabilities, but ShakerScan—not model output—owns target scope, approval, credential custody, budgets, placement, execution, evidence, recovery, and proof promotion.
Both pillars write into one shared findings store and one exposure graph, so DAST and AI results are triaged, filtered, and reported through the same workflow.
Connected-device posture is a deliberately separate plane: it inventories network services, applies device service policies, checks discovered SSH, and hands HTTP(S) interfaces on any port to bounded device-owned Web/API children without creating Web targets or changing ordinary DAST metrics.
2. System architecture
UI / CLI / agent
│ one Scan request: target + policy + budget + opaque references
▼
API admission
│ freezes target, scope, approvals, inputs, execution-plan digest
▼
immutable root action plan ── bounded continuation amendment after discovery
│
▼
shared action orchestrator
├── local worker backend
├── outbound-only broker backend
└── partitioned parallel child authority
│
▼
semantic capability adapters ── receipts / observations / budget settlement
│
▼
offline deterministic finalizer ── findings / coverage / grade reliability
Components
- API server (
api/api.py): admits the canonical request, freezes target and input authority, compiles and persists the content-addressed action plan, and serves the full product REST surface. Its six background asyncio loops maintain schedules, ASM, retention, and Model Intake workflows.stale_scan_checker— fails scans stuck beyondMAX_SCAN_DURATION.schedule_runner— fires due recurring schedules and recomputes their next run.asm_dispatcher— for each ASM-enabled target, picks one safe next action (recon vs. test batch vs. wait) within freshness/rate/window budgets.research_autopilot_runner— advances bounded compatibility research episodes.scan_artifact_retention_runner— enforces configured scan-artifact retention.model_intake_automatic_review_runner— advances durable automatic Model Intake reviews.
- Canonical Scan runtime (
api/scan/): the action compiler, allocator, durable action store, shared orchestrator, local/broker execution backends, continuation amendment, private manifest transport, and pure finalizer. This is the V2 execution authority. - Workers (
api/worker.py,api/broker_worker.py): lease only admitted jobs/actions by leasing Redis Stream messages. They resolve secrets late, revalidate scope and approval immediately before privileged work, reserve typed budget, execute one registered capability adapter, and settle a content-safe receipt. - Compatibility scanner (
scanner/scanner.py,scanner/scanner_tools/): supplies migrated detector implementations behind registered adapters. Its historical phase waterfall and mode flags are not V2 orchestration authority and must not be used to add a new Scan engine. - PostgreSQL (
db/init.sql): durable storage for scans, findings, targets, schedules, AI targets/credentials/principals, scan campaigns, the ASM endpoint inventory, attempt ledger, and discovery runs. Findings are de-duplicated at the DB withUNIQUE(target_id, fingerprint), which makes concurrent writes from many workers against one target race-safe. - Redis: delivery and coordination, never durable Scan authority. Canonical plan, action, receipt, observation, and budget state remains in PostgreSQL/object storage and survives redelivery.
- Session manager (
api/session_manager.py): headless Playwright browser sessions for interactive AI security testing. - Gungnir worker (
api/gungnir_worker.py): Certificate Transparency log monitor.
Worker scaling. Placement changes where an immutable action executes, not what it means. Local, broker, and parallel execution consume the same action schema, capability registry, budget ledger, proof contracts, and finalizer. A broker worker does not receive PostgreSQL or Redis credentials.
3. DAST — one Scan, policy, and budgets
V2 has exactly one deterministic engine: scan. Three independent inputs shape a run:
- Policy grants permission: passive-only versus active testing, state-changing HTTP, network or subdomain discovery, and family include/exclude constraints.
- Budget profile selects hard ceilings:
fast(30 minutes),balanced(60 minutes),thorough(180 minutes), or opt-indeep(360 minutes). - Opaque references select exact-target credential profiles and request-collection selections.
Cookie profiles admitted for web.browser_crawl seed the primary cookie jar in a fresh,
owner-only Chromium profile. Bearer profiles may additionally declare a nonsecret
browser_storage_key; when present, the worker seeds that localStorage key at the exact target
origin. Bootstrap navigation is fulfilled locally, the token never enters process arguments or
public receipts, and the ephemeral profile is deleted after Katana exits. Other bearer profiles
continue to authenticate HTTP-aware capabilities without guessing an application-specific browser
storage convention.
The typed budget covers duration, HTTP requests, state-changing requests, endpoints, hosts, browser
actions, TCP attempts, tool wall time, and workers. A custom value may only lower the selected
profile. max_state_changing_requests=0 is an explicit deny ceiling. Every action reserves its
multi-dimensional hold before execution and reconciles consumed, released, or uncertain authority
afterward; unused profile capacity remains visibly unallocated.
The server-generated GET /scan/contracts manifest is the public vocabulary for the UI and CLI.
The complete REST shape is frozen in docs/generated/public-openapi-manifest.json: every OpenAPI
operation ID, request/response schema digest, and component-schema digest is checked on API changes.
scripts/generate_public_api_contract.py also generates the six release-critical UI client surfaces
(Scan, Hunt, credentials, request collections, evidence, and Model Intake) from that same live
OpenAPI document. GET /hunts/contract remains the runtime Hunt policy/budget discovery endpoint.
The canonical action compiler currently implements recon, nuclei, xss, sqli, and bola.
An unsupported registry family is rejected rather than accepted as a successful no-op. Explicit
XSS, SQLi, or BOLA inclusion requires active permission; BOLA additionally requires two distinct
credential profiles whose scopes allow authz.verify.
Historical compatibility records
Historical quick, standard, deep, full, aggressive, and smart names remain readable for
audit and report continuity, but no public route or client accepts them as new authority. New UI,
API, CLI, skills, schedules, and agent flows use scan with explicit policy and budget fields.
4. DAST — immutable action plans and continuation
Admission creates a content-addressed scan-action-plan/v1 DAG. Every action records its semantic
capability, dependencies, target/input digests, requested budget, placement requirements, output
schema, and required/supporting classification. Capability arguments cannot carry secret fields,
shell commands, or planner-supplied argv.
The root plan closes deterministic prerequisites in this order:
- restore or establish any selected authenticated session;
- run bounded HTTP/DNS/TLS baseline actions;
- probe, crawl, discover content, and optionally discover subdomains/services;
- consume exact saved request selections through safe or confirmed-active replay capabilities;
- run the reviewed passive template pack;
- run policy-enabled deterministic XSS, SQLi, template, and cross-principal verifiers;
- finalize from persisted receipts and observations without target network authority.
Discovery can reveal work that did not exist at admission. V2 handles that through one bounded two-phase continuation, not a mutable plan: the root plan pre-commits a continuation allocation ceiling; discovery produces content-addressed endpoint/candidate/request/template manifests; the server appends a second digest-bound plan revision whose parent digest, family set, target, credentials, collections, approvals, and total budget cannot expand. Duplicate authority and more than 512 total actions fail closed.
The durable amendment chain stores root, parent, continuation, discovery-result, allocation, work- manifest, and revision digests. Completed terminal actions are reused after a restart. Cancellation remains distinct and never launches continuation. Safe partial receipts remain available after a timeout, while uncertain reservations stay visibly uncertain rather than being silently released.
5. DAST — discovery and reconnaissance
The canonical graph uses web.probe, web.crawl, web.content_discover, subdomains.discover,
ports.discover, and service.fingerprint. All targets receive the bounded web probe; the recon
family controls additional crawl/content breadth, and network/subdomain actions require their
separate policy permission. Output is normalized into one content-addressed endpoint manifest.
Declared surface (web.spec_ingest): besides the conventional OpenAPI/Swagger locations, the
same action fetches robots.txt and llms.txt from the origin root. Disallow/Allow rules and
Markdown links become discovered_route observations, origin-bound (another host's link is never
declared), with a wildcard rule contributing only the literal prefix it is anchored on and
Disallow: / contributing nothing. A path written in prose keeps its query string, since observed
parameters are what candidate generation is built from. A 200 that is really the application's
single-page shell is refused as hint_document_is_markup rather than mined. A declared path is a
claim, never a confirmed route: it enters the endpoint manifest and is probed like any other.
Measured absence (web.content_discover): a few high-entropy paths that cannot exist are probed
inside the same exact request reservation as the wordlist, and their responses are the negative
control. A hit whose response is an origin-only rewrite identical to at least two independent control
paths (same status, request path/query/fragment carried through unchanged — a fact the producer records
before redaction, because redaction is not injective) is dropped and counted as
indistinguishable_from_absent:N. Anything the observations cannot distinguish from a real route is
retained as uncertain and reported as unverified_redirect_observations:N; a run that carried no
control claims nothing.
Family presets and the active default. policy.preset selects the family set: passive
(recon, reviewed passive templates), standard_active (passive plus XSS and SQLi) or custom (exactly include_families). A submission that allows active testing and
names no preset resolves to standard_active; one that does not allow it resolves to passive.
Permission and work are reported separately: the scan page's Testing tile names the active
families that ran, or warns that active testing was allowed but no active family was selected.
DNS posture over a limited forwarder. dns.inspect asks the system resolver first. When a
query times out and the bound host is a public name on public addresses, the same query is retried
over DNS-over-HTTPS (SHAKERSCAN_DNS_DOH_RESOLVERS, comma-separated https:// URLs, default
Cloudflare then Google; empty disables it). Set it in the project .env: both Compose files pass it
to the api, worker and agent-tool-worker services, and the broker worker file passes it to its
worker, with ${VAR-default} so an explicit blank stays blank. Internal names and private addresses
never leave the network as a resolver query. An HTTP 200 is not a DNS answer: a reply is accepted
only when its rcode is NOERROR or NXDOMAIN, it is not truncated, its question is the one asked, and
every answer record belongs to the asked name or a CNAME target the answer introduces; anything else
is refused, the next resolver is tried, and a run with no valid answer keeps the primary timeout as
its stated reason. Recovered answers are marked resolver: doh in the record metadata and listed
under doh_fallback_queries.
Discovery reservations scale with the profile. Each producer keeps the share of the ceiling it
always took, but the cap that share may reach now rises with the granted budget instead of staying at
the constant sized for the smallest profile; the tools derive their rate from the reservation, so a
larger grant buys a longer look, not a louder one. dns.inspect bounds its fan-out and asks the six
conventional DKIM selectors alongside SPF/DMARC/CAA/DNSKEY/MTA-STS/TLS-RPT; absence from those names is
not proof that the domain does not sign mail.
The compatibility scanner_tools/ directory supplies migrated adapter implementations and richer
observations behind those registered capabilities. Its module inventory does not imply that every
module is enabled in every V2 plan. Available discovery/recon implementations include:
DNS & domain (discovery.py, dns_enhanced.py): A/AAAA/MX/TXT/NS/SOA/CAA records; SPF/DMARC/DKIM
enumeration; DNSSEC validation; zone-transfer attempts; virtual-host enumeration.
TLS & certificates (tls_scanner.py): certificate subject/issuer/expiry/key-size/chain analysis,
OCSP stapling, cipher-suite enumeration, and TLS version detection — using sslyze, testssl.sh, and
nmap in combination.
HTTP fingerprinting: server/framework detection, security-header analysis (HSTS, CSP, X-Frame- Options, Referrer-Policy, COOP/CORP), and HTTP/2 / HTTP/3 detection. CSP is graded with parsed directives.
Web application discovery:
- Crawling —
katanarecursive crawl +httpxprobing (discovery.py). - Browser crawl — headless Playwright multi-page crawl with HAR/network capture and API capture
(
http_scanner.py); SPA hash-route crawling (hash_routes.py). - Content discovery —
ffufdirectory/file fuzzing against bundled and custom wordlists. - Parameter discovery — query/body parameter inference from observed requests.
- JS bundle analysis — extracts hidden endpoints and routes from JavaScript bundles.
- API discovery — HTTP
OPTIONSmethod discovery, gRPC reflection (grpc_discovery.py), GraphQL introspection (graphql_schema_recovery.py), and JSON link following (HATEOAS/pagination). - HAR-driven prioritization —
har_discovery.py/active_prioritization.pyrank real network-captured endpoints first.
WAF detection: response-pattern fingerprinting of the protecting WAF product.
Port scanning (nmap.py): bounded TCP discovery and service/version detection under explicit
network permission and the plan's TCP/host/tool-time ceilings.
Subdomain enumeration: subfinder (passive), gungnir (CT logs), and crt.sh — see
§10.
Historical and source-assisted discovery: OpenAPI/Swagger schema discovery uses prioritized,
bounded concurrent probes under one global deadline and reuses the result across later active phases;
explicit schemas can also be exercised through Schemathesis. Wayback/Common Crawl/GAU helpers;
JavaScript and browser-derived API bases; GraphQL schema
recovery; gRPC reflection; virtual hosts; custom endpoint files, focus/avoid rules, and agent-produced
custom_endpoints/custom_list seeds.
Threat intelligence and external posture: opt-in DNSBL, AbuseIPDB, and VirusTotal IP reputation; typosquatting/lookalike-domain generation and resolution; WHOIS/RDAP domain age, expiry, and registrar analysis; certificate-transparency posture; ASN/hosting-provider/prefix/geography/multihoming facts; HIBP/GitHub-oriented breach and credential-leak checks; and third-party resource/vendor risk.
Known endpoints and exact request selections can seed discovery. Saved selections remain target-
bound and content-addressed; discovery_only contributes safe route facts without replay,
safe_reads executes only read-only requests, and confirmed_active requires active permission,
state-changing authority, and a target-bound approval receipt (the target's standing
authorization suffices). Arbitrary custom payload/shell input is not part of the canonical Scan
contract.
6. DAST — vulnerability checks
V2 exposes only checks backed by a registered semantic capability and deterministic output/evidence contract. The current Scan family surface is intentionally narrower than the historical module inventory: passive reviewed templates plus bounded XSS, SQLi, and two-principal BOLA verification. The modules below describe available detector implementations; modules not yet wired to the canonical action graph remain compatibility/internal implementation surface, not advertised Scan coverage.
Active injection
- XSS (
active_checks.py,dom_xss_analyzer.py):dalfox-based reflected/DOM detection plus a custom context-aware tester that detects reflection context (in-script, in-attribute, event handler, HTML body, SVG/CSS/JSON/URL-path) and selects context-specific payloads; canary-based reflection detection; browser proof for GET reflections and HTML-like POST/PUT/PATCH response reflections; hash-route testing; static DOM-XSS source-to-sink analysis over JS files. - SQLi (
active_checks.py):sqlmap-based testing that is DBMS-aware (SQLite, MySQL, PostgreSQL, MSSQL, Oracle) — it fingerprints the database, then chooses DBMS-specific payloads, techniques, and optional data-extraction chaining. Supports out-of-band (blind) detection viaoob_callback_url. - Other injection (
injection_extra_checks.py): SSI/ESI, prototype pollution, CSV/formula injection, RFI, LDAP/XPath, XXE/XML injection. - SSRF / command injection / LFI / RCE: high-risk active families, gated behind non-safe exploit
level and parameterized endpoints; SSRF includes cloud-metadata and Gopher payloads
(
gopher_payloads.py) with OOB verification.
Access control
- BOLA / IDOR (
bola_comparison.py,access_control_checks.py): dual-user testing — replay the same endpoint as user1 and user2, normalize volatile fields (timestamps, UUIDs, nonces), and detect cross-user data exposure with concrete PII matching. Also forced browsing, path traversal, privilege escalation, and unauthenticated-access detection.
Web/API security (Phase 4)
File upload bypass (file_upload_tests.py), open redirect, host-header injection, CSRF token
presence/reuse/randomness, HTTP method tampering, content-type switching, WebSocket auth/message
handling (websocket_security.py), OAuth flow tests (oauth_tests.py), and a generic API-security
sweep (api_security.py).
Auth/session/crypto
Weak JWT/session/cookie checks, default-credential testing (credential_check.py), and
deserialization tests (deserialization_tests.py) for Java/PHP/Python unsafe deserialization.
Business logic
Race conditions (race_condition_tests.py) for checkout, coupons, balance, votes, and invitations.
Template & infra
Nuclei template checks (nuclei.py, with a reviewed read-only passive pack); infrastructure-leak checks
(infrastructure_checks.py) for CI/CD config, cloud buckets, registries, k8s/terraform artifacts;
critical checks (critical_checks.py) for default creds, directory listing, and verbose error pages.
Opt-in infrastructure families also cover SSH authentication posture; SMTP STARTTLS, banner, MX, and safe open-relay checks; VPN, RDP/VNC, IoT, industrial-protocol, and database-service exposure; IP/ASN and domain intelligence; third-party vendor resources; webhook signature bypass; package-manager and backup artifacts; container registries; and Kubernetes/Terraform/cloud-storage exposure.
OpenAPI schemas can be supplied explicitly or discovered and exercised through Schemathesis. The scanner records schema/test errors as evidence rather than treating process exit as proof.
Canonical focus uses policy.include_families / policy.exclude_families. The old xss: true and
sqli: true booleans are compatibility inputs only and must not be added to new UI, CLI, skill, or
agent flows.
For OWASP-mapped coverage and intentional gaps, see docs/owasp-coverage-matrix.md.
7. DAST — authentication support
Authentication is resolved late per action. A credential is never globally inherited by every tool:
the worker checks the profile's semantic allowed_capabilities against the exact capability about
to execute. Static identities can authorize capabilities such as http.request, web.crawl,
templates.scan, collections.replay_safe, xss.verify, sqli.verify, or authz.verify.
Interactive form/OAuth profiles must additionally authorize auth.session.establish.
Canonical Scan submission accepts up to two credential_profile_ids, bound to the exact Web/API
target. Profiles hold authorization headers, bearer tokens, API-key headers, cookies, custom
headers, basic auth, or interactive form/OAuth material in the encrypted credential store.
Basic auth, form login, and OAuth password profiles accept a username-only or secret-only identity
when that unusual target flow requires it; at least one half is required. This is storage
flexibility, not proof that a specific Scan capability can authenticate with incomplete material.
primary/service selects the first identity and secondary selects the differential identity.
scan.execute is accepted only as a deprecated compatibility scope; new profiles should use
semantic capability names. Query-parameter credentials are not admitted to generic Scan because
they require exact request-replay authority.
Hunt can inspect public client artifacts without expanding every HTTP response placed in planner
context. artifact.inspect returns one target-pinned, redacted byte window (16 KiB maximum), while
javascript.analyze privately reads at most 256 KiB and returns bounded routes, source-map
references, client sink signals, Supabase origins, and decoded JWT metadata. JWT values never leave
the worker result boundary; a classified token remains evidence, not credential authority.
Worker-private form login, OAuth client credentials, and OAuth password exchange are supported. Sealed private session checkpoints preserve resumability without plaintext secrets at rest. Session headers remain bound to the profile version, action, target, and lane; a resumed action must re-establish or restore that exact authority.
Principal and benchmark receipts distinguish configured contexts, redacted identity fingerprints, server-observed accepted authentication, family attempts, and cross-principal proof. A verified BOLA result requires distinct accepted principals and a deterministic owner/attacker differential; two configured or merely attempted lanes do not satisfy that gate.
Workflow: create a test account → create an encrypted, target-bound profile → obtain a
target-bound approval receipt → pass only credential_profile_ids to /scans. The worker validates
the frozen profile version and resolves it in memory immediately before execution. Reusable secret
values do not enter canonical Scan requests, rows, logs, or queue payloads. Legacy Scan write paths
are removed; historical compatibility records remain readable for audit purposes.
8. DAST — scoring, attack chains, coverage, and reports
scan.finalize is an offline-only semantic capability. It receives zero target-traffic authority and
builds the report exclusively from the immutable plan/revision chain, terminal action results,
receipts, observation manifests, and private-work manifest references. The same evidence bundle can
be rebuilt with scanner.sh report-rebuild while outbound sockets are disabled; mismatched plan,
result, revision, or observation digests fail closed. File output uses an atomic same-directory
write, refuses to overwrite by default, and requires an explicit --force replacement.
Scoring & grading (api/scan/scoring.py, policy risk_and_assurance/v8): the report carries two
independent axes which must not be blended. risk_score (0–100, higher is better) and risk_grade
(A–F) describe the material risk observed by deterministic evidence, including only HTTP posture
that was actually observed from an application response. assurance_score (0–100) and
assurance_band (none, weak, limited, adequate, strong) describe completed required work,
selected-family and candidate coverage, verification attempts, authenticated contexts, placement,
and examination breadth. AI notes and suspected candidates cannot promote a finding to verified.
The compatibility score and grade mirror the risk axis. An unreliable grade gains *, while
grade_reliable=false, coverage.grade_reliability.reasons, and assurance_gaps carry the exact
qualification. risk_assessment_state=not_examined / application_observed=false is explicit when
the run received an HTTP response but did not observe the application (such as a 401 challenge). In
that state a numerical risk projection is not a clean bill of health. Historical reports retain
their stored scoring policy; score_projection.recomputed_for_display remains false rather than
silently rewriting old evidence. The scan also returns:
risk_score,risk_grade,risk_assessment_state, andgrade_reliableassurance_score,assurance_band,assurance_components, andassurance_gaps- compatibility
score/grade findings: array with severitiescritical/high/medium/low/inforesult: the rich object below
Finding processing: deduplication (deduplication_engine.py), false-positive validation
(finding_validator.py), correlation (finding_correlator.py), and a verification ladder
(verification_engine.py, verification_phase.py, proof_of_exploit.py) that produces reproducible
evidence for high-severity findings.
Attack-chain analysis (attack_chains.py): correlates findings into exploitable chains with
business impact. The nine implemented chain types (CHAIN_TEMPLATES) are
xss_to_account_takeover, sqli_to_privilege_escalation, ssrf_to_cloud_breach,
idor_to_data_breach, lfi_to_credential_theft, cors_to_data_theft,
weak_jwt_to_impersonation, xxe_to_data_exfil, and deserialization_to_rce.
Partial chains can be surfaced with include_partial_attack_chains: true.
Coverage tracking: /scans/{id}/actions, /capabilities, and /coverage expose the plan digest,
revision/continuation digests, stage timeline, per-action placement/status/reason, observation count,
required versus optional gaps, and allocated/reserved/consumed/released/uncertain/unallocated budget.
Legacy detector coverage fields may remain in historical results, but they are not the V2 execution
authority.
Compliance mapping (compliance_mapper.py): OWASP Top 10, CWE, PCI DSS, SOC 2, HIPAA, GDPR, CIS
Controls, control evidence requirements, business impact, remediation priority, and a GRC evidence
matrix. These are evidence mappings, not certification claims.
Rich result object (result.*): http.csp_evaluation, http.security_headers,
tls.certificate, tls.ocsp, dns, discovery.tech.items, discovery.browser_api_endpoints,
discovery.browser_crawl, discovery.waf_detection, attack_chains, canonical action execution, and — when AI
is enabled — ai_correlations and ai_logs.summary.cross_finding_correlations. SARIF 2.1 output,
fingerprinted baselines, known-finding suppression, and severity-count quality gates are available
through the scanner CLI; the UI offers PDF export.
9. Scaling DAST: parallel scanning and Continuous ASM
These two subsystems share the same durable primitives (endpoint inventory, work allocator, attempt ledger). They are two views over the same facts: "run full coverage now" vs. "keep this target covered over time."
Parallel scanning
Parallelism partitions immutable action authority; it does not invoke a second orchestration engine. The parent first commits a canonical discovery/root plan, then partitions content-addressed endpoint, candidate, template, credential, and exact-request manifests into child action plans. Every child is bound to the parent execution-plan/target/plan digests and receives only its assigned request IDs and aggregate budget share. The parent aggregate reservation is authoritative, so children cannot each spend the full profile ceiling.
The same shared orchestrator executes local, broker, and parallel actions. Outbound-only broker workers receive lease-scoped sealed private inputs and have no PostgreSQL/Redis credentials. Secrets are decrypted only by the executing child after target, profile version, approval, capability, and lease validation. Redelivery reuses terminal actions; duplicate completion is fenced by lease and result digests.
Placement and partition choices remain policy data:
| Choice | V2 meaning |
|---|---|
auto | Server selects a compatible placement/partition within max_workers |
scope | Partition an immutable known-endpoint/request manifest |
family | Partition supported family action authority without changing capability semantics |
coverage | Discover once, then partition the bounded canonical endpoint manifest |
coverage_family | Cross the bounded endpoint and supported-family partitions |
The parent is the user-visible Scan. Child/discovery rows are internal unless explicitly requested. Any missing, failed, cancelled, or uncertain required child makes the merged coverage incomplete and the grade unreliable. The report retains per-action backend/worker/attempt/receipt provenance and never claims that undiscovered endpoints were tested.
Current execution design: docs/dast-asm-architecture.md.
Continuous ASM
Continuous ASM keeps a persistent endpoint inventory per target (target_endpoints) and improves
coverage over time within safe budgets and allowed windows (api/asm_inventory.py, the
asm_dispatcher loop, and the exploit_batch worker job).
- Endpoint identity includes auth state, HTTP method, normalized path, and parameter location/shape, so the same path under anonymous/user1/user2 is tracked as distinct coverage obligations.
- The dispatcher reserves per-root-domain rate budget in Redis before queueing, claims rows with
FOR UPDATE SKIP LOCKEDunder durable leases, and never stacks load on a target. - Coverage derives from a normalized attempt ledger (
asm_endpoint_attempts): an endpoint is only markedtestedwhen scanner telemetry proves it was attempted/completed. Timeouts/partial results do not count unattempted endpoints as covered. - For AI/agent workflows, prefer
POST /targets/{id}/asm/improve, which chooses recon vs. test batch vs. wait from current gaps. Focused families:sqli,xss, credential-gatedauth(requires a primary auth context), and gatedbola(requiresexploit_depth: trueplus primary and second-user auth). Planned families (ssrf,lfi,rce,business_logic) are registered but rejected for ASM execution until their scanner integrations ship. GET /targets/{id}/asm/activityis the read-only operator summary for one target: recent hidden ASM recon/test jobs, the scheduler decision, campaign timeline events, active ASM scans, and a bounded target-scoped hypothesis situation report. The embedded hypothesis report surfaces proof leads and missing preconditions next to coverage state, but it does not queue work, create findings, or change proof state.
Current execution design: docs/dast-asm-architecture.md.
Multi-node boundary: the first owned-fleet trust foundation is implemented: durable node identity,
hashed usage-bounded join tokens (single-use by default), HTTPS enrollment, authenticated heartbeat, one-time overlay connection
bundles, and credential rotation/revocation. A digest-pinned worker/agent-only Compose runtime and
pull-based local node-agent now apply versioned worker-count/drain desired state without an inbound
listener or remote Docker API. The opt-in fleet Compose profile adds a CA-verified HTTPS listener on
the private data address, preserves the real overlay socket peer with Linux host networking, and
disables duplicate background controllers in that edge process. Linux host automation now implements
persistent fleet init, aggregated read-only fleet preflight, tag-to-digest image resolution,
automatic pre-conversion backup, bounded/revocable fleet join-token, automatic/manual peer reconciliation,
automatic restricted public HTTPS for broker fleets with pinned Caddy, certificate renewal and
secret-bound proxy trust, minimal public health, protected-route/rollback verification, bounded
enrollment attempts, and worker-only join with HTTPS preflight and WireGuard handshake
diagnostics. The installed worker image is derived automatically; --worker-image selects a custom
build. Fleet is host-aware and opt-in: standalone installs hide Fleet navigation, remote capacity,
and remote placement; direct macOS visits explain the Linux requirement, while uninitialized Linux
visits show setup guidance. GET /health and GET /workers expose the same non-secret capability
state. The enabled Fleet UI also flags WireGuard nodes awaiting their first connection. Leased delivery and
fencing, central artifact transfer, placement, capacity-weighted scaling, rolling lifecycle,
outbound-only HTTPS broker transport, and fleet-wide
admission/request controls are implemented. Exact-node broker execution and central persistence have
been exercised on two local-build VPS nodes; the remaining release-topology gate is the complete
digest-pinned physical acceptance and fault matrix. Follow the operator guide; the design authority is
docs/multi-node-architecture.md.
10. Attack-surface management: discovery, CT monitoring, schedules
Subdomain discovery (POST /discovery, process_discovery_job): enumerates subdomains for a root
domain via Gungnir, Subfinder, and crt.sh, then upserts discovered hosts as targets.
Certificate Transparency monitoring (Gungnir) (api/gungnir_worker.py): a long-running worker
that watches CT logs in real time, discovering new certificates for monitored domains. New subdomains
are auto-added as targets (discovery_source = gungnir-monitor); if the root domain has ASM enabled,
discovered surface inherits the ASM policy. Controlled via ./scanner.sh gungnir start|stop|status
and /gungnir/* endpoints.
Schedules (schedule_runner, /schedules): recurring daily/weekly actions with timezone and
jitter support. New schedules support normal scans and bounded asm_improve coverage waves.
Legacy evidence_retention_sweep records remain readable for migration but are automatically
disabled and cannot be created or resumed. Interactive deletion requires a fresh immutable preview
and an exact-action, target-matching approval created through the interactive flow.
Schedule listings include derived schedule_health when recent scan results
show repeated failures or timeout/heartbeat failures for the same active target/type pair, and the
Dashboard Action Center links operators to the affected schedule plus the latest failed scan.
Connected-device posture
Connected-device security is isolated from Web DAST targets. The /devices product surface stores
TVs, cameras, printers, routers, NAS systems, conference equipment, and other network-connected
assets in dedicated device, interface, and service tables. device_posture work uses its own queue,
worker capacity, and build-health registry, so it cannot change ordinary Web DAST worker freshness,
target counts, scan lists, ASM state, or dashboard posture.
Every profile uses Naabu for TCP discovery and Nmap only for confirmed-open TCP fingerprinting plus
the declared curated UDP set. inventory scans priority/device-hint ports followed by Naabu's top
100; posture and thorough divide all 65,535 TCP ports into bounded Naabu CONNECT ranges. Connect
concurrency is derived from the probe rate and timeout, each failed range receives one bounded retry,
and partial open-port evidence is preserved. There is no all-port Nmap fallback. Cancellation and
device-health checks run between ranges, and progress is persisted per range.
Reachability prioritizes previously observed, operator-hinted, policy-defined, and
credential-bound TCP ports, then applies compact common, device-class-specific, and major-TV-manufacturer
port sets (Vizio, LG, Samsung, TCL, and Hisense). If that bounded check is silent, only an already
all-TCP posture or thorough scan expands discovery; the same result becomes the main inventory,
so the range is never scanned twice and silence alone never proves online status. Each Naabu range
has an independent receipt, so partial all-port discovery cannot be reported complete. A completed
TCP scope proves reachable-open-port coverage from the scanner's vantage without claiming silent
ports were distinguished as closed versus filtered. UDP open|filtered/no-response results are kept as
inconclusive observations and excluded from service policy and scoring until a protocol response
confirms them open. Nmap service/version/CPE output, addresses, hostnames, MAC/vendor evidence, and
bounded OS hints are retained. The scanner recognizes
HTTP and TLS on discovered TCP ports rather than assuming 80/443, then optionally runs hidden,
request-aware quick, standard, or deep Web/API children with capped origins, time, URLs, and
requests. Operators can upload encrypted Postman Collection/environment, HAR 1.2, OpenAPI 3.x, or
Swagger 2.0 JSON, review a redacted request inventory, and bind selected collections to a scan.
Safe requests can be replayed normally;
POST/PUT/PATCH/DELETE require authenticated-active safety plus explicit confirmation. Imported
Postman scripts, HAR responses, and external OpenAPI references never execute, and every socket
remains pinned to a discovered origin on the device. Child
findings retain device/origin/request provenance and never create Web targets.
Before those children, ShakerScan parses same-device SSDP/UPnP descriptors and runs a versioned,
bounded application catalog for Roku, Vizio, Samsung, LG, Philips, Cast/DIAL, Panasonic, and Sony
interfaces. Confirmed cleartext APIs, unauthenticated privacy-sensitive reads, software disclosure,
TLS trust failures, cookie/CORS defects, and authenticated-versus-anonymous response equivalence are
reported as device findings. Untrusted device TLS remains scannable, but credentials and imported
secrets are withheld unless the operator grants a separate authenticated-active override.
SSH checks run on the discovered port and collect auth methods, host-key evidence, negotiated
algorithms, and weak-crypto signals without credential guessing. An operator may bind one encrypted,
device-scoped SSH password/private-key profile for one authentication attempt with no command
execution. Discovered web origins may likewise use an encrypted authorization-header, cookie, or
form-login profile. Credential values are decrypted only in the dedicated worker, never persisted in
scan options/results, and never shown to the AI planner. Ordered service policies support
allow, deny, review, and fail-closed required-control rules. Built-in generic, media, camera, printer,
and network-appliance baselines can be copied or replaced with custom allowlists. review findings
produce needs_review; deny/failed-require findings block. A complete report
states TCP/UDP scope and truncation; older device findings are cleared only after complete all-TCP
and complete web-origin coverage. Bluetooth/BLE and other radio protocols remain a future
capability-labeled sensor extension rather than an implied Docker-worker capability. See
connected-device-security.md.
Device coverage depth and action safety are independent. observe_only, safe_remote, and
authenticated_active are the executable profiles. The never-implemented lab_invasive profile was
removed; a request naming it is rejected with a pointer to authenticated_active. Device reports carry device-safety/v1 receipts plus a
stable device-evidence/v1 node/edge/observation graph. A device-target POST /hunts run lets the
current coding agent inspect device state, inspect redacted user-bound request collections, compare scans, recall prior hypotheses, query effective policy, use
size-capped SHA-256-pinned offline advisory candidates and protocol playbooks, queue bounded deterministic scans, and query
normalized evidence. Its context pack treats network data as untrusted, its target and safety profile
are immutable, and its tool/turn/scan/daily-device/fragility budgets are server-enforced and recorded
in a durable action ledger. A health circuit breaker freezes new traffic while leaving read-only
evidence tools available. Its debrief persists typed, non-authoritative candidates with canonical
device loci and registered verifier contracts. A server-owned candidate verifier, not model prose,
owns promotion; the initial service-exposure path requires a fresh protocol observation, a persisted
deny policy, a healthy safety receipt, and a satisfied Proof Contract v2 before creating a finding.
The selected device-scan view polls a structured, secret-free activity stream showing meaningful reachability, discovery, fingerprint, protocol, Web/API request, finding, and safety events instead of exposing raw command output.
For a narrow hypothesis, POST /devices/{device_id}/verify-service and the agent's
verify_service_state tool queue a device_probe on the same dedicated worker. The executor resolves
and pins the registered locator once, invokes rate-limited Nmap against exactly one declared TCP or
UDP port, checks health before and after, and returns a typed satisfied, refuted, or
inconclusive invariant. Filtered, silent, malformed, timed-out, or missing-port output is never
accepted as proof that a service is absent. Probe rows remain separate from Web DAST targets,
findings, scores, device inventory, and ordinary DAST metrics.
Each connected device has an immutable UUID and a mutable current locator. Operators can use
POST /devices/{device_id}/locator or the device detail page's Change address action after a
DHCP change; the API requires same-device confirmation, rejects changes during active device
traffic or an AI investigation, and appends the transition to device_locator_history. Existing
policies, credentials, findings, scans, and agent memory remain bound to the device UUID, while each
scan keeps the exact locator used at submission.
Core protocol adapters send bounded exact-target unicast SSDP and mDNS discovery probes, normalize
UPnP and DNS-SD metadata, refuse to follow cross-host descriptor locations, and promote UDP
open|filtered state only after a valid application response.
11. AI red teaming
The AI side has five capabilities:
- Hunt — the shared adaptive investigation runtime for Web, API, network, and device targets. The current coding-agent session owns strategy; the server advertises semantic capabilities and enforces every call's scope, approval, risk, typed budget, placement, credentials, evidence, and deterministic proof contract. Device Hunt is a target-kind/policy-filtered use of this runtime, not a target-specific planning engine. Historical Deep Hunt/device-agent URLs redirect to Hunt.
- AI Gate — probe-driven runtime testing of chat, RAG, agent, MCP, and widget surfaces.
- Model Intake — static artifact and supply-chain vetting before deployment.
- Interactive session compatibility API — bounded browser/session testing retained for Command Arsenal and the compatibility skill; no standalone 2.0 UI.
- AI-assisted analysis — correlation, explanation, and retest planning for DAST findings.
Design principle. AI may help judge, correlate, and explain, but verified security decisions must
be backed by deterministic, cryptographic, parser-backed, protocol-backed, or replay-backed evidence.
Findings carry proof quality explicitly (see AI proof and evidence states
below); AI is never the sole authority for verified status or severity promotion. Operator workflows
are in AI_TEST_WORKFLOWS.md, and future hardening belongs only in
the maintained architecture and evaluation documents.
AI capability status quick read
These implemented components were last reconciled against code on 2026-08-29. AI Gate remains a
preview product surface for 2.0.0. Model Intake is release-gated for deterministic static review,
artifact and report generation, and its opt-in AMD64 Linux/KVM Firecracker tier; unsupported formats,
incomplete evidence, missing required tools, and unavailable runtime qualification fail closed. The
AI Gate policy/exception and deterministic-judge seams marked Planned in
E2E_TEST_PLAN.md are not yet release-gated. "Partial" means the capability runs
but the listed caveat applies — treat the caveat as load-bearing, not cosmetic.
| Capability | Status | Trust / proof caveat |
|---|---|---|
| AI Gate REST / RAG / agent / MCP probing | Shipped | Production probe-safety filter now effective (3-tier derived classification; non_production_only probes dropped in production). |
| AI Gate widget target | Shipped | Playwright-driven target honors shared request-budget and response-byte cap contracts; deterministic proof still outranks AI judgment. |
| AI Gate per-finding retest | Shipped | Deterministic proof still outranks AI judgment. |
| Cross-principal AI testing | Shipped | Requires configured principals. |
| MCP readiness checks | Shipped | Safe resources/list added; audience/scope still partly from declared metadata. |
| Transcript retention / purge | Shipped | Response-time redaction by default + audited admin gate (AI_TRANSCRIPT_ALLOW_SENSITIVE). |
| Model Intake checksum / range / local-file gates | Shipped | Solid baseline. |
| Model Intake signature / provenance crypto | Shipped | Real detached-sig verification (cryptography: Ed25519/RSA-PSS/ECDSA); metadata booleans are claims, not proof. |
| Model Intake governance evidence | Shipped | SPDX normalization + expression parsing added (MIT OR Apache-2.0). |
| Agent execution receipts | Shipped | Verifies content-hash, prev_hash chain, and signature (Ed25519/RSA/ECDSA). |
| Deployment gate API | Shipped | Should converge on the unified proof/policy states. |
| Durable policy + exception registry | Shipped | DB-backed policy_profiles + finding_exceptions + CRUD; consumed by the deployment decision; exceptions expire and re-open blocks. |
| AI surface inventory and attempt ledger | Shipped | Stored surface/attempt facts are separate from findings and do not imply proof. |
| AI campaign replay and longitudinal history | Shipped | Supports selected probe/family/error/skipped reruns; replay remains budgeted and production-gated. |
| Model Intake saved trust anchors | Shipped | Write-managed public keys/fingerprints; inactive anchors do not satisfy strict policy. |
| Model Intake evidence export | Shipped | Content-free/hashed export contracts preserve provenance and redaction boundaries. |
AI proof and evidence states
Today a finding exposes a three-state proof level — verified (deterministic proof), suspected, or
unverified (api/api.py), with proof_state exploited / likely_vulnerable at the scanner — and
deterministic proof blocks any AI downgrade. The target is one taxonomy unified across DAST and AI
(deterministic_verified, cryptographically_verified, claimed_present, ai_judged_likely,
inconclusive, blocked, false_positive) so that claimed metadata and AI-judged results can
never render as verified. Future proof-state changes belong in the proof contracts and focused architecture/decision records.
11.1 AI Gate
AI Gate tests AI application surfaces by sending crafted probes and grading the responses.
Target types (api/ai_gate_scan.py, adapters under api/ai_gate/targets/):
| Type | Surface |
|---|---|
api_chat | Chat/completions-style JSON endpoint |
rag | RAG answer endpoint |
agent_trace | Agent/trace endpoint or trace-replay API |
mcp_trace | MCP HTTP/SSE endpoint or MCP trace-compatible API |
widget | Browser widget target (Playwright-driven) |
REST/JSON adapters use a request_template containing {{prompt}} (and optionally {{session_id}} /
{{previous_response}}), extract the model's answer via a JSONPath response_path (e.g. $.answer),
and support json or sse streaming modes plus a headers_template for auth.
Probe packs (api/ai_gate/probe_registry.py):
| Pack | Focus |
|---|---|
shaker-ai-smoke | Small broad smoke test |
shaker-owasp-llm | OWASP LLM Top-10 risks |
shaker-agent-abuse | Tool abuse, approval bypass, agent boundaries |
shaker-mcp-security | MCP tool/resource/scope/OAuth issues |
shaker-rag-lite | RAG leakage and retrieval-boundary issues |
Vulnerability classes probed: prompt injection, sensitive/secret disclosure, system-prompt leakage, improper output handling, excessive agency, unbounded consumption, encoding-bypass; agent families like approval bypass, tool-result injection, secret exfiltration, cross-account/cross-tenant actions, identity/approval-token replay; MCP families like untrusted-server trust, tool-metadata change, OAuth audience confusion, PKCE downgrade; and RAG families like retrieval-ACL bypass, citation fabrication, poisoned/deleted-document recall, and canary leakage.
Profiles (smoke / trace / standard / deep) scale the probe set and the max conversation
turns; environments (preview / staging / development / production) gate which probes run —
production blocks probes flagged unsafe for production, and production scans require
confirm_production: true.
Detection — two layers:
- Deterministic detectors run first (
api/ai_gate_scan.py): regex/keyword markers for token and secret patterns (AWS/GitHub/Slack keys, private keys, JWTs, DB connection strings), prompt-leakage markers, approval-bypass markers, metadata-injection markers, agent/tool markers, MCP/OAuth markers, and RAG markers. - Semantic AI judging (
scanner/scanner_tools/ai_classifier.py), when an AI provider is configured: judges probe transcripts and populatesai_verdict,ai_confidence,ai_rationale, andai_recommendations. Sensitive headers/bodies are redacted before being sent to the judge; a circuit breaker and retry/backoff protect against provider failures. A verdict policy (scanner/ai_verdict_policy.py) governs trust thresholds — high-confidence false positives can be downgraded, but never when deterministic proof of exploitation exists.
AI control-evidence baseline (api/ai_control_requirements.py): from a target's metadata_json,
AI Gate builds a control-evidence pack (asset owner, risk tier, data classification; RAG
ACL/ingestion/tenant-isolation controls; agent tool scopes, delegated identity, token-audience
validation, approval/dry-run/transaction limits, sandboxing, audit logs, anomaly detection, kill
switch; governance mappings to NIST AI RMF / ISO 27001 / OWASP LLM). With
enforce_ai_control_baseline: true, missing required controls become findings. The AI Gate score and
the deploy decision combine deterministic findings, AI verdicts, and control evidence.
Principals (/ai/targets/{id}/principals): multiple named identities (roles attacker/victim/
admin/service/observer) with separate credentials, enabling cross-user/cross-tenant RAG and
agent tests.
Transcripts & reporting: GET /ai/scans/{id}/transcript returns probe transcripts; AI findings
carry probe family/technique/OWASP refs, classifier output, and raw evidence. Post-scan AI red-team
reports are available via /scans/{id}/ai-redteam-report and a CI/CD deployment-decision endpoint.
11.2 Model Intake
Model Intake (scanner/scanner_tools/model_intake.py) is a provider-neutral model admission pipeline.
It resolves and completely acquires immutable subjects, creates content-addressed quarantine objects and
repository manifests, runs generated static evidence, optionally invokes a separate no-egress semantic
sandbox and content-free embedding/data-plane evaluation, and emits a signed, revocable decision package.
It never imports publisher model code in the API or worker process. An operator-configured, digest-pinned
runtime adapter can perform exact-subject load/inference and deterministic known-answer cases inside the
hardened sandbox tier. A disposable microVM with independent telemetry is still required for the highest-risk
custom-code approval tier.
Signature/provenance (R1, shipped 2026-06-24). Model Intake performs real detached-signature verification (Ed25519 / RSA-PSS / ECDSA via the
cryptographylib) over the artifact or its digest when a public key + signature are supplied (signature_public_key/_url,signature_value/signature_url);require_cryptographic_signature_verificationmakes a metadata-only claim fail. Metadata booleans such assigstore_verified: trueare treated as claims, never as cryptographic proof. Offline DSSE/in-toto subject verification is supported. A policy requiring transparency evidence fails closed unless an independently trusted transparency verifier/bundle is available.
Checks include:
- Unsafe serialization — flags pickle-like formats (
.pkl,.pickle,.joblib,.pt,.pth,.ckpt,.bin,.mar) vs. safer ones (.safetensors,.onnx,.tflite,.gguf); scans for pickle opcode markers and suspicious loader markers (os.system,subprocess,eval/exec,pickle.loads, network downloaders, base64 decode). - Archive payload analysis — recursively inspects ZIP and TAR families without extraction, enforcing entry/depth/expanded-size/ratio bounds and rejecting traversal, links, devices, collisions, nested unsafe serialization, and executables.
- Provenance & integrity — checksum (
sha256) verification; signature/attestation presence; claimed signature/provenance metadata; cryptographic detached-signature verification (Ed25519/RSA-PSS/ECDSA via thecryptographylib, over the artifact or its digest); Hugging Face reference normalization. - Generated evidence — normalized fail-closed adapters for model/pickle scanners, Python AST, secrets, malware, CycloneDX SBOM/SCA, native binaries, licenses, plus explicit tool/rules/version/coverage status.
- Packaged core adapter bundle — rebuilt worker images install hash-locked ModelScan 0.8.8, Semgrep
1.172.0, Fickling 0.1.12, Trivy 0.73.0, OSV Scanner 2.5.0, and a hash-bound offline
pip-audit 2.10.1 result. The image build fails unless the deterministic functional receipt matches
the safe, review, and malicious fixtures expected for the applicable adapters.
GET /model-intake/scanners/readinessexposes versions, applicability, rules/database identity, and the last functional receipt. - Advisory-data cadence — the dedicated Model Intake worker attempts a bounded Trivy database
refresh at startup when registry egress is available and retains the image's baked database on
failure or in offline environments. Generated static evidence and every frozen evidence manifest
record
trivy_db_updated_at, so operators can judge database age instead of inferring freshness from the image build date. - Typed non-scanner providers —
GET /model-intake/providers/readinessseparately reports sandbox execution, embedding evaluation, embedded/OPA policy, and core report providers. OPA remains explicitlyNOT_IMPLEMENTED; an installed or configured label does not imply an enforcing decision contract. - Model/application evaluation — computes retrieval quality, vector integrity, poisoning, ACL/tenant and sensitive-data leakage, stability, capacity, graph boundaries, deletion receipts, cache context, and index/model digest compatibility without persisting source text or benchmark vectors.
- Admission lifecycle — signs the complete decision, registers it durably, enforces exact subjects at
verification, and supports expiry, supersession, reassessment triggers, revocation, and audit history.
The core verifier accepts only an exact signed
allow; HTTP verification also requires an active matching registry record. Mutation endpoints require operator authentication, and global operations require explicit confirmation plus a change receipt. External deployment systems must integrate the verification boundary.
Saved trust anchors can be created, updated/deactivated, selected by policy, and previewed before a
scan. POST /model-intake/resolve normalizes HTTP, Hugging Face, S3, GCS, Azure, OCI, and MLflow
references. OCI/MLflow use an operator gateway or signed HTTPS export bound to the exact provider subject
and expected digest, so provider credentials never enter scanner output. Completed scans expose a
content-free evidence export and durable admission lifecycle APIs.
Model repositories and artifacts are Model Intake subjects, not web targets. They are therefore excluded
from the default /targets, /targets/grouped, /domains, dashboard web-target totals, and target-dedupe
surfaces. Existing internal target links remain readable for report and rescan compatibility, and Exposure
continues to show them explicitly as model_artifact assets. The automatic HTML report identifies the pinned
source/revision and digests, explains the controller stop reason and next action, shows a scanner coverage
matrix, and lists the bounded content-free repository manifest plus per-scanner file coverage.
Result shape: model_intake.checks.*, aibom, supply_chain, summary (with the decision), and
artifact. Findings are stored with tool = model_intake and filter independently through
source_type=model_intake; they are excluded from source_type=dast. Sensitive URL params and
metadata keys are redacted.
11.3 Interactive session compatibility API
api/session_manager.py plus /session/* endpoints remain available to agents and Command Arsenal
for bounded manual browser work. There is no standalone 2.0 UI and new adaptive investigation should
normally use Hunt. A compatibility client can start a session and drive actions (navigate, click, fill, register,
login, submit, wait, extract), maintain separate per-user contexts (e.g. user1/user2),
capture screenshots, and test endpoints for cross-user access (test-endpoint with as_user).
Endpoint tests that name a user require that user to exist and be authenticated in the session; authz
replay automation also requires at least two authenticated principals before it can make a
cross-principal claim.
Evidence-backed findings can be saved via POST /session/{id}/findings (the compatibility source value is
ai_session; the user-facing source label is Interactive). This is the engine behind the
/ai-security-session compatibility skill. These findings remain unverified until deterministic
proof establishes impact; see
the live /session* OpenAPI contract.
11.4 AI-assisted analysis of DAST findings
When an AI provider is configured (AI_URL / AI_API_KEY / AI_MODEL), ShakerScan adds
cross-finding correlation and an overall risk assessment to DAST reports, and can run AI-driven retest
verification of findings (AI_VERIFY_*). The AI retest tier generates an exploitation plan and
replays it (optionally via a browser), and can downgrade false positives — but deterministic proof of
exploitation blocks any downgrade.
11.5 AI Operations Router
POST /ai/ops/route maps natural-language DAST/ASM requests to concrete API calls with dry-run
defaults. It recognizes the deterministic Scan plus dated legacy-name compatibility translations,
"run parallel coverage", "keep this target covered" (enable ASM with a safe preset), "what is still
untested?" (ASM gaps), "spend more budget on APIs", and focused SQLi/XSS/BOLA requests. Active,
state-changing, or budget-increasing intents stay dry-run unless
execute=true and the explicit confirmations are all present. Standard installs enable the server
execution gate; AI_OPS_ROUTER_EXECUTE_ENABLED=false disables all gated execution globally. BOLA
additionally requires primary + second-user auth context. Ambiguous language never upgrades a
Safe/Balanced plan to Lab.
The UI binds execution confirmation to the exact prompt and target that produced the visible preview;
editing either input invalidates the preview and clears its confirmations.
11.6 Hunt
Hunt is the canonical AI-driven investigation workflow for web, API, network, and device targets.
The current Codex, Claude, or OpenCode session plans through POST /hunts, /query, and the
server-returned capability manifest; ShakerScan alone executes actions. Active or credentialed
capabilities require a live, target-bound approval that is revalidated per call. A target
authorized once (POST /targets/{id}/authorization, standing, revocable) supplies that approval
automatically for active, network, mutation, OOB, identity-header and direct-origin authority;
credential use keeps an explicit credential-tier receipt.
GET /hunt/skills publishes metadata for 31 server-shipped web-testing methodologies. Complete
methodology bodies remain server-side. A Hunt normally starts with no selection, then
POST /hunts/{id}/skills/suggestions returns at most three compact recommendations from the
objective, target metadata, and bounded observed-stack signals. The planner loads exactly one at the
Hunt-specific /read endpoint before /bind; it can later unbind or record evidenced use. Binding
validates existing prerequisites but never grants, removes, or resizes authority. Versioned lifecycle
events are stored outside the planner context and included in the Hunt record export.
The planner can issue read probes on explicit target-bound origins, compare managed principal contexts when they are configured, query stored knowledge, record candidates, and invoke bounded active capabilities. It cannot issue arbitrary state-changing HTTP. Capability calls, requests, active actions, wall time, ports, hosts, browser actions, device fragility, and candidate counts are bounded. A direct HTTP call consumes one request; external scanners reserve their fail-closed maximum wire request allowance before execution, and cannot run when that reservation does not fit. Receipts report reserved traffic, exact settled traffic when the scanner exposes it, and observed-minimum traffic otherwise. Scanner subprocesses run on the worker plane, which independently rebuilds fixed argv and revalidates the target host; the API never spawns them. The external coding agent owns its model context: ShakerScan cannot meter an external coding agent's tokens, and makes no token-budget claim for that planner. It meters every executable capability.
service.nse_check exposes Nmap's scripting engine inside Hunt only for the reviewed
ssl-enum-ciphers, http-security-headers, http-methods, and http-trace scripts. It requires
network-discovery authority and a standing active authorization, accepts at most four bound TCP
ports and three script IDs per call, and never accepts script arguments, categories, paths, or raw
Nmap flags. HTTP script traffic is charged at a conservative fixed allowance because NSE does not
report a reliable request count. Results contain bounded signals and a digest of the script output,
without raw target content; they are observations and cannot verify a finding. Broader CVE scripts
need separate review of their request and device-fragility behavior before being added to the
server-owned allowlist.
A final debrief persists evidence-backed claims only as durable,
non-authoritative investigation candidates outside the findings table. Candidate lifecycle is linked
to the server verification record and typed evidence. A finding is materialized only after a
supported family reaches Verified through server-run deterministic proof. Legacy unverified
autonomous_agent rows are migrated into the candidate ledger and retired. The /research/*
controller remains available for specialized guided verification and is not a Hunt launcher. Legacy
/agent/hunt/* and /device-agent/* writes return 410 Gone by default; reads and cancellation remain
temporarily available with deprecation headers.
Candidates can be created, corrected with PATCH, expired with DELETE, and submitted to a
registered deterministic verifier. A budget-exhausted run still accepts a final debrief without
erasing its exhaustion reason. GET /hunts supports target/search/status/kind/budget filters,
sorting, and pagination; GET /hunts/{id}/record exports the bounded explicit decision trace and
debrief, never hidden chain-of-thought.
HuntStartContract is the sole Hunt policy and budget authority. The server publishes the same
dimension/profile schema used to generate UI types at GET /hunts/contract. Zero is valid for risk
dimensions: disabled mutation, network discovery, out-of-band interaction, and non-device fragility
are persisted as hard zero ceilings, and an explicit positive override that contradicts policy is
rejected. Duration, capability calls, HTTP traffic, candidates, and verification counts remain
strictly positive runtime ceilings.
Web target identity is host-level: scheme and port variants share one target record and durable
security history, while each scan and hunt retains the exact concrete origin it executes against.
The target APIs return origins ordered by recent DAST use. Hunt binds the target and its known
origins at creation; capability calls cannot replace that destination. Model Intake subjects retain exact artifact/revision identity in the Model Intake evidence model;
they do not appear in the normal web-target inventory.
Targets also expose a validated cohort (production, staging, lab, demo, calibration,
internal, or unclassified on update). Cohorts drive grouped target views, the Exposure lens, and
the dashboard's default operational scope; they do not alter DAST scoring or finding proof.
Natural-language routing treats an unqualified “scan” as the deterministic Scan, historical mode
names as display-only history, “Deep Hunt” as Hunt, “verify this finding” as deterministic retest/verification, and manual
browser work as Interactive Testing. See product-model.md.
11.7 Test scenario catalog and Honey demo
GET /ai/test-scenarios returns ready-made templates — notably secure-rag-agent (canonical Honey
RAG/agent/MCP endpoints with full control metadata) and model-intake-pipeline (safe/unsafe-pickle/
missing-signature/missing-approval model presets). Probe/test-case metadata is exportable to
promptfoo, pyrit, and garak formats (/ai/test-cases/export). See
docs/AI_TEST_WORKFLOWS.md.
11.8 AI surface inventory, histories, replay, and evidence
/ai/surfaces/* persists normalized AI surfaces and attempt facts independently of findings.
AI-target and AI-scan campaign-history endpoints expose longitudinal decision, coverage, blocked,
errored, and readiness-trend context; target history also has an export endpoint. Scan replay can
rerun all probes or bounded slices selected by probe ID/family/error/skipped state while preserving
the original target context and safety gates. Transcript reads support redacted default output and
audited sensitive access only when the server policy allows it.
12. Cross-cutting: findings, exposure graph, workers, queue
Findings lifecycle: every proof-promoted DAST, connected-device, Hunt, Interactive, AI Gate,
ASM, manual, and model-intake result lands in one
findings table, de-duplicated by (target_id, fingerprint). Findings have a status
(active / resolved / false_positive / accepted_risk), CVSS, CWE/OWASP tags, evidence,
optional AI verdict fields, and verification history. The UI exposes DAST, Hunt, Interactive,
AI Gate, Model Intake, ASM, and Manual filters. The API source_type filter accepts the canonical
deep_hunt value plus compatibility values:
dast, ai, ai_gate, ai_session, autonomous, deep_hunt, model_intake, asm, manual.
Scanner findings driven by a hunt are included in deep_hunt and excluded from dast, so one row
does not present two competing sources. model_intake and the AI sources also filter separately
from dast (R8).
Findings support filtering, sorting, bulk status triage from the list selection dock (POST /findings/bulk), previewed cleanup, manual creation, and per-finding retest.
Findings freshness is separate from status. Status answers whether someone triaged a finding;
first_seen_at / last_seen_at answer when a scan actually observed it, and a scan that does not
observe a finding never advances last_seen_at. The Findings page opens on Current (observed
within the last 14 days), says how many older findings that leaves out, and offers Not seen
recently and All; the card shows when the finding was last and first seen, whether it
returned after being resolved (resurfaced_count), and the latest retest verdict. "Not seen
recently" is deliberately not "fixed": absence from a later scan may only mean that scan never
reached the route. Web findings are never auto-resolved on non-observation — only connected-device
findings are, and only after a run that proved complete coverage — and a false_positive retest
verdict does not change status unless auto_fp_on_retest is enabled, so a human stays in the loop.
The API exposes the same partition through seen_within_days and its complement
not_seen_within_days, so paging and totals are computed server-side.
Evidence objects: finding evidence is indexed by hash, storage URI, retention class, scan/finding
links, and redaction profile. Large evidence can live in local content-addressed storage or an opt-in
S3/MinIO-compatible backend; evidence reads verify SHA-256 before returning remote or local content.
Retention sweeps are target-scoped and dry-run by default. A preview persists the exact candidate
snapshot, criteria, storage effects, policy hash, and expiry in PostgreSQL and cannot be altered at
execution time. The preview TTL defaults to 600 seconds; EVIDENCE_RETENTION_PREVIEW_TTL_SECONDS
is clamped to 60-3600 seconds.
Deletion requires a target-scoped, one-use dangerous approval whose action_name is exactly
evidence.retention_sweep and whose canonical action context is exactly preview_id,
preview_hash, and target_id from that preview. The approval must expire no later than the
preview. The execution body contains only dry_run:false, preview_id, and
approval_receipt_id; resubmitted target, age, class, limit, or storage-deletion criteria are
rejected.
Execution locks and revalidates the immutable rows, storage-reference effects, and finding/scan
ownership, then commits durable executing intent and per-object pending markers before external
blob deletion. A retry with the same preview and approval resumes unfinished work, treats an
already-missing content-addressed blob as completed, and finalizes the persisted intent. Once the
preview is consumed, the same retry returns the stored result idempotently instead of repeating
side effects. Legal hold and evidence attached to active findings are never candidates. Local or
remote blob failures preserve their database rows, and drift or a reused/mismatched approval fails
closed.
Evidence instances and exports: proof instances bind a concrete route/object/payload/principal
pair to evidence objects, tool receipts, campaign actions, proof state, and retention policy. APIs
list/record instances, export content-free manifests or bounded bundles, verify object hashes on
read, and record export events. Retention classes are short, standard, audit, legal_hold, and
sensitive; legal hold is never swept.
HTTP transaction archive: GET /scans/{id}/http-transactions and
GET /hunts/{id}/http-transactions export instrumented calls as ShakerScan transaction JSON or HAR
1.2, aggregating descendant scan shards for a user-visible parent. JSON is redacted by default. HAR
is deliberately raw replay evidence and may contain credentials and bodies; raw non-HAR JSON also
requires SHAKERSCAN_HTTP_ARCHIVE_ALLOW_RAW plus the operator credential. The export's fidelity
and archive stats distinguish complete, partial, unavailable, failed, and dropped capture; absence
of an archived row is not proof that no request occurred. Operator-authenticated DELETE routes
purge the archive and unreferenced blobs without requiring raw export to be enabled.
Mission campaigns and action ledger: campaigns are durable operating wrappers over Continuous
ASM, authenticated DAST, API authorization, AI red-team, Model Intake, benchmark, and retest work.
Campaign actions retain plan/command/scope/approval/evidence/hypothesis/tool-receipt links and
explicit execution state. The cross-product /timeline merges actions, scans, evidence, exports,
refuter reviews, and upcoming schedules.
Campaign list/detail reads compute current finding impact across every linked action in one live
rollup. The displayed critical/high blocker count is explicitly a default-policy estimate, not the
authoritative per-scan deployment decision.
Batch scan submission: POST /scans/batch accepts 1-50 targets, de-duplicates them, and returns
accepted jobs plus per-target failures. Partial queueing is explicit (status: partial) rather than
being reported as all-or-nothing success.
Hypothesis lifecycle: source/spec hints, operation plans, benchmark artifacts, scanner signals, and application-graph producer/object/consumer facts can create source-only hypotheses. Hypotheses support dedupe, optimistic versions, leased claims, endorsements/refutations, signals, next-test planning, situation reports, and campaign linkage. Only exact existing deterministic finding proof can reconcile a hypothesis into the canonical finding path.
Refuter reviews: durable support/question/weaken/refute signals challenge weak or high-impact claims. Summary, queue, execution, and verdict derivation APIs delegate to existing gated replay or retest primitives. Signal-only, failed, error, and AI-only results cannot create proof-backed verdicts.
Scope, approval, context, and decision contracts: scope previews create bounded receipts; approval/denial receipts bind confirmations and expiry to that scope. Operation plans, command results, agent context packs, agent decision traces, tool receipts, evidence instances, and campaign actions are versioned/redacted audit records. Local-agent planning remains dry-run and parser- validated; it has no raw-shell command or direct finding authority.
Exposure graph (/exposure/*): a derived graph across domains, targets, APIs, auth roles,
vendors, AI surfaces, MCP tools, model artifacts, scans, and findings, with asset-centric breakdowns
(by owner/tier/classification), change deltas over time, and attack-path views. Backs the UI
/exposure page.
Dashboard & queue: /dashboard (active/critical counts, average score, running scans),
/queue/stats, and /queue/clear.
Verification & retest: deterministic provers exist for xss, sqli, ssrf, path_traversal,
open_redirect, cors, command_injection, ssti, xxe, jwt, idor, bola, and exposed_file; others can be
replayed by the AI tier. Retests are slot-limited (RETEST_MAX_PARALLEL) with a watchdog and
auto-retest-on-scan-complete policy.
13. REST API reference (by area)
Base URL http://localhost:8080. Most structured POST/PATCH operations accept JSON, while some
control and discovery operations use query parameters or no body. FastAPI also serves the live schema
at /openapi.json. The curated groups below explain product areas; §17 is the exhaustive generated
method/path catalog. (See api/api.py for handlers. The agent-facing
how-to with request bodies is in AGENTS.md.)
Health & settings: GET / · GET /health · GET|PUT /settings/ai · POST /settings/ai/test ·
GET|PUT /settings/scan-execution · GET|PUT /settings/automation
Multi-node fleet: POST|DELETE /fleet/join-tokens[/{token_id}] · POST /fleet/nodes/join ·
GET /fleet/nodes · POST /fleet/scale · GET|PATCH /fleet/nodes/{id}/state ·
GET /fleet/nodes/{id}/activity · GET /fleet/nodes/{id}/events · POST /fleet/nodes/{id}/heartbeat ·
POST /fleet/nodes/{id}/connection-bundle · POST /fleet/nodes/{id}/credentials/rotate ·
POST /fleet/nodes/{id}/revoke · /fleet/broker/*. Join tokens and node credentials are returned once and stored only
as hashes. Enrollment returns the public fleet CA alongside one-time node identity material. Fleet
operator reads and lifecycle operations require either an actual loopback socket peer or the
high-entropy bearer generated by fleet init; a loopback host-port publish does not authenticate
Docker-network peers. Non-loopback operator traffic requires HTTPS except for ShakerScan's narrow
token-authenticated HTTP exception when the persisted bind exactly matches the host's currently
verified Tailscale IPv4. Enrollment and
secret delivery require HTTPS, and connection bundles
also require the actual socket peer to be inside the configured overlay CIDR. Node state pulls and
heartbeats likewise reject plaintext transport so node bearer credentials are never sent over HTTP.
The worker-only Compose
WireGuard worker runtime requires a digest-pinned image and starts no UI, API, Redis, or Postgres. Its pull-based agent
uses owner-only local state, reconciles only node-labeled workers on the local Docker engine, and
reports applied state/capacity/errors. scanner.sh fleet init, fleet join-token, fleet reconcile,
and scanner.sh join provide the Linux host workflow with owner-only state, explicit system/private
CA trust, CA-verified overlay proof, one-time bundle persistence, and pinned-image startup. Broker
nodes receive no Redis, PostgreSQL, or object-store credentials and use outbound HTTPS only. On an
initialized Linux control plane, the Fleet UI manages capacity, drift, drain/resume, image rollout,
lifecycle events, and revocation. It stays hidden on standalone installs.
shakerscan fleet accept is implemented; development broker execution has passed on two local-build
VPS nodes, while the frozen, digest-pinned physical release run and fault matrix remain pending.
Command Arsenal: GET /arsenal/commands · GET /arsenal/contracts ·
POST|GET /arsenal/plans · POST|GET /arsenal/context-packs ·
POST /arsenal/context-packs/from-target · POST|GET /arsenal/decision-traces ·
GET /arsenal/command-results · POST /arsenal/scope/preview · POST /arsenal/approvals ·
GET /arsenal/tools · GET|POST /arsenal/refuter-reviews ·
GET /arsenal/refuter-reviews/summary · POST /arsenal/refuter-reviews/queue-from-summary ·
POST /arsenal/refuter-reviews/{id}/execute ·
POST /arsenal/refuter-reviews/{id}/derive-verdict ·
POST /arsenal/hypotheses/source-ingest · POST /arsenal/hypotheses/from-plan ·
POST /arsenal/hypotheses/{id}/reconcile-proof ·
GET /agents/local · POST /agents/local/test · POST /agents/local/plan. Source/spec hints and
saved dry-run plan actions can be recorded as source-only hypotheses; they never create findings or
queue scans. Worker finalization also routes uncertain medium-or-higher scanner findings into
scanner_signal hypotheses with deterministic finding.retest next actions; verified findings stay
on the finding/proof path instead of duplicating into the lead queue. The /settings/arsenal UI
includes a Source Hint Ingest panel for bounded source/spec/route facts. Refuter verdict derivation is
gated and derives only from a linked or explicit verification row; failed/error/AI-driven results remain signal-only. Authz replay promotion
requires an authenticated cross-principal differential, treats login/forbidden soft-200 bodies and
redirect denials as non-violations, and validates approval receipts against the campaign action's
actual target before a manual BOLA finding can be created.
Hypothesis proof reconciliation is separately approval-gated and can only link an existing
exploited canonical finding with exact campaign-action, target, family, and route dimensions; it
never creates or verifies a finding from lead context.
Bounded Research Agent: GET /research/readiness · POST|GET /research/episodes ·
GET /research/episodes/{id} · POST /research/episodes/{id}/decisions ·
POST /research/episodes/{id}/observe · POST /research/episodes/{id}/settle ·
POST /research/episodes/{id}/cancel. An episode is a target-bound state machine over immutable,
redacted ObservationPack rows and exactly-one-action DecisionEpisode rows. Decisions are bound to
the current observation ID/hash, cannot carry receipts or credentials, must declare an expected
signal and falsifier, and consume bounded step/action/time/request/model-token budgets. The campaign
and episode APIs supply server-owned target-hunt, exact-finding, and ASM-gap missions, deduplicate
concurrent one-click launches, and reserve a final synthesis step. The UI launches these missions from Finding
Detail, Continuous ASM, and registered web assets in Exposure as well as from the main Autonomous
Hunt page. Linked scans and finding retests must settle
before exactly one result-bearing observation is attached. No-progress duplicate actions are rejected
until a state-changing action occurs, and provider failures meter model usage before retry. Scan/ASM
request values are conservative reservation units rather than exact HTTP counts. Shadow mode
records decisions without dispatch. Read-only mode dispatches only the target-scoped inspection
allowlist. Gated mode can additionally dispatch asm.improve, asm.recon, asm.test,
finding.retest, scan.focused_family, experiment.http_diff, and experiment.workflow through the existing Arsenal gateway when a matching
scope/approval receipt and the global execution flag are present. Target IDs/URLs and receipts are
injected by the server. Research campaigns persist one of three planner modes. agent is the
clean-install default: the current Codex/Claude/OpenCode session reads the immutable observation and
submits one bounded decision without a stored provider. configured_ai uses AI settings and durable
server autopilot. local_codex uses the host-side
./scanner.sh research <episode-id> [max-decisions] with an isolated ephemeral Codex process and
fails fast when server autopilot is enabled for the episode, preventing two planners from racing the
same immutable observation. Pause server autopilot before invoking the local runner. The command
prints a compact decision/episode receipt and UI path instead of the full observation pack. A planner
cannot mint proof or findings. A trusted server-side workflow replay may create or refresh a finding
only after deterministic family proof and the promotion gate pass. Cancellation terminates the
episode, cancels linked queued retests and pending/running scans where possible, and reports
already-running retests as continuing rather than pretending they stopped.
experiment.http_diff is the first typed adaptive experiment actuator. It accepts two to four
anonymous control/mutation/verification requests using relative same-origin paths, JSON or form
bodies, bounded query/header mutations, and named scalar extraction from non-sensitive JSON paths
or response headers. Later steps may reference extracted resource values as ${name}; every
rendered request is revalidated before dispatch. It forbids model-supplied credential/host headers
and redirects. Autonomous planner proposals are limited to GET, HEAD, and OPTIONS;
experiment.http_diff cannot receive cleanup-safe write authority because it has no restoration
contract. The manual typed-experiment surface retains the broader runtime method contract. Variable
references and extract names are preflighted across the complete experiment,
so undeclared, forward, duplicate, or over-budget variables fail before any request is sent. Query
and form values are constrained to bounded scalars. Responses are closed after a capped streaming
prefix, extracted values are persisted as hash/length metadata, and failed steps are marked
non-comparable instead of producing synthetic deltas. The result records status/body/JSON-shape,
selected JSON/header, timing, and before/after comparisons in a tool receipt plus an unverified evidence instance. The
research budget reserves four requests before dispatch. Experiment signals cannot directly create
or verify findings; a family-specific deterministic verifier must establish proof.
experiment.workflow extends the actuator with two to twelve typed HTTP/browser steps and
server-resolved principal slots (anonymous, user1, user2, admin, or tenant:<id>). It
supports before/mutation/after/action/cleanup/rollback checkpoints, same-origin navigation, click,
fill, submit, bounded wait, scalar extraction, and shared ${name} resources. Credential profiles
are decrypted only in API memory and are never accepted in planner parameters. Cross-principal
workflows require distinct profile IDs and distinct verified account fingerprints before any target
or browser request. Results contain content-free principal/profile/role/tenant identity receipts,
bounded mixed HTTP/browser observations, comparisons, assertions, and restoration outcomes. A
caller-supplied workflow UUID allows cooperative cancellation through
POST /experiments/workflows/{id}/cancel; cancellation is checked between steps and browser contexts
always close in a finally block. Credential-tier Hunt may receive PUT, PATCH, and DELETE
steps only through the typed workflow contract, with later cleanup/rollback and restoration
assertions. The server independently re-executes a promotable workflow, derives family predicates
from observed results, and may create or refresh a canonical finding only when deterministic family
proof and promotion gates pass. Create-based mass-assignment workflows may leave explicitly labeled
test objects when the discovered target has no delete route; this bounded exception is limited to
server-materialized create/read-back proof and is surfaced in the run outcome.
MCP — read-only Arsenal inspection plus target-bound Hunt V2: ./scanner.sh mcp starts a stdio
adapter. Arsenal inspection exposes targets, ASM gaps, findings, content-free evidence manifests,
the mission timeline, saved dry-run plans, and tool status through POST /arsenal/execute; it
revalidates the live catalog and never represents state-changing Arsenal commands. Hunt tools load
GET /hunts/contract, generate the canonical start schema, expose progressive methodology
suggest/read/bind/unbind/usage operations, and wrap start/get/query/capability/candidate-create/
candidate-update/candidate-delete/verify/finish/cancel. Candidate edits are
Hunt-scoped and cannot alter deterministic proof state; deletion retains an immutable audit record.
Capability calls require the live Hunt manifest, validate its
published input schema, and use a caller-provided or returned generated idempotency key. Target
binding, approvals, budgets, receipts, evidence, and deterministic proof remain server-enforced.
See docs/mcp.md.
Scans (DAST): POST /scans · POST /scans/batch · GET /scans · GET /scans/{id} ·
GET /scans/{id}/result · GET /scans/{id}/logs · POST /scans/{id}/cancel ·
GET /scans/{id}/deployment-decision · GET /scans/{id}/ai-redteam-report ·
GET|DELETE /scans/{id}/http-transactions
Findings: GET /findings · GET /findings/{id} · PATCH /findings/{id} · DELETE /findings/{id} (list filters include severity, status, source_type, target_id, scan_id, root_domain, search, seen_within_days, not_seen_within_days, first_seen_within_days, resolved_within_days, verification_verdict, verified_only)
· POST /findings/bulk · POST /findings/cleanup · POST /findings/manual ·
POST /findings/{id}/retest · POST /findings/retest · GET /retests/{id} ·
GET /retests/finding/{id}
Targets & domains: GET /targets · GET /targets/grouped · GET /domains · POST /targets ·
GET /targets/{id} · PATCH /targets/{id} · DELETE /targets/{id} · POST /targets/{id}/scan
Connected devices: GET /devices/readiness · GET|POST /devices ·
GET|PATCH|DELETE /devices/{id} · POST /devices/{id}/scan ·
POST /devices/{id}/verify-service · GET /device-scans ·
GET|POST /devices/{id}/credentials · POST /devices/{id}/credentials/{profile_id}/rotate ·
DELETE /devices/{id}/credentials/{profile_id} · POST /devices/{id}/credentials/{profile_id}/acknowledge-lockout ·
GET|POST /device-policies · PATCH /device-policies/{id}
Hunt: GET /hunts/contract · GET /hunt/skills · GET /hunt/skills/{skill_id} ·
POST|GET /hunts · GET /hunts/{hunt_id} · GET /hunts/{hunt_id}/record ·
POST /hunts/{hunt_id}/skills/suggestions ·
POST /hunts/{hunt_id}/skills/{skill_id}/read|bind|usage ·
DELETE /hunts/{hunt_id}/skills/{skill_id} ·
POST /hunts/{hunt_id}/query · POST /hunts/{hunt_id}/capabilities/{capability_name} ·
POST /hunts/{hunt_id}/candidates · PATCH|DELETE /hunts/{hunt_id}/candidates/{candidate_id} ·
POST /hunts/{hunt_id}/candidates/{candidate_id}/verify ·
POST /hunts/{hunt_id}/finish|cancel|resume · GET|DELETE /hunts/{hunt_id}/http-transactions
Every Hunt capability call carries a client-generated opaque idempotency_key. Repeating the same
key with the same semantic input returns the original durable action; reusing it for a different
capability or input fails closed.
All release-critical public V2 writes also accept the optional Idempotency-Key header published in
OpenAPI. The server binds its SHA-256 digest to the exact method, concrete path, and request-body
digest, stores no request body or raw key, and replays only an already-public successful JSON
response. This makes installed Scan, Hunt start, credential create/rotate, and collection mutations
safe to retry after a lost response. A key reused with different input returns 409; an in-flight
duplicate returns a bounded idempotency_request_in_progress response instead of executing twice.
Legacy device SSH, header, cookie, and form profiles are backfilled to same-ID generic profiles. Their older encrypted JSON envelopes are canonicalized without returning or logging plaintext; new and compatibility mutations remain transactional in both stores until device execution stops reading the legacy table. SSH profiles receive only the SSH-plan capability, while device Web profiles receive bounded replay/probe capabilities.
Continuous ASM: GET /asm/check-families · GET /targets/{id}/asm/endpoints ·
GET /targets/{id}/asm/coverage · POST /targets/{id}/asm/test · POST /targets/{id}/asm/recon ·
POST /targets/{id}/asm/prune · POST /targets/{id}/asm/improve · GET|PUT /targets/{id}/asm/policy
· GET /targets/{id}/asm/diff · GET /targets/{id}/asm/gaps · GET /targets/{id}/asm/activity
AI Gate: GET /ai/test-scenarios · GET /ai/test-cases · GET /ai/test-cases/export ·
GET /ai/learning-guide · POST /ai/demo/run · GET /ai/inventory · GET|POST /ai/targets ·
PATCH|DELETE /ai/targets/{id} · POST /ai/targets/{id}/scan · POST /ai/targets/{id}/test ·
POST /ai/targets/{id}/mcp/live-readiness · GET /ai/targets/{id}/runtime-risk ·
GET|POST /ai/targets/{id}/principals · PATCH|DELETE /ai/targets/{id}/principals/{pid} ·
GET|DELETE /ai/scans/{id}/transcript · POST /ai/findings/{id}/retest ·
POST /ai/surfaces/sync · GET /ai/surfaces · GET /ai/surfaces/{id}/attempts
Model Intake: POST /model-intake/resolve · POST /model-intake/scan ·
POST /model-intake/targets/{id}/rescan · GET|POST /model-intake/trust-anchors ·
PATCH|DELETE /model-intake/trust-anchors/{id} ·
GET /model-intake/scans/{id}/evidence-export · GET /model-intake/capabilities ·
POST /model-intake/admission/verify · GET /model-intake/admissions ·
GET /model-intake/admissions/{id} · POST /model-intake/admissions/{id}/revoke ·
POST /model-intake/reassessment/events · POST /model-intake/retention/cleanup
Governance (deployment gate): GET|POST /policy-profiles · PATCH|DELETE /policy-profiles/{id} ·
GET|POST /finding-exceptions · PATCH|DELETE /finding-exceptions/{id} ·
POST /finding-exceptions/lifecycle/sweep
Evidence and mission control: GET|POST /evidence/instances · GET /evidence/{id} ·
GET /evidence/export-manifest · GET /evidence/export-bundle ·
POST /evidence/retention/sweep · GET /timeline · GET|POST /arsenal/campaigns ·
GET /arsenal/campaigns/{id} · POST /arsenal/campaigns/{id}/actions ·
GET|POST /arsenal/tool-receipts
AI Ops Router: POST /ai/ops/route
Interactive sessions: POST /session/start · GET /session/{id} · POST /session/{id}/screenshot
· GET /session/{id}/screenshot.png · POST /session/{id}/action · POST /session/{id}/test-endpoint
· POST /session/{id}/findings · DELETE /session/{id} · GET /sessions
Generic credential profiles: GET|POST /credential-profiles ·
GET|PATCH|DELETE /credential-profiles/{profile_id} ·
POST /credential-profiles/{profile_id}/rotate. These exact-target Web, API, network, and device
profiles use immutable encrypted versions, metadata-only responses, capability bounds, expiry, and
primary/secondary/service/SSH slots. Scan and Hunt queue only opaque IDs; workers revalidate the
target-bound approval and decrypt the admitted version immediately before execution. A bearer
profile may expose a nonsecret browser_storage_key for authenticated SPA crawling; cookie values
and bearer tokens remain worker-private, are placed only in an ephemeral browser profile, and are
never returned or passed on the scanner command line.
Legacy target credentials and principals: GET|POST /targets/{id}/credential-profiles ·
PATCH|DELETE /targets/{id}/credential-profiles/{profile_id} ·
POST /targets/{id}/credential-profiles/{profile_id}/rotate · GET|POST /targets/{id}/principals ·
PATCH|DELETE /targets/{id}/principals/{principal_id} · GET|POST /targets/{id}/principal-matrix.
This compatibility surface remains metadata-only and write-only for secrets. Existing rows are
backfilled under the schema migration lock and every create, rotation, principal-slot change, and
deactivation is transactionally mirrored to the generic immutable store. Generic rename, rotation,
expiry, and deactivation changes are mirrored back while legacy execution remains enabled. Ciphertext is never
returned or logged. An ID/target/auth-kind collision fails closed instead of overwriting a generic
identity. These routes will be removed after remaining legacy callers migrate.
Discovery & exposure: POST|GET /discovery · GET /discovery/{id} · GET /dashboard ·
GET /exposure/graph · GET /exposure/nodes · GET /exposure/assets · GET /exposure/changes ·
GET /exposure/attack-paths
Schedules: GET|POST /schedules · GET|PATCH|DELETE /schedules/{id}
Workers, queue, gungnir, results: GET|POST /workers · GET /queue/stats · DELETE /queue/clear
· GET /gungnir/status · POST /gungnir/start · POST /gungnir/stop · GET /results ·
GET /results/{folder}/latest
14. Configuration and integrated tools
Key environment variables (.env):
- AI analysis:
AI_URL,AI_API_KEY,AI_MODEL,AI_FALLBACK_MODEL. - AI retest verification:
AI_VERIFY_ENABLED,AI_VERIFY_URL,AI_VERIFY_API_KEY,AI_VERIFY_MODEL,AI_VERIFY_USE_BROWSER,AI_VERIFY_MAX_PER_SCAN,AI_VERIFY_MIN_SEVERITY. - AI Ops Router execution gate:
AI_OPS_ROUTER_EXECUTE_ENABLED(default on; setfalsefor a global kill switch). - Evidence-retention preview lifetime:
EVIDENCE_RETENTION_PREVIEW_TTL_SECONDS(default 600 seconds, clamped to 60-3600 seconds). - AI Gate transcripts:
AI_GATE_TRANSCRIPT_RETENTION_DAYS(retention label, default 30);AI_TRANSCRIPT_ALLOW_SENSITIVE(default off — when on,GET /ai/scans/{id}/transcript?include_sensitive=truereturns raw, audit-logged bodies; otherwise responses are redacted at response time). - Credential encryption-at-rest:
AI_CREDENTIAL_ENC_KEYmay supply the stable Fernet key. When it is unset, the runtime creates and persists an owner-only shared key underRESULTS_DIR. Every new secret write must produce anenc:fernet:value or fails closed. Plaintext is accepted only when reading a legacy row long enough to migrate it; it is never a supported new-write mode. - Allocation fallback:
COVERAGE_ALLOCATION_DEFAULT. Shard ceilings:SHAKERSCAN_MAX_SHARDS,SHAKERSCAN_COVERAGE_MAX_SHARDS,PARALLEL_SHARD_MAX_PER_PARENT, etc. - Custom dictionaries:
SHAKERSCAN_CUSTOM_WORDLIST,SHAKERSCAN_CUSTOM_<CAT>_PAYLOADS. - Deployment/binding:
SHAKERSCAN_BIND_HOST(UI/API),SHAKERSCAN_DATA_BIND_HOST(Redis/Postgres; loopback by default),SHAKERSCAN_PUBLIC_HOST,SHAKERSCAN_REMOTE. - Data-store authentication:
REDIS_PASSWORD,POSTGRES_PASSWORD(shakerscan startgenerates strong owner-only values when missing/weak and migrates the historical standalone Postgres default; Compose has no well-known password fallback). - Owned-fleet bootstrap:
FLEET_OVERLAY_CIDR,FLEET_CONTROL_PLANE_OVERLAY_URL,FLEET_WIREGUARD_PUBLIC_KEY,FLEET_WIREGUARD_ENDPOINT, digest-pinnedFLEET_WORKER_IMAGE_DIGEST, generatedFLEET_OPERATOR_TOKEN, and one-timeFLEET_CONNECTION_BUNDLE_JSON. Insecure enrollment is disabled by default and its explicit test escape hatch works only from loopback.
Integrated external tools: httpx (HTTP probing), katana (crawling), nuclei (templates),
ffuf/meg/dirb/gobuster (content discovery), dalfox/XSStrike (XSS), sqlmap/commix
(injection), subfinder/Gungnir/dnsrecon (domain discovery), tlsx/SSLyze/testssl.sh/OpenSSL (TLS),
nmap/masscan/netcat (ports and services), nikto, hydra/medusa, whois, Shodan client support,
and Playwright (browser). The authoritative execution-facing adapter catalog is generated in §17;
an installed binary is not automatically a runnable ShakerScan adapter. Subprocess execution is
concurrency-limited with per-tool timeouts and a global deadline.
15. Safety model
- Authorization: only scan targets you own or are explicitly authorized to test. A Scan sends state-changing or exploit-style probes only when its explicit policy and target-bound approval permit them; a resource ceiling never grants active authority. AI Gate production scans and ASM BOLA likewise require explicit confirmation.
- Bounded automation: passive recon and ASM new-surface tracking can be safe-on by default; active exploitation uses small safe batches and requires an explicit Lab/deep policy for deep exploit mode. Rate tokens are reserved before active work is queued.
- Coverage honesty: an endpoint is only counted
testedwhen scanner telemetry proves it was attempted/completed; timeouts/partials never inflate coverage. - Local binding: laptop mode binds to
127.0.0.1; remote mode binds to a Tailscale IP. Exposing on0.0.0.0is only safe behind a firewall/VPN/reverse proxy. - AI redaction and credential handling: sensitive headers/bodies and secret-bearing URL
params/metadata are redacted
before any content is sent to an AI provider, via the shared
redact_sensitive()helper (R2a). AI-target and target-profile credential secrets are encrypted at rest with a configured or auto-generated persistent key (R2b); unavailable stable encryption fails new writes closed, and transcript responses are redacted at response time by default (R3). Normal DAST worker launches pass auth material through a short-lived0600auth-config file rather than raw scanner subprocess argv, and scan-time AI provider keys are supplied through the child environment instead of--ai-api-key.
16. UI, CLI, skills, and agent surfaces
Web UI routes
| Route | Operator capability |
|---|---|
/ | Security posture, prioritized action center, recent activity, and a compact operations header for queue state, emergency clear, worker scaling/freshness, and Gungnir CT |
/docs | Safe in-app rendering of the installed README, including GitHub-flavored tables and code blocks |
/scan/new | One deterministic Scan with budget and policy controls, exact-target opaque primary/secondary credential-profile references, known endpoints, custom ceilings, and bounded batch submission with partial-failure receipts |
/scans | Filter, inspect, cancel, and rescan logical scans without exposing internal rows by default |
/scans/{id} | Live progress/logs, durable Model Intake activity, report, proof/coverage, deployment decision, AI/Model Intake panels, replay, history, and PDF |
/targets | Hierarchical target inventory, search/filter/sort, scanning, discovery, duplicate merge, and schedule entry points |
/devices | Separate connected-device inventory, readiness, all-port posture submission, policy assignment, and service/finding summaries |
/devices/{id} | Device identity, interfaces, listening services, policy decisions, discovered web origins, and scan history |
/devices/policies | Built-in and custom service allowlists with allow/deny/review/required-control rules and activation lifecycle |
/targets/{id}/graph | Route/object/principal graph, producer/consumer/auth edges, and graph-derived hypotheses |
/asm | Coverage, scheduler state, proof-family gaps, recommendations, endpoint inventory, inventory prune, and campaign timeline |
/timeline | Cross-product mission feed of command results, scans, schedules, evidence bindings, refuters, and exports |
/campaigns | Read-only mission campaign records with lifecycle status and live linked-finding impact |
/campaigns/{id} | Campaign detail: live default-policy impact estimate, all-action status rollup, and the bounded action ledger |
/exposure | Cross-product graph, asset inventory, deltas, and attack paths |
/findings | Granular source/severity/status/domain/date filters, sorting, bulk triage, cleanup, and retest entry points |
/findings/{id} | Evidence, raw request/response, proof/retest history, notes, status, deletion, and remediation |
/evidence | Evidence-instance inventory, single-object inspection, content-free export manifests/bundles, and immutable-preview, exact-approval retention cleanup |
/credentials | Metadata-only management for encrypted, exact-target-bound Web, API, network, and device credential profiles, including principal slots, rotation, expiry, capability bounds, and deactivation |
/schedules | Recurring normal scans and target-scoped ASM waves; evidence cleanup is interactive-only and legacy retention schedules are disabled |
/settings | AI provider, scan execution, and automation policy settings |
/ai-gate | AI target/principal lifecycle, inventory, readiness, probe packs, scans, longitudinal history, and durable AI surface inventory |
/model-intake | Reference resolution, trust preview/anchors, presets, policy selection, and intake submission |
/settings/policy-profiles | Deployment policy profile lifecycle across DAST, AI Gate, and Model Intake |
/settings/arsenal | Command contracts, receipts, plans, actions, hypotheses (claim/signal/plan-campaign, from-plan/from-benchmark generators), refuters, tools, local agents, context packs, and traces |
/hunt | Launch and inspect the canonical target-kind-aware Hunt runtime through /hunts/*, with exact-target generic primary, secondary, service, and SSH credential-profile selection |
/deep-hunt | Compatibility redirect to /hunt |
/deep-hunt/experiment | Create bounded HTTP-differential or managed-principal workflow experiments |
/deep-hunt/runs/{id} | Inspect a durable experiment run and its proof handoff |
/deep-hunt/leads | Review durable research leads and route them to the appropriate product workflow |
/deep-hunt/operator, /deep-hunt/explorer | Compatibility redirects to /deep-hunt (former split-page URLs) |
API-only or partially UI-backed workflows
Not every public operation should have a dedicated screen. The following remain intentionally available primarily to CI, agents, integrations, or advanced operators: raw result/result-folder reads; direct evidence-instance/tool-receipt recording; MCP read-only Arsenal inspection and target-bound Hunt V2; generic Arsenal execution; local-agent output parsing; host-side Codex episode driving; and bulk finding retest/update/manual creation. §17 lists every operation so this boundary is visible rather than accidental.
Several workflows that were previously API-only now have UI surfaces: the cross-product mission timeline
(/timeline), read-only mission campaign list/detail (/campaigns), evidence browsing plus content-free
manifest/bundle export and approval-gated retention sweeps (/evidence), the durable AI surface inventory
(inside /ai-gate), hypothesis claim/signal/plan-campaign and the from-plan/from-benchmark
generators (inside /settings/arsenal), the natural-language AI Operations Router (POST /ai/ops/route, API only),
and the one-click operational actions batch scan (/scan/new), target dedupe (/targets), queue emergency
clear (/), and ASM inventory prune (/asm).
Scanner CLI
scanner.sh scan is the canonical client. It submits scan-start/v2, loads the server contract,
accepts budget/policy/family/credential/collection/placement/advanced-ceiling inputs, supports
automation-safe --json, and never accepts raw reusable secrets. It prints the Scan ID and UI link
and exits without polling. The old scan-full, scan-smart, and scan --type ... write paths are
removed. Historical records remain readable through the audit
surfaces; they cannot create plans or queue work.
scanner/scanner.py and its large flag inventory are compatibility/internal detector implementation
surface. They remain generated in §17 so maintainers can audit migration risk, but users and agents
must not treat those flags as separate V2 engines or trusted capability input.
The remaining scanner.sh commands operate service lifecycle, status/doctor, scaling, logs, builds,
offline report rebuild, agent/MCP launch, Fleet, Model Intake runner, Gungnir, environment inspection,
backup, and containers. §17 inventories the canonical wrapper commands.
Skills, slash commands, and specialized agents
ai-security-session: drives authorized interactive Playwright testing with explicit evidence and finding-save boundaries.shakerscan: routes general scans, targets, findings, Continuous ASM, AI Gate, Model Intake, operations, and bounded research while enforcing authorization and asynchronous handoff rules.js-analyze: converts bundles and browser evidence into routes, APIs, libraries, secret leads,custom_endpoints, and content-discovery seeds.content-discovery: builds generic and app-specific route/file/API lists and scanner/ffuf inputs.research-agent: compatibility skill for older prompts; it routes new investigations to canonical Hunt and keeps specialized guided experiments bounded.device-hunt: drives one authorized connected-device investigation through immutable scope, context, memory, fragility, health, and deterministic-evidence boundaries.device-triage: explains and compares existing connected-device evidence without sending traffic.review-skills: audits skills, commands, and subagents for broken references, unsafe prompts, and missing gates or output contracts.
The slash-command layer provides canonical Scan, Hunt, AI Gate, interactive session, finding list/ save, subdomain, worker, status, JS analysis, content discovery, bounded research, and skill-review workflows. Historical smart/full command files are compatibility shims that translate to explicit Scan policy/budget input and carry the same 2026-12-31 sunset. Three specialized Claude subagents back JS analysis, content discovery, and skill review. The product also catalogs Codex, Claude Code, OpenCode, and Hermes local-agent capabilities. The Codex research runner can submit one schema-constrained decision at a time, but only the API policy controller can dispatch an accepted Arsenal action; local-agent output never grants execution or finding authority.
17. Generated capability inventory
This appendix is generated directly from code and repository manifests. It is intentionally verbose: it is the exhaustive backstop behind the human-readable product map above.
Saved browser login and read-only QA
browser.login_check is a shared credential-gated Scan/Hunt action using an
operator-saved encrypted workflow. Select it with Scan browser_login_profile_ids
or Hunt's managed principal and browser.login_check capability. It performs one
login and fixed protected-page assertions, retains no exported browser state, and
does not grant permission to other actions. See browser login QA
for the profile contract, invocation, limits and acceptance gates.
Generated source inventory. Run
python3 scripts/generate_capability_inventory.pyafter changing any inventoried surface. CI uses--check; do not edit this block manually.
Inventory Summary
| Surface | Count | Source |
|---|---|---|
| Public REST operations | 430 | api/**/*.py FastAPI decorators |
| Unique REST paths | 359 | api/**/*.py |
| Check families | 18 | api/check_registry.py |
| Command Arsenal commands | 82 | api/command_arsenal.py |
| Tool adapters | 0 | api/command_arsenal.py |
| Local-agent adapters | 4 | api/command_arsenal.py |
| Internal compatibility scanner flags | 161 | scanner/scanner.py |
| Canonical scanner wrapper commands | 32 | scanner.sh |
| Deprecated wrapper aliases | 0 | scanner.sh |
| Make targets | 19 | Makefile |
| Release gates | 17 | scripts/release_gates.py |
| Runtime environment keys | 391 | Python sources + Compose manifests |
| Internal compatibility scanner modules | 122 | scanner/scanner_tools/ |
| UI pages | 38 | ui/src/app/ |
| Skills | 9 | skills/ |
| Canonical slash commands | 14 | .claude/commands/ |
| Deprecated Scan-name slash shims | 0 | .claude/commands/ |
| Specialized subagents | 3 | .claude/agents/ |
| Durable tables | 101 | db/init.sql + migrations |
Public REST Operations
| Method | Path | Handler |
|---|---|---|
GET | / | root |
GET | /agent/context/{target_id} | get_agent_context_pack |
GET | /agent/findings/{target_id} | get_agent_two_tier_findings |
GET | /agent/hunt/runs | list_agent_hunt_runs |
GET | /agent/hunt/session/{run_id} | get_agent_hunt_session |
POST | /agent/hunt/session/{run_id}/cancel | cancel_agent_hunt_session |
GET | /agent/tools/readiness | get_agent_tool_readiness |
GET | /agents/local | local_agents |
POST | /agents/local/plan | local_agent_dry_run_plan |
POST | /agents/local/plan/parse | local_agent_parse_candidate_plan |
POST | /agents/local/test | local_agent_test |
POST | /ai/demo/run | run_ai_honey_demo |
POST | /ai/findings/{finding_id:path}/retest | retest_ai_finding |
GET | /ai/inventory | get_ai_inventory |
GET | /ai/learning-guide | get_ai_learning_guide |
POST | /ai/ops/route | ai_ops_route |
GET | /ai/scans/{scan_id}/campaign-history | get_ai_scan_campaign_history |
POST | /ai/scans/{scan_id}/replay | replay_ai_scan |
DELETE | /ai/scans/{scan_id}/transcript | purge_ai_scan_transcript |
GET | /ai/scans/{scan_id}/transcript | get_ai_scan_transcript |
GET | /ai/surfaces | list_ai_surfaces |
POST | /ai/surfaces/sync | sync_ai_surfaces |
GET | /ai/surfaces/{surface_id}/attempts | list_ai_surface_attempts |
GET | /ai/targets | list_ai_targets |
POST | /ai/targets | create_ai_target |
DELETE | /ai/targets/{target_id} | delete_ai_target |
PATCH | /ai/targets/{target_id} | update_ai_target |
GET | /ai/targets/{target_id}/campaign-history | get_ai_target_campaign_history |
GET | /ai/targets/{target_id}/campaign-history/export | get_ai_target_campaign_history_export |
POST | /ai/targets/{target_id}/mcp/live-readiness | test_ai_target_mcp_live_readiness |
GET | /ai/targets/{target_id}/principals | list_ai_target_principals |
POST | /ai/targets/{target_id}/principals | create_ai_target_principal |
DELETE | /ai/targets/{target_id}/principals/{principal_id} | delete_ai_target_principal |
PATCH | /ai/targets/{target_id}/principals/{principal_id} | update_ai_target_principal |
GET | /ai/targets/{target_id}/runtime-risk | get_ai_target_runtime_risk |
POST | /ai/targets/{target_id}/scan | scan_ai_target |
POST | /ai/targets/{target_id}/test | test_ai_target_connectivity |
GET | /ai/test-cases | list_ai_test_cases |
GET | /ai/test-cases/export | export_ai_test_cases |
GET | /ai/test-scenarios | list_ai_test_scenarios |
GET | /api/v1/findings | list_cli_v1_findings |
GET | /api/v1/scan | get_cli_v1_scan |
POST | /arsenal/approvals | arsenal_create_approval |
POST | /arsenal/approvals/{approval_receipt_id}/revoke | arsenal_revoke_approval |
GET | /arsenal/campaign-actions | arsenal_campaign_actions |
POST | /arsenal/campaign-actions/{campaign_action_id}/authz-promote | arsenal_promote_authz_replay |
POST | /arsenal/campaign-actions/{campaign_action_id}/authz-replay | arsenal_execute_authz_replay |
GET | /arsenal/campaigns | arsenal_campaigns |
POST | /arsenal/campaigns | arsenal_create_campaign |
GET | /arsenal/campaigns/{campaign_id} | arsenal_campaign_detail |
POST | /arsenal/campaigns/{campaign_id}/actions | arsenal_link_campaign_action |
GET | /arsenal/command-results | arsenal_command_results |
GET | /arsenal/commands | arsenal_commands |
GET | /arsenal/context-packs | arsenal_agent_context_packs |
POST | /arsenal/context-packs | arsenal_create_agent_context_pack |
POST | /arsenal/context-packs/from-target | arsenal_create_agent_context_pack_from_target |
GET | /arsenal/contracts | arsenal_contracts |
GET | /arsenal/decision-traces | arsenal_agent_decision_traces |
POST | /arsenal/decision-traces | arsenal_create_agent_decision_trace |
POST | /arsenal/execute | arsenal_execute |
GET | /arsenal/family-proof/contracts | arsenal_family_proof_contracts |
POST | /arsenal/family-proof/evaluate | arsenal_family_proof_evaluate |
GET | /arsenal/findings/{finding_id}/refuter-panel | arsenal_finding_refuter_panel |
GET | /arsenal/hypotheses | arsenal_hypotheses |
POST | /arsenal/hypotheses | arsenal_record_hypothesis |
POST | /arsenal/hypotheses/from-benchmark | arsenal_generate_hypotheses_from_benchmark |
POST | /arsenal/hypotheses/from-plan | arsenal_generate_hypotheses_from_plan |
GET | /arsenal/hypotheses/schedule | arsenal_schedule_hypotheses |
GET | /arsenal/hypotheses/situation-report | arsenal_hypothesis_situation_report |
POST | /arsenal/hypotheses/source-ingest | arsenal_generate_hypotheses_from_source |
POST | /arsenal/hypotheses/{hypothesis_id}/claim | arsenal_claim_hypothesis |
POST | /arsenal/hypotheses/{hypothesis_id}/plan-campaign | arsenal_plan_hypothesis_campaign |
POST | /arsenal/hypotheses/{hypothesis_id}/reconcile-proof | arsenal_reconcile_hypothesis_proof |
POST | /arsenal/hypotheses/{hypothesis_id}/signals | arsenal_append_hypothesis_signal |
POST | /arsenal/hypotheses/{hypothesis_id}/transition | arsenal_transition_hypothesis |
GET | /arsenal/plans | arsenal_operation_plans |
POST | /arsenal/plans | arsenal_create_operation_plan |
GET | /arsenal/refuter-reviews | arsenal_refuter_reviews |
POST | /arsenal/refuter-reviews | arsenal_record_refuter_review |
POST | /arsenal/refuter-reviews/queue-from-summary | arsenal_queue_refuter_reviews_from_summary |
GET | /arsenal/refuter-reviews/summary | arsenal_refuter_review_summary |
POST | /arsenal/refuter-reviews/{refuter_review_id}/derive-verdict | arsenal_derive_refuter_review_verdict |
POST | /arsenal/refuter-reviews/{refuter_review_id}/execute | arsenal_execute_refuter_review_plan |
POST | /arsenal/scope/preview | arsenal_scope_preview |
GET | /arsenal/tool-receipts | arsenal_tool_receipts |
POST | /arsenal/tool-receipts | arsenal_record_tool_receipt |
GET | /arsenal/tools | arsenal_tools |
GET | /artifacts/storage/health | get_artifact_storage_health |
GET | /asm/check-families | asm_check_families |
GET | /authenticated-scan-profiles | list_profiles |
POST | /authenticated-scan-profiles | write_profile |
GET | /authenticated-scan-profiles/contract | contract |
GET | /authenticated-scan-profiles/validations/{request_id} | get_validation |
POST | /authenticated-scan-profiles/validations/{request_id}/cancel | cancel_validation |
GET | /authenticated-scan-profiles/{profile_id} | get_profile |
GET | /authenticated-scan-profiles/{profile_id}/history | get_profile_history |
POST | /authenticated-scan-profiles/{profile_id}/validate | validate_profile |
GET | /credential-profiles | list_credential_profiles |
POST | /credential-profiles | create_credential_profile |
GET | /credential-profiles/capabilities | credential_capability_catalog |
DELETE | /credential-profiles/{profile_id} | delete_credential_profile |
GET | /credential-profiles/{profile_id} | get_credential_profile |
PATCH | /credential-profiles/{profile_id} | patch_credential_profile |
POST | /credential-profiles/{profile_id}/rotate | rotate_credential_profile |
GET | /dashboard | dashboard |
POST | /data-deletion/execute | execute_record_deletion |
POST | /data-deletion/preview | preview_record_deletion |
GET | /device-agent/runs | list_device_agent_runs |
GET | /device-agent/session/{run_id} | get_device_agent_session |
POST | /device-agent/session/{run_id}/cancel | cancel_device_agent_session |
GET | /device-policies | list_device_policies |
POST | /device-policies | create_device_policy |
PATCH | /device-policies/{policy_id} | update_device_policy |
GET | /device-scans | list_device_scans |
GET | /devices | list_devices |
POST | /devices | create_device |
GET | /devices/readiness | get_device_readiness |
DELETE | /devices/{device_id} | deactivate_device |
GET | /devices/{device_id} | get_device |
PATCH | /devices/{device_id} | update_device |
GET | /devices/{device_id}/capabilities | get_device_capabilities |
GET | /devices/{device_id}/credentials | list_device_credentials |
POST | /devices/{device_id}/credentials | create_device_credential |
DELETE | /devices/{device_id}/credentials/{profile_id} | deactivate_device_credential |
POST | /devices/{device_id}/credentials/{profile_id}/acknowledge-lockout | acknowledge_device_credential_lockout |
POST | /devices/{device_id}/credentials/{profile_id}/rotate | rotate_device_credential |
POST | /devices/{device_id}/locator | change_device_locator |
GET | /devices/{device_id}/request-collections | list_device_request_collections |
POST | /devices/{device_id}/request-collections | create_device_request_collection |
DELETE | /devices/{device_id}/request-collections/{collection_id} | deactivate_device_request_collection |
GET | /devices/{device_id}/request-collections/{collection_id} | get_device_request_collection |
PATCH | /devices/{device_id}/request-collections/{collection_id} | update_device_request_collection |
POST | /devices/{device_id}/scan | scan_device |
POST | /devices/{device_id}/verify-service | verify_device_service |
GET | /discovery | list_discovery_runs |
POST | /discovery | start_discovery |
GET | /discovery/{discovery_id} | get_discovery |
GET | /domains | list_domains |
GET | /evidence/export-bundle | evidence_export_bundle |
GET | /evidence/export-manifest | evidence_export_manifest |
GET | /evidence/instances | list_evidence_instances |
POST | /evidence/instances | record_evidence_instance |
GET | /evidence/instances/{instance_id} | get_evidence_instance |
GET | /evidence/retention/executions | list_evidence_retention_executions |
POST | /evidence/retention/sweep | evidence_retention_sweep |
GET | /evidence/{evidence_id} | get_evidence_object |
POST | /experiments/workflows/{workflow_id}/cancel | cancel_workflow_experiment |
GET | /exposure/assets | exposure_assets |
GET | /exposure/attack-paths | exposure_attack_paths |
GET | /exposure/changes | exposure_changes |
GET | /exposure/graph | exposure_graph |
GET | /exposure/nodes | exposure_nodes |
GET | /exposure/services | exposure_services |
GET | /finding-exceptions | list_finding_exceptions |
POST | /finding-exceptions | create_finding_exception |
POST | /finding-exceptions/lifecycle/sweep | finding_exception_lifecycle_sweep |
DELETE | /finding-exceptions/{exception_id} | delete_finding_exception |
PATCH | /finding-exceptions/{exception_id} | update_finding_exception |
GET | /findings | list_findings |
POST | /findings/bulk | bulk_update_findings |
POST | /findings/cleanup | cleanup_findings |
POST | /findings/manual | create_manual_finding |
POST | /findings/retest | bulk_retest_findings |
DELETE | /findings/{finding_id:path} | delete_finding |
GET | /findings/{finding_id:path} | get_finding |
PATCH | /findings/{finding_id:path} | update_finding |
POST | /findings/{finding_id:path}/retest | retest_finding |
GET | /findings/{finding_id}/evidence | list_finding_evidence |
POST | /fleet/acceptance/lease-probe | run_fleet_acceptance_lease_probe |
POST | /fleet/broker/nodes/{node_id}/lease | lease_broker_job |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/actions/{action_id}/cancel | cancel_broker_scan_action |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/actions/{action_id}/heartbeat | heartbeat_broker_scan_action |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/actions/{action_id}/lease | lease_broker_scan_action |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/actions/{action_id}/observations | get_broker_scan_action_observations |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/actions/{action_id}/result | settle_broker_scan_action |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/actions/{action_id}/status | get_broker_scan_action_status |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/actions/{action_id}/work-manifest | get_broker_scan_action_work_manifest |
PUT | /fleet/broker/nodes/{node_id}/leases/{lease_id}/artifacts | upload_broker_job_artifact |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/cancel-status | get_broker_scan_cancel_status |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/continuation | continue_broker_scan_action_plan |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/heartbeat | heartbeat_broker_job |
POST | /fleet/broker/nodes/{node_id}/leases/{lease_id}/result | submit_broker_job_result |
POST | /fleet/join-tokens | create_fleet_join_token |
DELETE | /fleet/join-tokens/{token_id} | revoke_fleet_join_token |
GET | /fleet/nodes | list_fleet_nodes |
POST | /fleet/nodes/join | join_fleet_node |
GET | /fleet/nodes/{node_id}/activity | get_fleet_node_activity |
POST | /fleet/nodes/{node_id}/connection-bundle | get_fleet_connection_bundle |
POST | /fleet/nodes/{node_id}/credentials/rotate | rotate_fleet_node_credential |
GET | /fleet/nodes/{node_id}/events | get_fleet_node_events |
POST | /fleet/nodes/{node_id}/heartbeat | heartbeat_fleet_node |
POST | /fleet/nodes/{node_id}/revoke | revoke_fleet_node |
GET | /fleet/nodes/{node_id}/state | get_fleet_node_state |
PATCH | /fleet/nodes/{node_id}/state | update_fleet_node_state |
GET | /fleet/public-health | fleet_public_health |
POST | /fleet/scale | scale_fleet_workers |
POST | /gungnir/start | gungnir_start |
GET | /gungnir/status | gungnir_status |
POST | /gungnir/stop | gungnir_stop |
GET | /health | health |
GET | /health | health |
GET | /health | health |
GET | /health | health |
GET | /hunt/skills | list_hunt_skills |
GET | /hunt/skills/{skill_id} | get_hunt_skill |
GET | /hunts | list_hunts |
POST | /hunts | start_hunt |
GET | /hunts/contract | get_hunt_contract |
GET | /hunts/lifecycle-metrics | get_hunt_lifecycle_metrics |
GET | /hunts/{hunt_id} | get_hunt |
POST | /hunts/{hunt_id}/authorization-investigations | investigate_authorization |
GET | /hunts/{hunt_id}/authorization-investigations/{proposal_id} | read_authorization_investigation |
POST | /hunts/{hunt_id}/authorization-investigations/{proposal_id}/approve | approve_authorization_investigation |
GET | /hunts/{hunt_id}/authorization-investigations/{proposal_id}/reproduction | authorization_reproduction |
POST | /hunts/{hunt_id}/authorization-investigations/{proposal_id}/skip | skip_authorization_investigation |
GET | /hunts/{hunt_id}/budget-amendments | get_hunt_budget_amendments |
POST | /hunts/{hunt_id}/budget-amendments | amend_hunt_budget |
POST | /hunts/{hunt_id}/cancel | cancel_hunt |
POST | /hunts/{hunt_id}/candidates | create_hunt_candidate |
DELETE | /hunts/{hunt_id}/candidates/{candidate_id} | delete_hunt_candidate |
PATCH | /hunts/{hunt_id}/candidates/{candidate_id} | update_hunt_candidate |
POST | /hunts/{hunt_id}/candidates/{candidate_id}/verify | verify_hunt_candidate |
POST | /hunts/{hunt_id}/capabilities/{capability_name:path} | execute_hunt_capability |
POST | /hunts/{hunt_id}/finish | finish_hunt |
DELETE | /hunts/{hunt_id}/http-transactions | purge_hunt_transactions |
GET | /hunts/{hunt_id}/http-transactions | export_hunt_transactions |
POST | /hunts/{hunt_id}/query | query_hunt |
GET | /hunts/{hunt_id}/record | export_hunt_record |
POST | /hunts/{hunt_id}/resume | resume_hunt |
POST | /hunts/{hunt_id}/shell-plans/{plan_id}/confirm | confirm_hunt_shell_plan |
POST | /hunts/{hunt_id}/skills/suggestions | suggest_hunt_skills |
DELETE | /hunts/{hunt_id}/skills/{skill_id} | unbind_hunt_skill |
POST | /hunts/{hunt_id}/skills/{skill_id}/bind | bind_hunt_skill |
POST | /hunts/{hunt_id}/skills/{skill_id}/read | read_hunt_skill |
POST | /hunts/{hunt_id}/skills/{skill_id}/usage | record_hunt_skill_usage |
POST | /internal/model-intake/admissions/issue | issue |
POST | /internal/model-intake/runner/jobs | submit_job |
GET | /internal/model-intake/runner/jobs/{job_id} | get_job |
GET | /internal/model-intake/runner/storage | get_storage |
POST | /internal/model-intake/runner/storage/cleanup | cleanup_runner_storage |
GET | /investigation/candidates | list_investigation_candidates |
GET | /investigation/candidates/{candidate_id} | get_investigation_candidate |
GET | /metrics/v2 | get_v2_operational_metrics |
POST | /model-intake/admission/verify | verify_model_intake_admission |
GET | /model-intake/admissions | list_model_intake_admissions |
POST | /model-intake/admissions/v2/observe | observe_model_intake_deployment_v2 |
POST | /model-intake/admissions/v2/verify | verify_model_intake_admission_v2 |
GET | /model-intake/admissions/{admission_id} | get_model_intake_admission |
POST | /model-intake/admissions/{admission_id}/revoke | revoke_model_intake_admission |
GET | /model-intake/agent/session/{session_id} | get_model_intake_agent_session |
POST | /model-intake/agent/session/{session_id}/cancel | cancel_model_intake_agent_session |
POST | /model-intake/agent/session/{session_id}/reply | reply_model_intake_agent_session |
GET | /model-intake/automatic-reviews | list_model_intake_automatic_reviews |
POST | /model-intake/automatic-reviews | create_model_intake_automatic_review |
GET | /model-intake/automatic-reviews/{review_id} | get_model_intake_automatic_review |
GET | /model-intake/automatic-reviews/{review_id}/report | get_model_intake_automatic_review_report |
GET | /model-intake/capabilities | model_intake_capabilities |
GET | /model-intake/checks | model_intake_check_catalog |
POST | /model-intake/conversion-profiles/resolve | resolve_model_intake_conversion_profile |
POST | /model-intake/loader-profiles/resolve | resolve_model_intake_loader_profile |
GET | /model-intake/operator-session | model_intake_operator_session |
GET | /model-intake/providers/readiness | model_intake_provider_readiness |
POST | /model-intake/reassessment/events | create_model_intake_reassessment_event |
POST | /model-intake/resolve | resolve_model_intake |
POST | /model-intake/retention/cleanup | cleanup_model_intake_quarantine |
GET | /model-intake/runners/install-plan | model_intake_runner_install_plan |
GET | /model-intake/runners/readiness | model_intake_runner_readiness |
GET | /model-intake/runners/stage | model_intake_runner_stage_status |
POST | /model-intake/runners/stage | model_intake_runner_stage |
GET | /model-intake/runners/storage | model_intake_runner_storage |
POST | /model-intake/runners/storage/cleanup | model_intake_runner_storage_cleanup |
POST | /model-intake/scan | scan_model_intake |
GET | /model-intake/scanners/readiness | model_intake_scanner_readiness |
GET | /model-intake/scans/{scan_id}/evidence-export | get_model_intake_evidence_export |
GET | /model-intake/scans/{scan_id}/license-bom | download_model_intake_license_bom |
GET | /model-intake/scans/{scan_id}/sbom | download_model_intake_sbom |
GET | /model-intake/scans/{scan_id}/sbom/summary | model_intake_sbom_summary |
GET | /model-intake/scans/{scan_id}/third-party-notices | download_model_intake_third_party_notices |
GET | /model-intake/submissions | list_model_intake_submissions |
POST | /model-intake/submissions | create_model_intake_submission |
GET | /model-intake/submissions/{submission_id} | get_model_intake_submission |
POST | /model-intake/submissions/{submission_id}/agent/session | create_model_intake_agent_session |
GET | /model-intake/submissions/{submission_id}/agent/sessions | list_model_intake_agent_sessions |
POST | /model-intake/submissions/{submission_id}/approvals | create_model_intake_approval |
GET | /model-intake/submissions/{submission_id}/embedding-configuration | model_intake_embedding_configuration |
POST | /model-intake/submissions/{submission_id}/evidence-receipts | attach_model_intake_runner_evidence |
POST | /model-intake/submissions/{submission_id}/freeze-evidence | freeze_model_intake_evidence |
POST | /model-intake/submissions/{submission_id}/policy-decisions | create_model_intake_policy_decision |
POST | /model-intake/submissions/{submission_id}/promote | promote_model_intake_submission |
GET | /model-intake/submissions/{submission_id}/report | get_model_intake_submission_report |
GET | /model-intake/submissions/{submission_id}/runner-bundle | model_intake_runner_bundle |
GET | /model-intake/submissions/{submission_id}/runner-jobs | list_model_intake_runner_jobs |
POST | /model-intake/submissions/{submission_id}/runner-jobs | create_model_intake_runner_job |
POST | /model-intake/submissions/{submission_id}/runner-jobs/{job_id}/refresh | refresh_model_intake_runner_job |
POST | /model-intake/submissions/{submission_id}/static-runs | attach_model_intake_static_run |
POST | /model-intake/targets/{target_id}/rescan | rescan_model_intake_target |
GET | /model-intake/trust-anchors | list_model_intake_trust_anchors |
POST | /model-intake/trust-anchors | create_model_intake_trust_anchor |
DELETE | /model-intake/trust-anchors/{anchor_id} | deactivate_model_intake_trust_anchor |
PATCH | /model-intake/trust-anchors/{anchor_id} | update_model_intake_trust_anchor |
GET | /policy-profiles | list_policy_profiles |
POST | /policy-profiles | create_policy_profile |
DELETE | /policy-profiles/{profile_id} | delete_policy_profile |
PATCH | /policy-profiles/{profile_id} | update_policy_profile |
POST | /public/check | public_check |
DELETE | /queue/clear | clear_queue |
GET | /queue/stats | queue_stats |
GET | /request-collections | list_request_collections |
POST | /request-collections | create_request_collection |
DELETE | /request-collections/{collection_id} | deactivate_request_collection |
GET | /request-collections/{collection_id} | get_request_collection |
POST | /request-collections/{collection_id}/bindings | upsert_request_collection_binding |
POST | /request-collections/{collection_id}/environments | upsert_request_collection_environment |
DELETE | /request-collections/{collection_id}/environments/{environment_id} | deactivate_request_collection_environment |
GET | /request-collections/{collection_id}/requests | list_request_collection_requests |
POST | /request-collections/{collection_id}/select | select_request_collection_index |
POST | /request-collections/{collection_id}/selections | upsert_request_collection_selection |
DELETE | /request-collections/{collection_id}/selections/{selection_id} | deactivate_request_collection_selection |
POST | /research/campaigns/launch | launch_research_campaign |
POST | /research/campaigns/{campaign_id}/control | control_research_campaign |
GET | /research/episodes | list_research_episodes |
POST | /research/episodes | create_research_episode |
GET | /research/episodes/{episode_id} | get_research_episode |
PUT | /research/episodes/{episode_id}/autopilot | set_research_episode_autopilot |
GET | /research/episodes/{episode_id}/benchmark | research_episode_benchmark |
POST | /research/episodes/{episode_id}/cancel | cancel_research_episode |
POST | /research/episodes/{episode_id}/decisions | submit_research_decision |
POST | /research/episodes/{episode_id}/observe | refresh_research_observation |
POST | /research/episodes/{episode_id}/settle | settle_research_episode |
GET | /research/readiness | research_readiness |
GET | /results | list_results |
GET | /results/{target_folder}/latest | get_latest_result |
GET | /retests/finding/{finding_id:path} | list_finding_retests |
GET | /retests/{retest_id} | get_retest |
GET | /scan/contracts | get_scan_public_contract |
POST | /scan/contracts/preview | preview_scan_contract |
GET | /scans | list_scans |
POST | /scans | submit_scan_endpoint |
POST | /scans/batch | submit_batch_endpoint |
GET | /scans/dispatch-receipts/lookup | scan_dispatch_receipt |
GET | /scans/{scan_id} | get_scan |
GET | /scans/{scan_id}/actions | get_scan_actions |
GET | /scans/{scan_id}/ai-redteam-report | get_ai_redteam_report |
GET | /scans/{scan_id}/artifacts | list_scan_artifacts |
GET | /scans/{scan_id}/artifacts/{artifact_id} | download_scan_artifact |
GET | /scans/{scan_id}/authentication-assurance | get_scan_assurance |
POST | /scans/{scan_id}/cancel | cancel_scan |
GET | /scans/{scan_id}/capabilities | get_scan_capabilities |
GET | /scans/{scan_id}/coverage | get_scan_coverage |
GET | /scans/{scan_id}/deployment-decision | get_scan_deployment_decision |
GET | /scans/{scan_id}/device-activity | get_scan_device_activity |
DELETE | /scans/{scan_id}/http-transactions | purge_scan_transactions |
GET | /scans/{scan_id}/http-transactions | export_scan_transactions |
GET | /scans/{scan_id}/logs | get_scan_logs |
GET | /scans/{scan_id}/parity-artifact | get_scan_parity_artifact |
GET | /scans/{scan_id}/queue-delivery | get_scan_queue_delivery |
GET | /scans/{scan_id}/result | get_scan_result |
GET | /schedules | list_schedules |
POST | /schedules | create_schedule |
DELETE | /schedules/{schedule_id} | delete_schedule |
GET | /schedules/{schedule_id} | get_schedule |
PATCH | /schedules/{schedule_id} | update_schedule |
POST | /session/start | start_session |
DELETE | /session/{session_id} | end_session |
GET | /session/{session_id} | get_session_state |
POST | /session/{session_id}/action | session_action |
POST | /session/{session_id}/findings | create_session_finding |
POST | /session/{session_id}/screenshot | session_screenshot |
GET | /session/{session_id}/screenshot.png | session_screenshot_raw |
POST | /session/{session_id}/test-endpoint | session_test_endpoint |
GET | /sessions | list_sessions |
GET | /settings/ai | get_ai_settings |
PUT | /settings/ai | update_ai_settings |
POST | /settings/ai/test | test_ai_settings |
GET | /settings/automation | get_automation_settings |
PUT | /settings/automation | update_automation_settings |
GET | /settings/scan-execution | get_scan_execution_settings |
PUT | /settings/scan-execution | update_scan_execution_settings |
GET | /system/resources | get_system_resources |
GET | /targets | list_targets |
POST | /targets | create_target |
POST | /targets/dedupe | dedupe_targets |
GET | /targets/grouped | list_targets_grouped |
DELETE | /targets/{target_id} | delete_target |
GET | /targets/{target_id} | get_target |
PATCH | /targets/{target_id} | update_target |
POST | /targets/{target_id}/archive | archive_target |
GET | /targets/{target_id}/asm/activity | asm_activity |
GET | /targets/{target_id}/asm/coverage | asm_coverage |
GET | /targets/{target_id}/asm/diff | asm_diff |
GET | /targets/{target_id}/asm/endpoints | asm_list_endpoints |
GET | /targets/{target_id}/asm/gaps | asm_gaps |
POST | /targets/{target_id}/asm/improve | asm_improve |
GET | /targets/{target_id}/asm/policy | asm_get_policy |
PUT | /targets/{target_id}/asm/policy | asm_set_policy |
POST | /targets/{target_id}/asm/prune | asm_prune |
POST | /targets/{target_id}/asm/recon | asm_recon |
POST | /targets/{target_id}/asm/test | asm_test |
DELETE | /targets/{target_id}/authorization | revoke_target_authorization |
GET | /targets/{target_id}/authorization | get_target_authorization |
POST | /targets/{target_id}/authorization | authorize_target |
GET | /targets/{target_id}/credential-profiles | list_target_credential_profiles |
POST | /targets/{target_id}/credential-profiles | create_target_credential_profile |
DELETE | /targets/{target_id}/credential-profiles/{profile_id} | delete_target_credential_profile |
PATCH | /targets/{target_id}/credential-profiles/{profile_id} | update_target_credential_profile |
POST | /targets/{target_id}/credential-profiles/{profile_id}/rotate | rotate_target_credential_profile |
GET | /targets/{target_id}/graph | get_application_graph |
POST | /targets/{target_id}/graph/hypotheses | generate_application_graph_hypotheses |
GET | /targets/{target_id}/invariants | list_target_invariant_contracts |
POST | /targets/{target_id}/invariants | create_target_invariant_contract |
POST | /targets/{target_id}/invariants/compile | compile_target_invariant_rule |
POST | /targets/{target_id}/invariants/hypotheses | generate_target_invariant_hypotheses |
POST | /targets/{target_id}/invariants/{contract_id}/approve | approve_target_invariant_contract |
POST | /targets/{target_id}/invariants/{contract_id}/retire | retire_target_invariant_contract |
GET | /targets/{target_id}/invariants/{contract_id}/verification-plan | get_target_invariant_verification_plan |
POST | /targets/{target_id}/inventory/hypotheses | generate_endpoint_inventory_hypotheses |
GET | /targets/{target_id}/posture | get_target_posture |
GET | /targets/{target_id}/principal-matrix | list_target_principal_matrix |
POST | /targets/{target_id}/principal-matrix | upsert_target_principal_matrix |
DELETE | /targets/{target_id}/principal-matrix/{expectation_id} | delete_target_principal_expectation |
GET | /targets/{target_id}/principals | list_target_principals |
POST | /targets/{target_id}/principals | create_target_principal |
POST | /targets/{target_id}/principals/auto-provision | auto_provision_target_principals |
DELETE | /targets/{target_id}/principals/{principal_id} | delete_target_principal |
PATCH | /targets/{target_id}/principals/{principal_id} | update_target_principal |
POST | /targets/{target_id}/scan | scan_target |
GET | /timeline | mission_timeline |
POST | /validate | validate |
GET | /workers | get_workers |
POST | /workers | scale_workers |
Check-Family Registry
| Name | Phase | Family | Active | Risk | Runnable | Adapter | Telemetry | Description |
|---|---|---|---|---|---|---|---|---|
auth | active | access_control | True | medium | True | asm_endpoint_batch | active_endpoint_attempt_v1 | Read-only authenticated-vs-anonymous access checks for focused ASM endpoint batches. |
authz_surface | active | access_control | True | high | False | authz_surface_verify_batch | active_endpoint_attempt_v1 | Deterministic BFLA proof via anonymous vs authenticated route access differential. |
bola | active | access_control | True | high | True | asm_endpoint_batch | active_endpoint_attempt_v1 | Multi-user object authorization comparisons. Requires Lab/deep policy and two auth contexts. |
business_logic | active | workflow | True | high | False | none | planned_workflow_attempt | Workflow/business-logic testing. Planned for AI/manual-assisted campaigns. |
endpoint_security | passive | endpoint_surface | False | low | True | endpoint_scoped_surface | endpoint_surface_attempt_v1 | Target-wide API data exposure, webhook signature, and approval/authorization checks over the discovered endpoint inventory. |
headers | passive | headers | False | low | True | legacy_config_findings | planned_passive_attempt | HTTP security header posture checks. |
jwt | active | authentication | True | medium | True | legacy_advanced_jwt | jwt_probe_attempt_v1 | JWT algorithm, signature, key, and claim mutation checks with acceptance proof. |
lfi | active | server_side | True | high | False | none | planned_high_risk_attempt | File inclusion and path traversal checks. Planned and permission-gated. |
mass_assignment | active | access_control | True | medium | True | legacy_phase4_mass_assignment | mass_assignment_attempt_v1 | Bounded privileged-field mutation with baseline-vs-response effect proof. |
nosqli | active | injection | True | high | False | nosqli_verify_batch | active_endpoint_attempt_v1 | Deterministic Mongo-style operator injection proof over query and JSON candidates. |
nuclei_active | template | nuclei | True | medium | True | legacy_nuclei_template | nuclei_template | Explicit active Nuclei templates, scheduled after deterministic verifier quotas. |
nuclei_passive | template | nuclei | False | low | True | none | nuclei_template | Reviewed read-only Nuclei templates included in passive Scan presets. |
rce | active | server_side | True | high | False | none | planned_high_risk_attempt | Command/code execution checks. Planned and permission-gated. |
recon | recon | passive | False | low | True | legacy_discovery | discovery | Crawl, API/HAR/OpenAPI discovery, and passive surface refresh. |
sensitive_exposure | active | disclosure | True | high | False | exposure_probe_batch | active_endpoint_attempt_v1 | Deterministic probing for exposed secrets, VCS/env files, metrics, listings, and backups. |
sqli | active | injection | True | medium | True | legacy_active_loop | active_endpoint_attempt_v1 | SQL injection probes and proof/extraction depth. |
ssrf | active | server_side | True | high | False | none | planned_high_risk_attempt | Server-side request forgery checks. Planned and permission-gated. |
xss | active | client | True | medium | True | legacy_active_loop | active_endpoint_attempt_v1 | Reflected, stored, and DOM XSS probes. |
Command Arsenal
| Command | Family | Status | Risk | HTTP | Path | Description |
|---|---|---|---|---|---|---|
agent_context_pack.generate_from_target | governance | dry_run | read_only | POST | /arsenal/context-packs/from-target | Generate and persist a bounded AgentContextPack from stored target facts without executing work. |
agent_context_pack.list | governance | read_only | read_only | GET | /arsenal/context-packs | Read recent bounded AgentContextPack records. |
agent_context_pack.record | governance | dry_run | read_only | POST | /arsenal/context-packs | Validate and persist a bounded redacted AgentContextPack without executing work. |
agent_decision_trace.list | governance | read_only | read_only | GET | /arsenal/decision-traces | Read recent AgentDecisionTrace audit records. |
agent_decision_trace.record | governance | dry_run | read_only | POST | /arsenal/decision-traces | Validate and persist a dry-run AgentDecisionTrace without executing actions. |
ai_gate.replay_probe | ai_gate | gated | active | POST | /ai/scans/{scan_id}/replay | Queue focused AI Gate replay using original target/profile/probe context. |
ai_gate.scan | ai_gate | gated | active | POST | /ai/targets/{target_id}/scan | Queue an AI Gate scan for a saved AI target through the existing production and approval gates. |
ai_gate.target_history_export | ai_gate | read_only | read_only | GET | /ai/targets/{target_id}/campaign-history/export | Read a content-free AI Gate target campaign-history export with readiness trends, trend series, and report links. |
ai_target.list | ai_gate | read_only | read_only | GET | /ai/targets | List configured AI Gate targets and control metadata. |
approval.record | governance | gated | credential | POST | /arsenal/approvals | Persist an approval or denial receipt for an existing scope receipt without executing work. |
asm.activity | asm | read_only | read_only | GET | /targets/{target_id}/asm/activity | Read recent Continuous ASM recon/test activity and the target campaign timeline. |
asm.gaps | asm | read_only | read_only | GET | /targets/{target_id}/asm/gaps | Explain remaining Continuous ASM gaps and recommended campaigns for one target. |
asm.improve | asm | gated | active | POST | /targets/{target_id}/asm/improve | Queue or preview the next Continuous ASM action for one target. |
asm.recon | asm | gated | passive | POST | /targets/{target_id}/asm/recon | Queue an explicit Continuous ASM recon refresh for a target's persistent endpoint inventory. |
asm.test | asm | gated | active | POST | /targets/{target_id}/asm/test | Queue an async exploitation batch over untested/stale Continuous ASM inventory endpoints. |
authz.promote_replay_finding | authz | gated | credential | POST | /arsenal/campaign-actions/{campaign_action_id}/authz-promote | Promote a stored authz replay violation into a manual-source finding with replay evidence refs. Requires explicit authorization. |
authz.replay_plan | authz | gated | credential | POST | /arsenal/campaign-actions/{campaign_action_id}/authz-replay | Execute a stored deterministic authorization replay plan through an existing interactive session. Does not create findings automatically. |
campaign.create | governance | dry_run | read_only | POST | /arsenal/campaigns | Create a mission campaign record (the operating wrapper over ASM/scan/AI Gate/Model Intake/retest actions). Records only; queues no work and creates no findings. |
campaign.get | governance | read_only | read_only | GET | /arsenal/campaigns/{campaign_id} | Read one mission campaign plus its linked action-ledger rollup. |
campaign.link_action | governance | dry_run | read_only | POST | /arsenal/campaigns/{campaign_id}/actions | Link an existing command-result/action-ledger row to a mission campaign. Bookkeeping link only; changes no proof state and creates no findings. |
campaign.list | governance | read_only | read_only | GET | /arsenal/campaigns | Read recent mission campaign records. |
campaign_action.list | governance | read_only | read_only | GET | /arsenal/campaign-actions | Read recent campaign/action execution records derived from product actions and command results. |
command_result.list | governance | read_only | read_only | GET | /arsenal/command-results | Read recent Command Arsenal result/audit records for queued, partial, or blocked product actions. |
deployment.decision | governance | read_only | read_only | GET | /scans/{scan_id}/deployment-decision | Read deployment gate decision for a scan and policy profile. |
evidence.export_bundle | evidence | read_only | read_only | GET | /evidence/export-bundle | Read a content-free evidence export bundle descriptor or metadata zip with manifest hash, API replay paths, and retention/integrity summaries. |
evidence.export_manifest | evidence | read_only | read_only | GET | /evidence/export-manifest | Read a content-free evidence export manifest with hashes, storage URIs, retention classes, and integrity status. |
evidence.get | evidence | read_only | read_only | GET | /findings/{finding_id}/evidence | Read redacted durable evidence objects for a finding. |
evidence.retention_sweep | evidence | gated | dangerous | POST | /evidence/retention/sweep | Preview or execute target-scoped evidence-object retention cleanup. Preview is read-only and needs no approval. Gated execution requires dry_run=false, that exact preview ID, and a matching approval receipt. Scheduled deletion is not supported. |
evidence_instance.list | evidence | read_only | read_only | GET | /evidence/instances | Read concrete evidence instances split from canonical findings. |
evidence_instance.record | evidence | dry_run | read_only | POST | /evidence/instances | Record a concrete evidence instance without updating finding proof state. |
experiment.http_diff | research | gated | active | POST | /arsenal/execute | Run a bounded same-origin read-only HTTP differential and record unverified evidence. |
experiment.workflow | research | gated | credential | POST | /arsenal/execute | Run a bounded principal-bound HTTP/browser workflow and record unverified state-transition evidence. |
exposure.graph.get | inventory | read_only | read_only | GET | /exposure/graph | Read the exposure graph built from existing targets, scans, AI targets, model artifacts, and findings. |
finding.get | findings | read_only | read_only | GET | /findings/{finding_id} | Read one finding by id or fingerprint. |
finding.list | findings | read_only | read_only | GET | /findings | List findings with filters and proof-state fields. |
finding.retest | findings | gated | active | POST | /findings/{finding_id}/retest | Queue deterministic or AI-assisted retest for one finding through existing retest gates. |
finding_exception.lifecycle_sweep | policy | gated | active | POST | /finding-exceptions/lifecycle/sweep | Preview or execute a bounded one-way exception lifecycle sweep. Only effective exceptions whose expires_at is in the past are marked expired; the sweep never renews, revokes, or deletes exceptions. |
hypothesis.claim | governance | dry_run | read_only | POST | /arsenal/hypotheses/{hypothesis_id}/claim | Claim a hypothesis using compare-and-set leasing; does not queue scanner work. |
hypothesis.generate_from_benchmark | governance | dry_run | read_only | POST | /arsenal/hypotheses/from-benchmark | Record benchmark scorecard follow-up rows as hypotheses only; benchmark misses cannot create findings or satisfy proof. |
hypothesis.generate_from_graph | governance | dry_run | read_only | POST | /targets/{target_id}/graph/hypotheses | Generate app-graph authorization hypotheses from persisted producer/object/consumer facts without queueing tests. |
hypothesis.generate_from_plan | governance | dry_run | read_only | POST | /arsenal/hypotheses/from-plan | Record saved dry-run OperationPlan actions as planner-signal hypotheses only; planner output cannot execute work or satisfy proof. |
hypothesis.generate_from_source | governance | dry_run | read_only | POST | /arsenal/hypotheses/source-ingest | Record bounded source/spec/package hints as hypotheses only; source text cannot create findings or satisfy runtime proof. |
hypothesis.list | governance | read_only | read_only | GET | /arsenal/hypotheses | Read deduped claimable/refutable hypotheses that have not become findings. |
hypothesis.plan_campaign | governance | dry_run | read_only | POST | /arsenal/hypotheses/{hypothesis_id}/plan-campaign | Create or link a mission campaign and planned action from a hypothesis next_test_action without executing the action. |
hypothesis.reconcile_proof | governance | gated | active | POST | /arsenal/hypotheses/{hypothesis_id}/reconcile-proof | Reconcile one executed campaign action back to its hypothesis using only exact deterministic finding proof already persisted by ShakerScan. |
hypothesis.record | governance | dry_run | read_only | POST | /arsenal/hypotheses | Record or endorse a deduped hypothesis without creating a finding or queueing work. |
hypothesis.signal | governance | dry_run | read_only | POST | /arsenal/hypotheses/{hypothesis_id}/signals | Append an endorsement or refutation signal to a hypothesis without changing findings or gates. |
hypothesis.situation_report | governance | read_only | read_only | GET | /arsenal/hypotheses/situation-report | Read a bounded hypothesis situation report with hot unclaimed leads, owned claims, blockers, terminal leads, missing preconditions, and application-graph context. |
local_agent.list | planner | read_only | read_only | GET | /agents/local | Read local planner capability records without reading auth artifacts or executing prompts. |
local_agent.parse_plan | planner | dry_run | read_only | POST | /agents/local/plan/parse | Fail-closed validation for raw local-agent planner JSON before any candidate can become an OperationPlan. |
local_agent.plan_dry_run | planner | dry_run | read_only | POST | /agents/local/plan | Persist a local-agent-labeled dry-run OperationPlan from a saved AgentContextPack without spawning a local agent. |
local_agent.test | planner | dry_run | read_only | POST | /agents/local/test | Run a bounded harmless local-agent capability ping without sending prompts or enabling planner execution. |
mission.timeline | governance | read_only | read_only | GET | /timeline | Read the cross-product mission timeline: command results, campaign actions, recent scans, evidence bindings, export events, refuter reviews, and upcoming schedules. |
model_intake.evidence_export | model_intake | read_only | read_only | GET | /model-intake/scans/{scan_id}/evidence-export | Read a content-free Model Intake evidence export with trust, AIBOM, policy, and replay hashes. |
model_intake.scan | model_intake | gated | passive | POST | /model-intake/scan | Queue a Model Intake artifact check through existing policy and artifact-fetch gates. |
model_intake.trust_preview | model_intake | read_only | read_only | CLIENT | /model-intake | Preview Model Intake trust mode and policy readiness in the UI before queueing a scan. |
operation_plan.list | governance | read_only | read_only | GET | /arsenal/plans | Read recent dry-run OperationPlan records. |
operation_plan.preview | governance | dry_run | read_only | POST | /arsenal/plans | Validate and persist a dry-run OperationPlan without executing any action. |
refuter_review.derive_verdict | governance | gated | read_only | POST | /arsenal/refuter-reviews/{refuter_review_id}/derive-verdict | Record a refuter signal or deterministic proof-backed verdict from a completed finding verification row without changing product truth. |
refuter_review.execute_plan | governance | gated | active | POST | /arsenal/refuter-reviews/{refuter_review_id}/execute | Execute the next planned refuter automation step through existing gated retest/replay primitives. Does not directly change proof state or gates. |
refuter_review.list | governance | read_only | read_only | GET | /arsenal/refuter-reviews | Read durable refuter signals and proof-backed verdict records without changing findings. |
refuter_review.queue_from_summary | governance | dry_run | read_only | POST | /arsenal/refuter-reviews/queue-from-summary | Record signal-only refuter review work from the current weak-claim summary without mutating findings. |
refuter_review.record | governance | dry_run | read_only | POST | /arsenal/refuter-reviews | Record a refuter signal or evidence-backed verdict without directly changing findings, proof state, or gates. |
refuter_review.summary | governance | read_only | read_only | GET | /arsenal/refuter-reviews/summary | Read a bounded worklist of weak/high-impact findings that should be challenged, with non-executing deterministic automation plans. |
scan.focused_family | scans | gated | active | POST | /scans | Submit a focused DAST family campaign through existing scan submission gates. |
scan.result | scans | read_only | read_only | GET | /scans/{scan_id}/result | Read scan status and stored result JSON. |
scope.preview | governance | dry_run | read_only | POST | /arsenal/scope/preview | Validate and persist a fail-closed scope receipt preview without executing work. |
target.get | inventory | read_only | read_only | GET | /targets/{target_id} | Get one target and recent scan metadata. |
target.invariant.compile | authorization_policy | dry_run | read_only | POST | /targets/{target_id}/invariants/compile | Compile one short business/security rule into non-authoritative typed draft candidates. |
target.invariant.generate_hypotheses | authorization_policy | dry_run | read_only | POST | /targets/{target_id}/invariants/hypotheses | Convert approved typed invariants into deduplicated worklist leads without executing tests. |
target.invariant.verification_plan | authorization_policy | read_only | read_only | GET | /targets/{target_id}/invariants/{contract_id}/verification-plan | Read the deterministic proof family and missing runtime bindings for one target invariant. |
target.invariant_contract.approve | authorization_policy | gated | active | POST | /targets/{target_id}/invariants/{contract_id}/approve | Approve a validated typed invariant for planning, never direct finding promotion. |
target.invariant_contract.record | authorization_policy | gated | active | POST | /targets/{target_id}/invariants | Record a typed target invariant as a non-authoritative draft. |
target.invariant_contract.retire | authorization_policy | gated | active | POST | /targets/{target_id}/invariants/{contract_id}/retire | Retire a target invariant so it no longer guides autonomous planning. |
target.invariants | authorization_policy | read_only | read_only | GET | /targets/{target_id}/invariants | Read typed target invariants; only approved rows can guide autonomous planning. |
target.list | inventory | read_only | read_only | GET | /targets | List configured targets. |
target.principal_matrix | inventory | read_only | read_only | GET | /targets/{target_id}/principal-matrix | Read endpoint x principal/role expectations for authorization planning without queueing tests. |
target.principal_matrix.record | authorization_policy | gated | active | POST | /targets/{target_id}/principal-matrix | Record a non-executing endpoint principal expectation for future authz campaigns. |
target.principals | inventory | read_only | read_only | GET | /targets/{target_id}/principals | Read role/tenant principals configured for one web/API target. |
tool.status | tool_status | read_only | read_only | GET | /arsenal/tools | Read installed/runnable/waived/catalog status for integrated adapters. |
tool_receipt.list | evidence | read_only | read_only | GET | /arsenal/tool-receipts | Read durable receipts for existing tools/executors. |
tool_receipt.record | evidence | dry_run | read_only | POST | /arsenal/tool-receipts | Record an existing tool/executor receipt without running tools or creating findings. |
Tool And Local-Agent Adapters
| Tool | Family | Status | Risk | Parser | Proof contract | Description |
|---|
| Agent | Display | Headless prompt | Timeout | Workdir isolation | Max prompt bytes | Max output bytes |
|---|---|---|---|---|---|---|
claude-code | Claude Code | True | True | True | 120000 | 32000 |
codex | Codex | True | True | True | 120000 | 32000 |
hermes | Hermes | False | True | True | 64000 | 16000 |
opencode | OpenCode | True | True | True | 120000 | 32000 |
Internal Compatibility Scanner Flags
These parser flags inventory the private compatibility scanner surface. They are not the
public Scan contract, must not receive secrets directly from V2 clients, and cannot grant
execution authority. Public clients use GET /scan/contracts plus /scans policy, budget,
opaque profile, and collection-reference fields.
| Flag | Choices | Purpose |
|---|---|---|
--abuseipdb-key | - | AbuseIPDB API key for enhanced IP reputation (env: ABUSEIPDB_API_KEY) |
--active | - | Run active security checks (dalfox/sqlmap) on discovered/synthetic URLs |
--aggressive | - | Aggressive mode - maximum coverage with aggressive testing (2+ hours) |
--ai | - | Enable AI-assisted verification of findings (non-invasive) |
--ai-api-key | - | AI provider API key |
--ai-fallback-model | - | Comma-separated fallback AI model IDs |
--ai-mask-host | - | Replacement host sent to AI instead of the real target (default: example.com) |
--ai-url | - | AI provider URL (HTTP endpoint) |
--api-security-testing | - | Test for API security issues (mass assignment, BFLA) |
--api-token | - | Bearer token for API testing (Authorization header) |
--asn-discovery | - | Enable ASN/IP discovery (hosting provider, geographic distribution, multi-homing) |
--auth-config-file | - | - |
--auth-cookies | - | Session cookies for authenticated scanning (e.g., 'session=abc; token=xyz') |
--auth-header | - | Authorization header for authenticated scanning (e.g., 'Bearer token123') |
--auth-headers-json | - | Custom auth headers as JSON (e.g., '{"X-API-Key": "abc"}') |
--auth-scenario-json | - | Auth scenario DSL JSON (login flow, credentials, success condition) |
--auto-auth | - | Attempt API login with provided credentials (JSON/form endpoints) |
--avoid-rules-json | - | JSON array of avoid rules to exclude endpoint scope |
--backup-file-testing | - | Test for exposed backup files |
--baseline | - | Baseline file to filter known issues (suppress matching findings) |
--bola-testing | - | Test for BOLA/IDOR vulnerabilities (API1:2023, broken object-level authorization) |
--breach-check | - | Check for credential breaches and leaks (HIBP, GitHub) |
--budget-active-max-endpoints | - | - |
--budget-active-max-seconds | - | - |
--budget-active-params-per-endpoint | - | - |
--budget-active-worklist-max | - | - |
--budget-api-probe-limit | - | - |
--budget-browser-max-depth | - | - |
--budget-browser-max-pages | - | - |
--budget-disable-nuclei-early-stop | - | - |
--budget-discovery-depth | - | - |
--budget-max-duration-minutes | - | - |
--budget-max-findings-per-family | - | -1 disables the per-family active finding cap |
--budget-max-urls | - | - |
--budget-nuclei-max-targets | - | - |
--budget-param-discovery-max-params | - | - |
--budget-param-discovery-url-limit | - | - |
--budget-phase4-max-seconds | - | - |
--budget-profile | fast, balanced, thorough, exhaustive | Resource ceiling for the deterministic Scan pipeline; it does not select an engine or module set. |
--budget-request-max | - | - |
--business-logic-testing | - | Detect business logic vulnerability indicators |
--canonical-scan | - | - |
--check-family | - | Run a scanner-supported active check family: all, sqli, or xss |
--cicd-exposure | - | Test for exposed CI/CD configuration files |
--cloud-bucket-testing | - | Test for publicly accessible cloud storage buckets |
--cloud-ssrf | - | Test for SSRF vulnerabilities targeting cloud metadata |
--complete | - | Complete scan mode - broader passive plus selected active checks (30-60 min) |
--complete-tier | safe, full, aggressive | Scan tier for complete mode: safe (30-45min), full (2-3hr), aggressive (3+hr) |
--compliance-report | - | Generate compliance report (PCI DSS, SOC 2, HIPAA, GDPR, CIS) |
--create-baseline | - | Create baseline file from scan results (save known issues) |
--csrf-testing | - | Test for CSRF vulnerabilities |
--ct-monitoring | - | Enable certificate transparency monitoring (CA diversity, suspicious certs) |
--deep | - | Deep scan - thorough passive assessment (30-60 min, alias for --complete) |
--deep-discovery | - | Enable deep discovery with ffuf (complete mode) |
--deep-domxss | - | Enable dalfox deep DOM XSS (spawns headless browser; heavy) |
--default-creds-testing | - | Test for default credentials (safe mode) |
--deserialization-testing | - | Test for insecure deserialization (detection only) |
--discovery-manifest-only | - | Build a bounded Smart endpoint manifest without adaptive post-template refinement |
--dkim-enumeration | - | Enumerate DKIM selectors |
--dkim-selectors | - | Comma-separated DKIM selectors to check (e.g., default,google) |
--dom-xss-max-files | - | - |
--domain-intelligence | - | Enable domain intelligence (WHOIS, age, expiration, registrar reputation) |
--endpoints | - | Manual endpoint (e.g., 'GET /api/v1/users id,email' or '/api/login') |
--endpoints-file | - | File with manual endpoints (one per line, same format as --endpoints) |
--enhanced-dns | - | Enable enhanced DNS checks (DKIM, SPF validation, zone transfer) |
--exploit-level | safe, moderate, aggressive | Exploit level for active tests |
--exposure-client | - | Enable client-side exposure checks (JS Dependencies, JS Secrets) |
--exposure-infra | - | Enable infrastructure exposure checks (CI/CD, Packages, Cloud Buckets, Backups, SSH, SMTP, Network Services, K8s/Terraform/Registry) |
--fail-on-high | - | Fail quality gate on high severity findings (alias for --max-high 0) |
--file-upload-testing | - | Test for file upload vulnerabilities |
--focus-rules-json | - | JSON array of focus rules to constrain endpoint scope |
--focused-endpoints-only | - | - |
--forced-browsing | - | Test for forced browsing/direct request vulnerabilities (privileged path enumeration) |
--full | - | Broad full assessment including active XSS/SQLi (1-2 hours; bounded modules and budgets apply) |
--github-token | - | GitHub token for code search (env: GITHUB_TOKEN) |
--grpc-discovery | - | Enable gRPC reflection discovery (requires grpcurl) |
--health-check | - | Run tool health check and exit (validate all scanner tools are available) |
--hibp-api-key | - | HIBP API key for email breach lookups (env: HIBP_API_KEY) |
--host-header-testing | - | Test for host header injection |
--idor-testing | - | Test for IDOR/BOLA vulnerabilities |
--include-partial-attack-chains | - | Include partial attack chains in report (analyst mode) |
--ip-reputation | - | Check IP reputation against DNS blacklists and threat intelligence |
--js-dependency-scanning | - | Scan for vulnerable JavaScript dependencies (Retire.js methodology) |
--js-secret-scanning | - | Scan for hardcoded secrets in JavaScript files |
--json-link-following | - | Follow JSON/HATEOAS links to expand API endpoints |
--kubernetes-exposure | - | Test for exposed Kubernetes API servers |
--login-extra-fields | - | Extra form fields as JSON (e.g., '{"remember_me": "1"}') |
--login-password | - | Password for form-based login |
--login-url | - | Login page URL for form-based authentication (auto-detected if not provided) |
--login-username | - | Username for form-based login |
--mass-assignment-testing | - | Test for mass assignment vulnerabilities (CWE-915, privilege escalation via parameters) |
--max-active | - | Max URLs for active checks (default 10) |
--max-critical | - | Max critical findings before quality gate fails (default: 0) |
--max-high | - | Max high findings before quality gate fails (default: 0) |
--max-medium | - | Max medium findings before quality gate fails (-1 = unlimited) |
--max-ports | - | Max ports to scan in complete mode (default 1000) |
--max-typo-checks | - | Maximum typosquatting permutations to check (default: 100) |
--model | - | AI model identifier (provider specific) |
--network-discovery | - | Permit bounded target-host port and network-service discovery |
--network-services | - | Enable network services detection (VPN, RDP, VNC, IoT, Industrial, databases) |
--no-browser | - | Disable browser-based scanning, use curl only (faster but less data) |
--no-early-stop | - | Internal pre-V2 compatibility control for detector execution |
--no-verified-findings-only | - | Keep all findings regardless of verification status |
--nuclei | - | Nuclei scan mode - vulnerability scan with the configured template set (10-30 min) |
--oauth-client-id | - | OAuth 2.0 client ID |
--oauth-client-secret | - | OAuth 2.0 client secret |
--oauth-password | - | Password for OAuth password grant flow |
--oauth-scope | - | OAuth scopes (space-separated) |
--oauth-token-url | - | OAuth token endpoint URL (auto-discovered via OIDC if not provided) |
--oauth-username | - | Username for OAuth password grant flow |
--oob-callback-url | - | Out-of-band callback URL for blind SQLi verification (e.g., Burp Collaborator) |
--oob-max-findings | - | - |
--oob-max-payloads | - | - |
--open-redirect-testing | - | Test for open redirect vulnerabilities |
--openapi | - | OpenAPI/Swagger schema URL to test with Schemathesis |
--options-method-discovery | - | Use HTTP OPTIONS to enumerate allowed methods |
--package-exposure | - | Test for exposed package manager files |
--password-reset-testing | - | Test for password reset vulnerabilities |
--path-traversal-testing | - | Test for path traversal vulnerabilities |
--port | - | Server port |
--pretty | - | Pretty-print JSON |
--public | - | Public data collection only (no active scans) |
--quality-gate | - | Enable quality gate (exit code 1 if critical/high findings) |
--quick | - | Quick scan mode - faster but less thorough (affects active checks) |
--rate-limiting-testing | - | Test for missing rate limiting |
--registry-exposure | - | Test for exposed container registries |
--sarif | - | Output SARIF file for CI/CD integration (e.g., results.sarif) |
--server | - | Run FastAPI server |
--session-mgmt-testing | - | Test for session management issues |
--show-suppressed | - | Include suppressed findings in output (marked with suppressed=true) |
--skip-global-checks | - | Skip duplicate global exposure/posture checks in a parallel child shard |
--smart | - | Internal pre-V2 compatibility flag; canonical clients use one Scan contract |
--smart-bola-max-endpoints | - | - |
--smtp-security | - | Enable SMTP security testing (STARTTLS, open relay, banner analysis) |
--sqli | - | Run only SQLi active checks (implies --active) |
--sqli-extract-max | - | - |
--ssh-port | - | SSH port to scan (default 22) |
--ssh-testing | - | Test SSH configuration (password auth detection) |
--standard | - | Standard scan - balanced passive coverage (5-10 min) |
--subdomain-quick | - | Quick subdomain scan using Gungnir only (faster) |
--subdomain-sources | - | Comma-separated subdomain sources: gungnir,subfinder,crtsh (default: all) |
--subfinder | - | Subdomain discovery mode - comprehensive CT log and passive enumeration |
--terraform-exposure | - | Test for exposed Terraform state files |
--thorough-params | - | Test more parameters (100 endpoints x 10 params vs default 50x5) |
--threat-intel | - | Enable threat intelligence checks (IP Reputation, Breach Check, Vendor Risk, Typosquatting, Domain Intel, CT Monitoring, ASN Discovery, Enhanced DNS) |
--twofa-bypass-testing | - | Test for 2FA bypass vulnerabilities |
--typosquatting | - | Detect typosquatting/lookalike domains |
--user2-cookies | - | Session cookies for second user (BOLA comparison) |
--user2-header | - | Authorization header for second user (BOLA comparison) |
--user2-login-password | - | Password for second user form login |
--user2-login-username | - | Username for second user form login |
--vendor-risk | - | Assess third-party/vendor supply chain risk (CDN, analytics, dependencies) |
--verified-findings-only | - | Only keep findings with exploit verification evidence |
--virustotal-key | - | VirusTotal API key for enhanced IP reputation (env: VIRUSTOTAL_API_KEY) |
--vuln-auth | - | Enable all auth/access checks (CSRF, IDOR, Rate Limiting, 2FA, Password Reset, Session, Default Creds) |
--vuln-injection | - | Enable all injection checks (Path Traversal, Deserialization) |
--vuln-web | - | Enable all web app checks (File Upload, Open Redirect, Host Header, Business Logic, API Security, Forced Browsing, Cloud SSRF) |
--websocket-testing | - | Test WebSocket endpoints for CSWSH, auth bypass, and other vulnerabilities |
--xss | - | Run only XSS active checks (implies --active) |
--zero-rediscovery | - | - |
--zone-transfer-test | - | Test for DNS zone transfer (AXFR) vulnerability |
Wrapper Commands, Make Targets, And Release Gates
| Surface | Names |
|---|---|
Canonical scanner.sh commands | agent, ai, api, backup, build, collections, credentials, devices, doctor, env, evidence, fleet, gungnir, help, hunt, install-deps, join, logs, mcp, model-intake-runner, rebuild, reload, report-rebuild, research, reset, restart, scale, scan, shell, start, status, stop |
| Make targets | dependency-audit, dependency-lock, e2e, e2e-ai-gate, e2e-api-overlay, e2e-dast, e2e-hunt, e2e-model-intake, e2e-model-intake-fixture, e2e-platform, e2e-scan-parity, e2e-wire, fleet-acceptance, installed-stack-smoke, installer-smoke, installer-upgrade-smoke, release-gates, test, upgrade-smoke |
| Release gates | test:evidence-provenance, test:fleet-current, test:hypothesis-proof-promotion, test:mcp-read-only, test:no-ai-verified, test:no-benchmark-fitting, test:no-phantom-tools, test:planner-no-shell, test:planner-risk, test:planner-scope, test:scanner-auth-quality, test:scanner-bounds, test:scanner-proof-truth, test:scanner-registry-coverage, test:v2-detection-parity, test:v2-fault-injection, test:v2-security-invariants |
Runtime Environment-Key Inventory
Only key names and declaring sources are documented; secret values are never read or emitted.
| Environment key | Referenced by |
|---|---|
ABUSEIPDB_API_KEY | scanner/scanner.py |
AGENT_TOOL_ONLY_WORKER | api/worker.py |
AGENT_TOOL_QUEUE_NAME | api/api.py, api/worker.py, docker-compose.release.yml, docker-compose.yml |
AI_API_KEY | api/ai_gate_scan.py, api/api.py, api/worker.py, docker-compose.release.yml, docker-compose.yml, scanner/scanner.py |
AI_CLASSIFY_CHAIN_BUDGET_SECONDS | docker-compose.release.yml, docker-compose.yml, scanner/scanner_tools/ai_classifier.py |
AI_CLASSIFY_CIRCUIT_COOLDOWN_SECONDS | docker-compose.release.yml, docker-compose.yml, scanner/scanner_tools/ai_classifier.py |
AI_CLASSIFY_CIRCUIT_ERROR_THRESHOLD | docker-compose.release.yml, docker-compose.yml, scanner/scanner_tools/ai_classifier.py |
AI_CLASSIFY_CIRCUIT_WINDOW_SECONDS | docker-compose.release.yml, docker-compose.yml, scanner/scanner_tools/ai_classifier.py |
AI_CLASSIFY_MAX_FINDINGS_PER_BATCH | scanner/scanner_tools/ai_classifier.py |
AI_CLASSIFY_MAX_PROMPT_CHARS | scanner/scanner_tools/ai_classifier.py |
AI_CLASSIFY_MIN_SEVERITY | api/api.py, api/worker.py, docker-compose.release.yml, docker-compose.yml, scanner/scanner.py |
AI_CREDENTIAL_ENC_KEY | api/secret_store.py |
AI_CREDENTIAL_ENC_KEY_FILE | api/secret_store.py |
AI_DEMO_HONEY_PUBLIC_URL | api/api.py, docker-compose.release.yml, docker-compose.yml |
AI_DEMO_HONEY_SCANNER_URL | api/api.py, docker-compose.release.yml, docker-compose.yml |
AI_DEMO_MODE_ENABLED | api/api.py, docker-compose.release.yml, docker-compose.yml |
AI_ESCALATION_MIN_SEVERITY | api/api.py, api/retest_contract.py, api/worker.py |
AI_FALLBACK_MODEL | api/api.py, api/worker.py, docker-compose.release.yml, docker-compose.yml, scanner/scanner.py |
AI_GATE_TRANSCRIPT_RETENTION_DAYS | api/ai_gate_scan.py |
AI_GATE_TRUSTED_RECEIPT_KEYS | api/ai_gate_scan.py |
AI_GATE_TRUSTED_RECEIPT_KEY_SHA256 | api/ai_gate_scan.py |
AI_JUDGE_MODEL | api/ai_gate_scan.py |
AI_MASK_HOST | api/api.py, api/worker.py, docker-compose.release.yml, docker-compose.yml |
AI_MODEL | api/ai_gate_scan.py, api/api.py, api/worker.py, docker-compose.release.yml, docker-compose.yml, scanner/scanner.py |
AI_OPS_ROUTER_EXECUTE_ENABLED | api/api.py, docker-compose.release.yml, docker-compose.yml |
AI_REASONING_RETRY_MAX_TOKENS | scanner/scanner_tools/ai_classifier.py |
AI_SCAN_CLASSIFICATION_ENABLED | api/api.py, api/worker.py, docker-compose.release.yml, docker-compose.yml, scanner/scanner.py |
AI_SETTINGS_KEY | api/settings_routes/router.py, api/worker.py |
AI_TRANSCRIPT_ALLOW_SENSITIVE | api/ai_targets/router.py |
AI_URL | api/ai_gate_scan.py, api/api.py, api/worker.py, docker-compose.release.yml, docker-compose.yml, scanner/scanner.py |
AI_VERIFY_ENABLED | api/api.py, api/worker.py, docker-compose.release.yml, docker-compose.yml |
AI_VERIFY_MAX_PER_SCAN | api/worker.py |
AI_VERIFY_MIN_SEVERITY | api/api.py, api/retest_contract.py, api/worker.py, docker-compose.release.yml, docker-compose.yml, scanner/scanner.py |
AI_VERIFY_USE_BROWSER | api/worker.py |
API_IMAGE | docker-compose.release.yml |
APPROVAL_RECEIPTS_REQUIRED_FOR_STATE_CHANGING_ACTIONS | api/api.py |
ARTIFACT_CHECKPOINT_INTERVAL_SECONDS | api/worker.py |
ARTIFACT_REFERENCED_FILE_MAX_BYTES | api/worker.py |
ARTIFACT_REFERENCED_FILE_MAX_COUNT | api/worker.py |
ARTIFACT_RETENTION_ATTACHMENT_DAYS | docker-compose.release.yml, docker-compose.yml |
ARTIFACT_RETENTION_CHECKPOINT_DAYS | docker-compose.release.yml, docker-compose.yml |
ARTIFACT_RETENTION_DAYS | api/artifact_storage.py, docker-compose.release.yml, docker-compose.yml |
ARTIFACT_RETENTION_DIAGNOSTIC_DAYS | docker-compose.release.yml, docker-compose.yml |
ARTIFACT_RETENTION_RESULT_DAYS | docker-compose.release.yml, docker-compose.yml |
ARTIFACT_RETENTION_SCREENSHOT_DAYS | docker-compose.release.yml, docker-compose.yml |
ARTIFACT_RETENTION_SWEEP_SECONDS | docker-compose.release.yml, docker-compose.yml |
ARTIFACT_S3_PREFIX | docker-compose.release.yml, docker-compose.yml |
ARTIFACT_STORAGE_BACKEND | api/artifact_storage.py, docker-compose.release.yml, docker-compose.yml |
ARTIFACT_STORAGE_REQUIRED | api/artifact_storage.py, api/broker_worker.py, docker-compose.release.yml, docker-compose.yml |
ASM_DEFAULT_DOMAIN_RATE_PER_HOUR | api/asm_inventory.py, docker-compose.yml |
ASM_DEFAULT_ENABLED | api/api.py |
ASM_GONE_RETENTION_DAYS | api/asm_inventory.py |
ASM_GONE_STREAK_THRESHOLD | api/asm_inventory.py |
ASM_REACHABILITY_SWEEP | api/asm_inventory.py |
ASM_SCAN_SWEEP_MAX | api/worker.py |
ASM_SCHEDULE_RETRY_MINUTES | api/api.py |
ASM_SOFT404_DETECT | api/asm_inventory.py |
ASM_SOFT404_SIZE_TOL_BYTES | api/asm_inventory.py |
ASM_VALIDATE_REACHABILITY | api/asm_inventory.py |
AUTOMATION_SETTINGS_KEY | api/settings_routes/router.py |
AUTO_FP_MIN_CONFIDENCE | api/api.py, api/retest_contract.py, api/worker.py |
AUTO_FP_ON_RETEST | api/api.py, api/retest_contract.py, api/worker.py |
AUTO_RETEST_MAX_ATTEMPTS | api/targets/router.py, api/worker.py |
AUTO_RETEST_MAX_PER_SCAN | api/api.py, api/retest_contract.py, api/worker.py, docker-compose.release.yml, docker-compose.yml |
AUTO_RETEST_MIN_SEVERITY | api/api.py, api/retest_contract.py, api/worker.py, docker-compose.release.yml, docker-compose.yml |
AUTO_RETEST_ON_SCAN_COMPLETE | api/api.py, api/retest_contract.py, docker-compose.release.yml, docker-compose.yml |
AUTO_SHARDING_ENABLED | api/settings_routes/router.py |
AUTO_SHARDING_MAX_SHARDS | api/settings_routes/router.py |
AUTO_SHARDING_MIN_WORKERS | api/settings_routes/router.py |
AUTO_SHARDING_STRATEGY | api/settings_routes/router.py |
AWS_ACCESS_KEY_ID | api/evidence_storage.py |
AWS_ENDPOINT_URL_S3 | api/evidence_storage.py |
AWS_REGION | api/evidence_storage.py |
AWS_SECRET_ACCESS_KEY | api/evidence_storage.py |
AWS_SESSION_TOKEN | api/evidence_storage.py |
BROKER_INGEST_QUEUE_NAME | api/fleet_routes/router.py, api/worker.py |
BUDGET_RESERVATION_SWEEP_BATCH_SIZE | api/worker.py |
BUDGET_RESERVATION_SWEEP_INTERVAL_SECONDS | api/worker.py |
BUILD_FINGERPRINT | api/worker.py |
COMPOSE_PROJECT_NAME | api/api.py, scripts/fleet_cli.py |
COVERAGE_ALLOCATION_DEFAULT | api/parallel_scan.py |
DATABASE_URL | api/api.py, api/gungnir_worker.py, api/model_intake_signer_service.py, api/operations/router.py, api/worker.py, scanner/gungnir_worker.py, scripts/model_intake_workflow_smoke.py, scripts/upgrade_schema_smoke.py |
DEFAULT_ASM_ENABLED | api/api.py |
DEFAULT_RESEARCH_PLANNER_MODE | api/api.py |
DEVICE_INTEL_DB_PATH | api/device_agent.py, api/devices/router.py, api/exposure/service_intel.py, api/worker.py |
DEVICE_INTEL_DB_SHA256 | api/device_agent.py, api/devices/router.py, api/exposure/service_intel.py, api/worker.py |
DEVICE_ONLY_WORKER | api/worker.py |
DEVICE_POSTURE_ENABLED | api/devices/router.py, api/worker_handlers/device.py, docker-compose.release.yml, docker-compose.yml |
DEVICE_QUEUE_NAME | api/api.py, api/devices/router.py, api/operations/router.py, api/worker.py, docker-compose.release.yml, docker-compose.yml |
DEVICE_SCAN_WORKER_ENABLED | api/worker.py |
DEVICE_SSH_AUTH_COOLDOWN_SECONDS | api/worker.py |
DEVICE_SSH_AUTH_DAILY_FAILURE_CAP | api/worker.py |
DOCKERHUB_TOKEN | scripts/cleanup_candidate_tags.py |
DOCKERHUB_USERNAME | scripts/cleanup_candidate_tags.py |
DOMAIN_RATE_REQUEUE_DELAY_SECONDS | api/worker.py |
ENV | scanner/scanner_tools/remediation_kb.py |
EVIDENCE_INLINE_MAX_BYTES | api/evidence_storage.py |
EVIDENCE_RETENTION_PREVIEW_TTL_SECONDS | api/evidence_routes/router.py |
EVIDENCE_S3_ACCESS_KEY_ID | docker-compose.release.yml, docker-compose.yml |
EVIDENCE_S3_BUCKET | docker-compose.release.yml, docker-compose.yml |
EVIDENCE_S3_ENDPOINT_URL | docker-compose.release.yml, docker-compose.yml |
EVIDENCE_S3_FORCE_PATH_STYLE | docker-compose.release.yml, docker-compose.yml |
EVIDENCE_S3_REGION | docker-compose.release.yml, docker-compose.yml |
EVIDENCE_S3_SECRET_ACCESS_KEY | docker-compose.release.yml, docker-compose.yml |
EVIDENCE_S3_SESSION_TOKEN | docker-compose.release.yml, docker-compose.yml |
EVIDENCE_S3_TIMEOUT_SECONDS | api/evidence_storage.py |
EVIDENCE_STORAGE_BACKEND | api/artifact_storage.py, api/evidence_storage.py, docker-compose.release.yml, docker-compose.yml |
FINALIZATION_HEARTBEAT_TIMEOUT_MINUTES | api/api.py |
FLEET_AGENT_INTERVAL_SECONDS | api/fleet_agent.py, docker-compose.broker-worker.yml, docker-compose.worker.yml |
FLEET_ALLOW_INSECURE_ENROLLMENT | api/fleet_routes/router.py, docker-compose.release.yml, docker-compose.yml |
FLEET_BROKER_STATE_PATH | api/broker_worker.py |
FLEET_CA_CERT_PATH | api/fleet_routes/router.py |
FLEET_COMPOSE_PROJECT_NAME | docker-compose.broker-worker.yml, docker-compose.worker.yml |
FLEET_CONNECTION_BUNDLE_JSON | api/fleet_routes/router.py, docker-compose.release.yml, docker-compose.yml |
FLEET_CONNECTION_BUNDLE_PATH | api/fleet_routes/router.py, docker-compose.release.yml, docker-compose.yml |
FLEET_CONTROL_PLANE_OVERLAY_URL | api/fleet_routes/router.py, docker-compose.release.yml, docker-compose.yml |
FLEET_DESIRED_WORKER_COUNT | docker-compose.release.yml, docker-compose.yml |
FLEET_DRAIN_GRACE_SECONDS | api/fleet_agent.py |
FLEET_EDGE_MODE | api/api.py |
FLEET_EXPECTED_WORKER_IMAGE_DIGEST | docker-compose.broker-worker.yml, docker-compose.worker.yml |
FLEET_GATEWAY_BIND_HOST | docker-compose.release.yml, docker-compose.yml |
FLEET_GATEWAY_PROXY_SECRET | api/fleet_routes/router.py, docker-compose.release.yml, docker-compose.yml |
FLEET_HEARTBEAT_TIMEOUT_MINUTES | api/fleet_routes/router.py, api/operations/router.py |
FLEET_HEARTBEAT_TIMEOUT_SECONDS | api/worker.py, docker-compose.release.yml, docker-compose.yml |
FLEET_JOIN_RATE_LIMIT_PER_MINUTE | api/fleet_routes/router.py, docker-compose.release.yml, docker-compose.yml |
FLEET_NETWORK_BACKEND | scripts/fleet_cli.py |
FLEET_NODE_ID | api/worker.py, docker-compose.broker-worker.yml, docker-compose.worker.yml |
FLEET_OPERATOR_TOKEN | api/api.py, api/operator_auth.py, docker-compose.release.yml, docker-compose.yml, scripts/fleet_acceptance.py |
FLEET_OVERLAY_CIDR | api/fleet_routes/router.py, docker-compose.release.yml, docker-compose.yml |
FLEET_RECONCILE_MODE | api/fleet_routes/router.py, docker-compose.release.yml, docker-compose.yml |
FLEET_RESULTS_DIR | docker-compose.broker-worker.yml, docker-compose.worker.yml |
FLEET_RUNTIME_DIR | docker-compose.broker-worker.yml, docker-compose.worker.yml |
FLEET_STATE_PATH | api/fleet_agent.py |
FLEET_TLS_PORT | docker-compose.release.yml, docker-compose.yml |
FLEET_WIREGUARD_ENDPOINT | api/fleet_routes/router.py, docker-compose.release.yml, docker-compose.yml |
FLEET_WIREGUARD_PUBLIC_KEY | api/fleet_routes/router.py, docker-compose.release.yml, docker-compose.yml |
FLEET_WORKER_CPU_LIMIT | docker-compose.broker-worker.yml, docker-compose.worker.yml |
FLEET_WORKER_ENV_FILE | docker-compose.worker.yml |
FLEET_WORKER_IMAGE | docker-compose.broker-worker.yml, docker-compose.worker.yml |
FLEET_WORKER_IMAGE_DIGEST | api/api.py, api/fleet_routes/router.py, api/fleet_worker_entrypoint.py, api/worker.py, docker-compose.release.yml, docker-compose.yml |
FLEET_WORKER_MEMORY_LIMIT | docker-compose.broker-worker.yml, docker-compose.worker.yml |
FULL_COVERAGE_ALLOCATION_DEFAULT | api/parallel_scan.py |
GITHUB_REPOSITORY | scripts/apply_main_ruleset.py |
GITHUB_TOKEN | scanner/scanner.py |
GIT_COMMIT | api/api.py, api/model_intake/router.py, docker-compose.release.yml, docker-compose.yml, scanner/release_identity.py |
HEARTBEAT_INTERVAL_SECONDS | api/worker.py |
HF_TOKEN | scanner/scanner_tools/model_intake.py |
HIBP_API_KEY | scanner/scanner.py |
HOSTNAME | api/api.py, api/broker_worker.py, api/hunt/interaction_router.py, api/worker.py |
HOST_RESULTS_PATH | api/api.py |
HTTP_ARCHIVE_MAX_BODY_BYTES | api/runtime/http_archive.py |
HTTP_ARCHIVE_MAX_CAPTURED_CALLS | scanner/scanner_tools/http_archive_capture.py |
HTTP_ARCHIVE_MAX_CAPTURE_BYTES | scanner/scanner_tools/http_archive_capture.py |
LOCAL_ENV_FILE | api/settings_routes/router.py |
MINIO_BUCKET | docker-compose.release.yml, docker-compose.yml |
MINIO_PORT | docker-compose.release.yml, docker-compose.yml |
MINIO_ROOT_PASSWORD | docker-compose.release.yml, docker-compose.yml |
MINIO_ROOT_USER | docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_ADMISSION_BUILDER_ID | api/model_intake_signer_service.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_ADMISSION_POLICY_PROFILE | api/model_intake/router.py |
MODEL_INTAKE_ADMISSION_SIGNING_KEY_PEM | scanner/scanner_tools/model_intake_admission.py |
MODEL_INTAKE_ADMISSION_TRUSTED_PUBLIC_KEYS | docker-compose.release.yml, docker-compose.yml, scanner/scanner_tools/model_intake_admission.py |
MODEL_INTAKE_ADMISSION_V2_TRUSTED_BUILDERS | api/model_intake/router.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_ADMISSION_V2_TRUSTED_PUBLIC_KEYS | api/model_intake/router.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_ALLOWED_HOSTS | scanner/scanner_tools/model_intake_acquisition.py |
MODEL_INTAKE_ALLOWED_PORTS | scanner/scanner_tools/model_intake_acquisition.py |
MODEL_INTAKE_ALLOW_INSECURE_HTTP | scanner/scanner_tools/model_intake_acquisition.py |
MODEL_INTAKE_ALLOW_LEGACY_V1_VERIFICATION | api/model_intake/router.py |
MODEL_INTAKE_ALLOW_LOCAL_FILES | scanner/scanner_tools/model_intake.py |
MODEL_INTAKE_ALLOW_PRIVATE_NETWORKS | scanner/scanner_tools/model_intake_acquisition.py |
MODEL_INTAKE_AUTO_MAX_MEMORY_MIB | api/api.py |
MODEL_INTAKE_CONTROL_PLANE_SIGNING_KEY_PEM | api/model_intake_signer_service.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_DEPLOYMENT_VERIFIER_TOKEN | api/model_intake_admission_webhook.py |
MODEL_INTAKE_IMAGE | docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_LOCAL_SESSION_SECRET | api/model_intake/router.py, api/operator_auth.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_OCI_REGISTRY_REPOSITORY | scripts/model_intake_push_oci.py |
MODEL_INTAKE_ONLY_WORKER | api/worker.py |
MODEL_INTAKE_OPERATOR_CREDENTIALS_JSON | api/operator_auth.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_OPERATOR_ROLES | api/operator_auth.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_OPERATOR_TOKEN | api/operator_auth.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_POLICY_BUNDLE_SHA256 | api/model_intake/router.py |
MODEL_INTAKE_QUARANTINE_DIR | api/model_intake/router.py, scanner/scanner_tools/model_intake.py |
MODEL_INTAKE_QUEUE_NAME | api/model_intake/router.py, api/worker.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_RUNNER_AUTO_CLEANUP | api/model_intake_runner_service.py |
MODEL_INTAKE_RUNNER_HOST_RESULTS_ROOT | api/model_intake/router.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_RUNNER_INTERNAL_TOKEN | api/model_intake/router.py, api/model_intake_runner_service.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_RUNNER_JOB_ROOT | api/model_intake_runner_service.py |
MODEL_INTAKE_RUNNER_MAX_INPUT_BYTES | api/model_intake/router.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_RUNNER_MAX_OUTPUT_BYTES | docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_RUNNER_QUEUE_LIMIT | api/model_intake_runner_service.py |
MODEL_INTAKE_RUNNER_STAGE_DIR | api/model_intake/router.py |
MODEL_INTAKE_RUNNER_URL | api/model_intake/router.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_SANDBOX_GID | docker-compose.release.yml, docker-compose.yml, scanner/scanner_tools/model_intake_acquisition.py |
MODEL_INTAKE_SANDBOX_IMAGE | docker-compose.yml |
MODEL_INTAKE_SANDBOX_NETWORK_MODE | scanner/scanner_tools/model_intake_sandbox.py |
MODEL_INTAKE_SANDBOX_NO_NEW_PRIVILEGES | scanner/scanner_tools/model_intake_sandbox.py |
MODEL_INTAKE_SANDBOX_QUEUE_DIR | scanner/scanner_tools/model_intake.py, scanner/scanner_tools/model_intake_providers.py |
MODEL_INTAKE_SANDBOX_READ_ONLY | scanner/scanner_tools/model_intake_sandbox.py |
MODEL_INTAKE_SANDBOX_RUNTIME_ADAPTERS_JSON | docker-compose.release.yml, docker-compose.yml, scanner/scanner_tools/model_intake_providers.py, scanner/scanner_tools/model_intake_sandbox.py |
MODEL_INTAKE_SANDBOX_RUNTIME_TIMEOUT_SECONDS | docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_SANDBOX_UID | docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_SIGNER_ALLOW_LOCAL_PEM | api/model_intake_signer_service.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_SIGNER_AWS_KMS_KEY_ID | api/model_intake_signer_service.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_SIGNER_AWS_REGION | api/model_intake_signer_service.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_SIGNER_BACKEND | api/model_intake_signer_service.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_SIGNER_DATABASE_PASSWORD | docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_SIGNER_INTERNAL_TOKEN | api/model_intake/router.py, api/model_intake_signer_service.py, docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_SIGNER_POSTGRES_IMAGE | docker-compose.release.yml, docker-compose.yml |
MODEL_INTAKE_SIGNER_URL | api/model_intake/router.py |
MODEL_INTAKE_TRUSTED_KEY_SHA256 | scanner/scanner_tools/model_intake.py |
MODEL_INTAKE_TRUSTED_SIGNING_KEYS | scanner/scanner_tools/model_intake.py |
NUCLEI_TEMPLATES | scanner/scanner_tools/nuclei.py |
PARALLEL_SHARD_CONCURRENCY_HARD_MAX | api/worker.py |
PARALLEL_SHARD_MAX_PER_PARENT | api/worker.py |
PARALLEL_SHARD_REQUEUE_DELAY_SECONDS | api/worker.py |
PARALLEL_SHARD_SLOT_TTL_SECONDS | api/worker.py |
PARENT_STALE_TIMEOUT_MINUTES | api/api.py |
PATH | scanner/scanner_tools/model_intake_scanners.py |
PLAYWRIGHT_BROWSERS_PATH | api/ai_gate/targets/widget_playwright.py, scanner/scanner_tools/form_login.py, scanner/scanner_tools/http_scanner.py |
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD | scanner/scanner_tools/form_login.py, scanner/scanner_tools/http_scanner.py |
POSTGRES_IMAGE | docker-compose.release.yml, docker-compose.yml |
POSTGRES_PASSWORD | docker-compose.release.yml, docker-compose.yml |
POSTGRES_PORT | docker-compose.release.yml, docker-compose.yml |
PROOF_REQUIRED_FOR_SMART | api/api.py, api/retest_contract.py, api/worker.py, scanner/scanner.py |
REDIS_IMAGE | docker-compose.release.yml, docker-compose.yml |
REDIS_PASSWORD | docker-compose.release.yml, docker-compose.yml |
REDIS_PORT | docker-compose.release.yml, docker-compose.yml |
REDIS_URL | api/api.py, api/gungnir_worker.py, api/operations/router.py, api/worker.py, scanner/gungnir_worker.py |
RESEARCH_EPISODE_ABANDON_TTL_HOURS | api/api.py |
RESULTS_DIR | api/api.py, api/runtime/http_archive_router.py, api/secret_store.py, api/worker.py |
RETEST_AI_BUDGET_SECONDS | api/worker.py, docker-compose.release.yml, docker-compose.yml |
RETEST_AI_CIRCUIT_COOLDOWN_SECONDS | api/worker.py, docker-compose.release.yml, docker-compose.yml |
RETEST_AI_CIRCUIT_ERROR_THRESHOLD | api/worker.py, docker-compose.release.yml, docker-compose.yml |
RETEST_AI_CIRCUIT_KEY | api/worker.py |
RETEST_AI_CIRCUIT_WINDOW_SECONDS | api/worker.py, docker-compose.release.yml, docker-compose.yml |
RETEST_INCONCLUSIVE_MAX_REQUEUE | api/worker.py |
RETEST_INCONCLUSIVE_RETRY_AFTER_HOURS | api/worker.py |
RETEST_MAX_PARALLEL | api/worker.py |
RETEST_QUEUE_MAX_RETRIES | api/worker.py |
RETEST_QUEUE_NAME | api/api.py, api/finding_routes/router.py, api/operations/router.py, api/worker.py |
RETEST_REQUEUE_DELAY_SECONDS | api/worker.py |
RETEST_RUNNING_STALE_SECONDS | api/worker.py, docker-compose.release.yml, docker-compose.yml |
RETEST_RUNNING_TIMEOUT_MINUTES | api/operations/router.py |
RETEST_SLOT_KEY | api/worker.py |
RETEST_SLOT_TTL_SECONDS | api/worker.py |
RETEST_SLOT_WAIT_MAX_SECONDS | api/worker.py |
RETEST_STALE_BATCH_SIZE | api/worker.py, docker-compose.release.yml, docker-compose.yml |
RETEST_STALE_CHECK_INTERVAL_SECONDS | api/worker.py, docker-compose.release.yml, docker-compose.yml |
RETEST_STALE_REQUEUE_LIMIT | api/worker.py, docker-compose.release.yml, docker-compose.yml |
RETEST_WATCHDOG_LOCK_KEY | api/worker.py |
RETEST_WATCHDOG_LOCK_SECONDS | api/worker.py |
SCANNER_DALFOX_DEEP_DOMXSS | scanner/scanner_tools/active_checks.py |
SCANNER_DEBUG_ENDPOINTS | scanner/scanner.py |
SCANNER_DEBUG_NOSQL | scanner/scanner.py, scanner/scanner_tools/active_checks.py |
SCANNER_DEBUG_SQLMAP | scanner/scanner.py |
SCANNER_DNS_RESOLVERS | scanner/scanner.py |
SCANNER_EXPECTED_REVISION | scanner/release_identity.py |
SCANNER_EXPECTED_VERSION | scanner/release_identity.py |
SCANNER_IMAGE | docker-compose.release.yml |
SCANNER_LOCAL_WORKER_IMAGE | docker-compose.yml |
SCANNER_MAX_CONCURRENT | scanner/scanner_tools/common.py |
SCANNER_RELEASE_VERSION | docker-compose.release.yml |
SCANNER_SUBPROCESS_ARTIFACT_MAX_BYTES | scanner/scanner_tools/common.py |
SCANNER_SUBPROCESS_RECEIPT_LIMIT | scanner/scanner_tools/common.py |
SCANNER_VERSION | api/api.py, api/model_intake/router.py, docker-compose.release.yml, docker-compose.yml, scanner/release_identity.py |
SCAN_CANCEL_POLL_SECONDS | api/worker.py |
SCAN_CHECKPOINT_FILE | scanner/manifests.py, scanner/scanner.py |
SCAN_COOPERATIVE_CANCEL_GRACE_SECONDS | api/worker.py |
SCAN_FAULTHANDLER | scanner/scanner.py |
SCAN_FORCED_BROWSING_MAX_SECONDS | scanner/scanner.py |
SCAN_FORCE_EXIT_ON_SHUTDOWN_TIMEOUT | scanner/scanner.py |
SCAN_KILL_GRACE_SECONDS | api/worker.py |
SCAN_LOG_TAIL | api/worker.py |
SCAN_LOG_TTL_SECONDS | api/worker.py |
SCAN_MAX_DURATION_DEFAULT_MINUTES | api/worker.py |
SCAN_PHASE4_CANCEL_GRACE | scanner/scanner.py |
SCAN_PHASE4_LOGS | scanner/scanner.py |
SCAN_PHASE4_MAX_SECONDS | scanner/scanner.py |
SCAN_PHASE4_TRACE | scanner/scanner.py |
SCAN_QUEUE_NAME | api/ai_targets/router.py, api/fleet_routes/router.py, api/model_intake/router.py, api/operations/router.py, api/targets/router.py |
SCAN_SETTINGS_KEY | api/settings_routes/router.py |
SCAN_SHUTDOWN_GRACE_SECONDS | scanner/scanner.py |
SCAN_VERIFICATION_MAX | scanner/scanner.py |
SHAKERSCAN_AGENT_TOOL_OUTPUT_BYTES | api/worker.py |
SHAKERSCAN_AGENT_TOOL_RESULT_TTL_SECONDS | api/worker.py |
SHAKERSCAN_API_GID | docker-compose.release.yml |
SHAKERSCAN_API_PORT | docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_API_TOKEN | scripts/scan_cli.py, scripts/v2_cli.py |
SHAKERSCAN_API_TOKEN_FILE | scripts/scan_cli.py |
SHAKERSCAN_API_UID | docker-compose.release.yml |
SHAKERSCAN_API_URL | api/model_intake_admission_webhook.py, scripts/shakerscan_mcp.py |
SHAKERSCAN_ASM_DISPATCH_INTERVAL | api/api.py |
SHAKERSCAN_AUTHENTICATED_ASSURANCE | api/authenticated_assurance/router.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_BIND_HOST | api/authenticated_assurance/router.py, api/fleet_routes/router.py, api/operator_auth.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_BROKER_LEASE | api/broker_worker.py, api/worker.py |
SHAKERSCAN_BROKER_LEASE_SECONDS | api/fleet_routes/router.py |
SHAKERSCAN_BROKER_MAX_ACTIVE_SCANS | api/fleet_routes/router.py |
SHAKERSCAN_BROKER_MAX_ARTIFACT_BYTES | api/fleet_routes/router.py |
SHAKERSCAN_BROKER_MAX_RESULT_BYTES | api/fleet_routes/router.py |
SHAKERSCAN_BUILD_NETWORK | docker-compose.yml |
SHAKERSCAN_CALIBRATION_IMPORT_ROOT | scripts/device_posture_calibration.py |
SHAKERSCAN_CANCEL_FILE | scanner/scanner_tools/cancellation.py, scanner/scanner_tools/common.py, scanner/scanner_tools/discovery.py |
SHAKERSCAN_CANONICAL_REPORT_ONLY | scanner/scanner_tools/common.py |
SHAKERSCAN_CANONICAL_SCAN_EXECUTION | scanner/scanner.py |
SHAKERSCAN_COMPOSE_PROJECT | api/api.py |
SHAKERSCAN_CORS_ALLOW_ORIGINS | api/api.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_CORS_ALLOW_ORIGIN_REGEX | api/api.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_CRAWLER_MEMORY_LIMIT_MB | api/deployment_policy.py |
SHAKERSCAN_CREDENTIAL_TMP_DIR | api/runtime/credential_resolver.py |
SHAKERSCAN_CUSTOM_WORDLIST | scanner/scanner_tools/discovery.py |
SHAKERSCAN_DATA_BIND_HOST | docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_DEBUG_POST_INFER | scanner/scanner.py |
SHAKERSCAN_DEVICE_ALLOW_METADATA_TARGETS | scanner/scanner_tools/device_posture.py |
SHAKERSCAN_DEVICE_DENY_CIDRS | scanner/scanner_tools/device_posture.py |
SHAKERSCAN_DEVICE_QUEUE_VISIBILITY_TIMEOUT_SECONDS | docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_DISABLE_DISCOVERY_RECOVERY | scanner/manifests.py |
SHAKERSCAN_DNS_DOH_RESOLVERS | api/capabilities/dns.py, docker-compose.broker-worker.yml, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_DOCKER_GID | docker-compose.release.yml |
SHAKERSCAN_ENABLE_ADAPTIVE_THROTTLE | scanner/scanner.py |
SHAKERSCAN_ENDPOINT_MANIFEST_FILE | scanner/manifests.py |
SHAKERSCAN_ENFORCE_FLEET_LIMITS | api/worker.py |
SHAKERSCAN_EXPECTED_API_FINGERPRINT | docker-compose.yml |
SHAKERSCAN_FLEET_MEMORY_GB | api/deployment_policy.py |
SHAKERSCAN_FLEET_OPERATOR_TOKEN | scripts/fleet_acceptance.py |
SHAKERSCAN_HOST_PLATFORM | api/api.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_HTTP_ARCHIVE | api/runtime/http_archive.py |
SHAKERSCAN_HTTP_ARCHIVE_ALLOW_RAW | api/runtime/http_archive_router.py |
SHAKERSCAN_HUNT_INTERACTSH_SERVER | api/agent_tools.py |
SHAKERSCAN_HUNT_INTERACTSH_TOKEN | api/agent_tools.py |
SHAKERSCAN_INSTALL_KIND | api/model_intake/router.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_MAX_ACTIVE_SCANS | api/api.py, api/worker.py |
SHAKERSCAN_MAX_WORKERS | api/api.py, docker-compose.yml |
SHAKERSCAN_MCP_ALLOW_REMOTE_API | scripts/shakerscan_mcp.py |
SHAKERSCAN_MCP_TIMEOUT_SECONDS | scripts/shakerscan_mcp.py |
SHAKERSCAN_MODEL_INTAKE_ADAPTER_SELF_TEST | scanner/scanner_tools/model_intake_scanners.py |
SHAKERSCAN_MODEL_INTAKE_RUNTIME_LOCK | scanner/scanner_tools/model_intake_scanners.py |
SHAKERSCAN_NODE_ID | api/artifact_storage.py, api/broker_worker.py, api/fleet_worker_entrypoint.py, api/worker.py |
SHAKERSCAN_NODE_LABELS_JSON | api/worker.py |
SHAKERSCAN_PAYLOAD_PACK_MAX | scanner/scanner_tools/active_checks.py |
SHAKERSCAN_PER_WORKER_MEM_GB | api/api.py, docker-compose.yml |
SHAKERSCAN_PLATFORM_MEMORY_RESERVE_GB | api/api.py, docker-compose.yml |
SHAKERSCAN_POSTURE_CONCURRENCY | api/public_check.py |
SHAKERSCAN_POSTURE_ENGINE | api/public_check.py |
SHAKERSCAN_POSTURE_IPINFO_TOKEN | api/public_check.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_POSTURE_NODE | api/public_check.py |
SHAKERSCAN_POSTURE_RESOLVER | api/public_check.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_PRIVATE_NETWORK_TARGETS | api/deployment_policy.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_PUBLIC_API_URL | docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_PUBLIC_HOST | api/api.py, api/operator_auth.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_QUEUE_CONSUMER_GROUP | api/job_queue.py, docker-compose.release.yml, docker-compose.worker.yml, docker-compose.yml |
SHAKERSCAN_QUEUE_LEASE_HEARTBEAT_FAILURE_LIMIT | api/worker.py, docker-compose.release.yml, docker-compose.worker.yml, docker-compose.yml |
SHAKERSCAN_QUEUE_LEASE_HEARTBEAT_SECONDS | api/worker.py, docker-compose.release.yml, docker-compose.worker.yml, docker-compose.yml |
SHAKERSCAN_QUEUE_MAX_DELIVERY_ATTEMPTS | api/fleet_routes/router.py, api/worker.py, docker-compose.release.yml, docker-compose.worker.yml, docker-compose.yml |
SHAKERSCAN_QUEUE_ROUTE_MAX | api/job_queue.py |
SHAKERSCAN_QUEUE_VISIBILITY_TIMEOUT_SECONDS | api/worker.py, docker-compose.release.yml, docker-compose.worker.yml, docker-compose.yml |
SHAKERSCAN_RELEASE_MANIFEST | scanner/release_identity.py |
SHAKERSCAN_REQUEST_BUDGET_DOMAIN | scanner/scanner.py |
SHAKERSCAN_REQUEST_BUDGET_LIMIT | scanner/scanner.py |
SHAKERSCAN_REQUEST_BUDGET_MODE | api/worker.py, scanner/scanner.py |
SHAKERSCAN_REQUEST_BUDGET_RESERVED | scanner/scanner.py |
SHAKERSCAN_RUNTIME_DIR | api/model_intake/router.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_SCAN_SLOT_MAX_WAIT_SECONDS | api/worker.py |
SHAKERSCAN_SCAN_SLOT_TTL_SECONDS | api/worker.py |
SHAKERSCAN_SCHEDULE_DISPATCH_ORIGIN | api/schedules/managed_options.py, api/schedules/managed_runner.py |
SHAKERSCAN_SCHEDULE_DISPATCH_TOKEN | api/schedules/managed_options.py, api/schedules/managed_runner.py |
SHAKERSCAN_SKILLS_DIR | api/hunt/skills.py |
SHAKERSCAN_STALE_DURATION_GRACE_MIN | api/api.py |
SHAKERSCAN_STALE_FAIL_AFTER_SECONDS | api/worker.py |
SHAKERSCAN_STREAM_SCANNER_LOGS | api/worker.py |
SHAKERSCAN_TRIVY_CACHE_DIR | scanner/scanner_tools/model_intake_scanners.py |
SHAKERSCAN_TRIVY_REFRESH_ON_START | scanner/scanner_tools/model_intake_scanners.py |
SHAKERSCAN_TRIVY_REFRESH_TIMEOUT_SECONDS | scanner/scanner_tools/model_intake_scanners.py |
SHAKERSCAN_TRUSTED_REMOTE_TRANSPORT | api/operator_auth.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_UI_PORT | api/api.py, api/public_api_contract.py, docker-compose.release.yml, docker-compose.yml |
SHAKERSCAN_WORKER_BUILD_REPORT_INTERVAL_SECONDS | api/worker.py |
SHAKERSCAN_WORKER_FAIL_CLOSED | api/worker.py |
SHAKERSCAN_WORKER_IMAGE_DIGEST | scanner/scanner_tools/model_intake_scanners.py |
SHAKERSCAN_WORKER_MEM_LIMIT_GB | api/api.py |
SIGNER_IMAGE | docker-compose.release.yml |
SMART_BOLA_LANE_MAX_SECONDS | scanner/scanner.py |
TESTSSL_BIN | scanner/scanner_tools/tls_scanner.py |
UI_IMAGE | docker-compose.release.yml |
VERIFICATION_MIN_SEVERITY | api/api.py, api/retest_contract.py, api/worker.py, scanner/scanner.py |
VIRUSTOTAL_API_KEY | scanner/scanner.py |
WORKER_ID | api/broker_worker.py, api/worker.py |
WORKER_IMAGE | api/worker.py |
WORKER_PREFLIGHT_ENABLED | api/worker.py |
WORKER_PREFLIGHT_REQUIRE_SCANNER | api/worker.py |
WORKER_PREFLIGHT_TIMEOUT_SECONDS | api/worker.py |
WORKER_QUEUE_BLOCK_SECONDS | api/worker.py |
WORKER_REDIS_SOCKET_TIMEOUT_SECONDS | api/worker.py |
UI Pages
| Route | Source |
|---|---|
/ai-gate | ui/src/app/ai-gate/page.tsx |
/asm | ui/src/app/asm/page.tsx |
/campaigns/{id} | ui/src/app/campaigns/[id]/page.tsx |
/campaigns | ui/src/app/campaigns/page.tsx |
/credentials | ui/src/app/credentials/page.tsx |
/deep-hunt/experiment | ui/src/app/deep-hunt/experiment/page.tsx |
/deep-hunt/explorer | ui/src/app/deep-hunt/explorer/page.tsx |
/deep-hunt/leads | ui/src/app/deep-hunt/leads/page.tsx |
/deep-hunt/operator | ui/src/app/deep-hunt/operator/page.tsx |
/deep-hunt | ui/src/app/deep-hunt/page.tsx |
/deep-hunt/runs/{id} | ui/src/app/deep-hunt/runs/[id]/page.tsx |
/devices/{id}/agent | ui/src/app/devices/[id]/agent/page.tsx |
/devices/{id} | ui/src/app/devices/[id]/page.tsx |
/devices | ui/src/app/devices/page.tsx |
/devices/policies | ui/src/app/devices/policies/page.tsx |
/docs | ui/src/app/docs/page.tsx |
/evidence | ui/src/app/evidence/page.tsx |
/exposure | ui/src/app/exposure/page.tsx |
/findings/{id} | ui/src/app/findings/[id]/page.tsx |
/findings/candidates | ui/src/app/findings/candidates/page.tsx |
/findings | ui/src/app/findings/page.tsx |
/fleet | ui/src/app/fleet/page.tsx |
/hunt | ui/src/app/hunt/page.tsx |
/hunts | ui/src/app/hunts/page.tsx |
/model-intake | ui/src/app/model-intake/page.tsx |
/ | ui/src/app/page.tsx |
/request-collections | ui/src/app/request-collections/page.tsx |
/scan/new | ui/src/app/scan/new/page.tsx |
/scans/{id} | ui/src/app/scans/[id]/page.tsx |
/scans | ui/src/app/scans/page.tsx |
/schedules | ui/src/app/schedules/page.tsx |
/settings/arsenal | ui/src/app/settings/arsenal/page.tsx |
/settings | ui/src/app/settings/page.tsx |
/settings/policy-profiles | ui/src/app/settings/policy-profiles/page.tsx |
/targets/{id}/graph | ui/src/app/targets/[id]/graph/page.tsx |
/targets | ui/src/app/targets/page.tsx |
/timeline | ui/src/app/timeline/page.tsx |
/workers | ui/src/app/workers/page.tsx |
Skills, Slash Commands, And Subagents
| Skill | Purpose | Source |
|---|---|---|
ai-security-session | Interactive Testing through ShakerScan's /session API. Use when asked to test manually, open an interactive browser session, exercise authentication workflows, or perform BOLA/IDOR endpoint replay. | skills/ai-security-session/SKILL.md |
content-discovery | Build target-specific content discovery seeds, path lists, and ShakerScan scan inputs from scan results, JS analysis, framework clues, and exposed docs. Use when asked for content discovery, wordlist generation, ffuf seeds, admin path discovery, hidden file discovery, route discovery, or custom endpoint seeding. | skills/content-discovery/SKILL.md |
device-hunt | Compatibility entry point for the unified ShakerScan Hunt workflow. Use only when an older prompt says Device Hunt; follow the canonical hunt skill and /hunts API with a device target. | skills/device-hunt/SKILL.md |
device-triage | Explain or triage one registered connected device using existing ShakerScan evidence only. Use for requests such as explain this device, compare its scans, assess whether a device finding is credible, review policy decisions, or summarize device drift when the user has not authorized new device traffic. Do not queue scans or probes. | skills/device-triage/SKILL.md |
hunt | Drive ShakerScan Hunt for an authorized web, API, network, or connected-device target through the target-bound /hunts API. Use for autonomous investigation, security hunting, or evidence-driven exploration; use Scan for deterministic baseline assessment. | skills/hunt/SKILL.md |
js-analyze | Analyze JavaScript bundles, frontend routes, browser-captured APIs, libraries, and secrets for a ShakerScan target or completed scan. Use when asked for JS analysis, route analysis, frontend endpoint discovery, library review, source-map hints, or to build custom_endpoints for a ShakerScan scan. | skills/js-analyze/SKILL.md |
research-agent | Compatibility entry point for the unified ShakerScan Hunt workflow. Use only when an older prompt says Deep Hunt or autonomous research; follow the canonical hunt skill and /hunts API. | skills/research-agent/SKILL.md |
review-skills | Review ShakerScan skills, commands, and subagents for broken references, invalid Claude Code configuration, prompt anti-patterns, missing hard gates, missing outputs, and weak operational guidance. Use when asked to audit, review, or quality-check the skill system itself. | skills/review-skills/SKILL.md |
shakerscan | Operate ShakerScan. Route deterministic assessment to one budgeted Scan, adaptive investigation of web or device targets to Hunt, and manual browser work to Interactive Testing; also manage targets, Continuous ASM, findings, AI Gate, Model Intake, evidence, schedules, workers, and fleets. | skills/shakerscan/SKILL.md |
| Canonical slash command | Title | Purpose | Source |
|---|---|---|---|
/ai-gate | AI Gate | Create/list AI Gate targets and queue AI safety scans. | .claude/commands/ai-gate.md |
/ai-security-session | Interactive Testing | Drive an authorized Interactive Testing browser workflow with the compatibility-named ai-security-session skill. | .claude/commands/ai-security-session.md |
/content-discovery | Content Discovery | Build a high-signal route and file discovery plan for a target using ShakerScan evidence, JS outputs, and framework clues. | .claude/commands/content-discovery.md |
/deep-hunt | Hunt compatibility command | Run an authorized, AI-driven Hunt against the supplied target. | .claude/commands/deep-hunt.md |
/delete-target | Archive or Delete a Target | Archive a target (hide it, pause its schedules, keep its history) or permanently delete it with | .claude/commands/delete-target.md |
/findings | List Security Findings | Show security findings from scans. | .claude/commands/findings.md |
/js-analyze | JS Analyze | Run JavaScript and frontend attack-surface analysis for a target, completed scan, or supplied JS bundle set. | .claude/commands/js-analyze.md |
/research | Hunt compatibility command | Use the research-agent skill. | .claude/commands/research.md |
/review-skills | Review Skills | Review all ShakerScan skills, commands, and agents for prompt bugs and quality gaps. | .claude/commands/review-skills.md |
/save-finding | Save Finding | Save an evidence-backed finding from authorized manual or interactive testing. | .claude/commands/save-finding.md |
/scan | Submit the deterministic Scan | Submit ShakerScan's single deterministic Web/API security workflow. Resource profiles are hard | .claude/commands/scan.md |
/status | Scanner Status | Check the status of ShakerScan. | .claude/commands/status.md |
/subdomains | Subdomain Discovery | Discover subdomains for a domain using CT logs and passive sources. | .claude/commands/subdomains.md |
/workers | Worker Management | View and scale scanner workers. | .claude/commands/workers.md |
| Subagent | Model | Purpose | Source |
|---|---|---|---|
content-discovery-agent | sonnet | Use this agent for high-signal route and file discovery, admin path seeding, API/spec path generation, and producing custom_list and custom_endpoints output for ShakerScan. | .claude/agents/content-discovery-agent.md |
js-analysis-agent | sonnet | Use this agent for JavaScript bundle analysis, frontend route discovery, browser-captured API review, library/version review, source-map hints, and ShakerScan custom_endpoints generation. | .claude/agents/js-analysis-agent.md |
skills-reviewer | opus | Use PROACTIVELY to review ShakerScan skills, commands, and agents for prompt bugs, bad gates, invalid frontmatter, broken references, or weak output contracts. | .claude/agents/skills-reviewer.md |
Internal Compatibility Scanner Module Inventory
Implementation modules below are inventory only. The immutable action graph and canonical capability registry define execution authority; module presence does not advertise a public Scan feature or a second orchestration engine.
access_control_checks.py, active_checks.py, active_enrichment_policy.py, active_prioritization.py, adaptive_throttle.py, ai_classifier.py, api_auth.py, api_security.py, approval_checks.py, asn_discovery.py, attack_chains.py, attempt_telemetry.py, auth_session.py, authz_replay_routing.py, benchmark_summary.py, bola_comparison.py, bounded_exec.py, brand_protection.py, breach_check.py, browser_profile.py, build_fingerprint.py, cancellation.py, client_side.py, common.py, completion_status.py, compliance_mapper.py, coverage_tracker.py, credential_check.py, critical_checks.py, ct_monitor.py, data_exposure.py, deduplication_engine.py, deserialization_tests.py, device_advisories.py, device_application.py, device_control_plane.py, device_evidence.py, device_postman.py, device_posture.py, device_probe.py, device_protocols.py, device_reachability.py, device_request_formats.py, device_safety.py, device_shell.py, device_web.py, discovery.py, discovery_policy.py, dns_enhanced.py, dom_xss_analyzer.py, domain_intel.py, exposure_markers.py, file_upload_tests.py, finding_correlator.py, finding_validator.py, focused_scope.py, form_login.py, github_recon.py, google_dorking.py, gopher_payloads.py, graphql_schema_recovery.py, grpc_discovery.py, gungnir.py, har_discovery.py, hash_routes.py, health_check.py, http_archive_capture.py, http_scanner.py, hunter_summary.py, infrastructure_checks.py, injection_extra_checks.py, ip_reputation.py, logging_checks.py, model_intake.py, model_intake_acquisition.py, model_intake_adapter_self_test.py, model_intake_admission.py, model_intake_archives.py, model_intake_attestation.py, model_intake_evaluation.py, model_intake_licenses.py, model_intake_providers.py, model_intake_registry.py, model_intake_retention.py, model_intake_runtime.py, model_intake_safetensors_runtime.py, model_intake_safetensors_selftest.py, model_intake_sandbox.py, model_intake_scanners.py, network_services.py, nmap.py, nuclei.py, oauth_auth.py, oauth_tests.py, phase4_checks.py, proof_of_exploit.py, race_condition_tests.py, remediation_kb.py, report_gating.py, request_collections.py, request_meter.py, request_replay.py, resource_propagation.py, sarif_output.py, scan_delta.py, signal_types.py, smtp_scanner.py, ssh_scanner.py, subdomain_discovery.py, subfinder.py, tech_discovery.py, tls_scanner.py, url_redaction.py, v2_fingerprint_hardening.py, v2_request_replay_hardening.py, vendor_risk.py, verification_engine.py, verification_phase.py, wayback_discovery.py, webhook_checks.py, websocket_security.py, xss_evidence.py
Durable Storage Inventory
| Table | Declared by |
|---|---|
agent_context_packs | api/retest_contract.py |
agent_decision_traces | api/retest_contract.py |
agent_hunt_runs | api/retest_contract.py |
ai_surface_attempts | db/init.sql |
ai_surfaces | db/init.sql |
ai_target_credentials | db/init.sql |
ai_target_principals | api/retest_contract.py |
ai_targets | db/init.sql |
app_schema_migrations | db/init.sql |
app_settings | api/retest_contract.py |
application_graph_edges | db/init.sql |
application_graph_nodes | db/init.sql |
approval_receipts | api/retest_contract.py |
asm_endpoint_attempts | db/init.sql |
auth_sessions | db/init.sql |
broker_job_leases | db/init.sql |
broker_job_results | db/init.sql |
campaign_actions | api/retest_contract.py |
campaigns | api/retest_contract.py |
command_results | api/retest_contract.py |
credential_profile_bindings | db/init.sql |
credential_profile_versions | db/init.sql |
credential_profiles | db/init.sql |
device_agent_actions | db/init.sql |
device_agent_runs | db/init.sql |
device_credential_attempts | db/init.sql |
device_credential_profiles | db/init.sql |
device_interfaces | db/init.sql |
device_locator_history | db/init.sql |
device_policies | db/init.sql |
device_request_collections | db/init.sql |
device_services | db/init.sql |
device_targets | db/init.sql |
discovery_runs | db/init.sql |
evidence_instances | api/retest_contract.py |
evidence_objects | db/init.sql |
evidence_retention_previews | db/init.sql |
export_events | db/init.sql |
finding_exceptions | db/init.sql |
finding_verifications | db/init.sql |
findings | db/init.sql |
fleet_node_events | db/init.sql |
http_archive_stats | db/init.sql |
http_transactions | db/init.sql |
hunt_actions | db/init.sql |
hunt_budget_amendments | db/init.sql |
hunt_cancellable_jobs | api/retest_contract.py |
hunt_runs | db/init.sql |
hunt_skill_events | db/init.sql |
hypotheses | api/retest_contract.py |
investigation_candidate_observations | api/retest_contract.py |
investigation_candidates | api/retest_contract.py |
model_intake_admission_events | db/init.sql |
model_intake_admissions | db/init.sql |
model_intake_agent_actions | db/init.sql |
model_intake_agent_sessions | db/init.sql |
model_intake_approval_receipts | db/init.sql |
model_intake_automatic_reviews | api/retest_contract.py |
model_intake_deployment_bindings | db/init.sql |
model_intake_evidence_manifests | db/init.sql |
model_intake_evidence_records | db/init.sql |
model_intake_policy_decisions | db/init.sql |
model_intake_runner_jobs | db/init.sql |
model_intake_subjects | db/init.sql |
model_intake_submission_events | db/init.sql |
model_intake_submissions | db/init.sql |
model_intake_trust_anchors | db/init.sql |
node_credentials | db/init.sql |
node_join_tokens | db/init.sql |
nodes | db/init.sql |
operation_plans | api/retest_contract.py |
policy_profiles | db/init.sql |
public_api_idempotency | db/init.sql |
refuter_reviews | api/retest_contract.py |
request_collection_bindings | db/init.sql |
request_collection_environments | db/init.sql |
request_collection_requests | db/init.sql |
request_collection_selections | db/init.sql |
request_collections | db/init.sql |
research_decisions | api/retest_contract.py |
research_episodes | api/retest_contract.py |
research_events | api/retest_contract.py |
research_observations | api/retest_contract.py |
scan_action_plan_revisions | db/init.sql |
scan_artifacts | db/init.sql |
scan_campaigns | db/init.sql |
scan_capability_actions | db/init.sql |
scan_observation_manifests | db/init.sql |
scan_stage_checkpoints | db/init.sql |
scan_work_manifests | db/init.sql |
scans | db/init.sql |
schedules | db/init.sql |
scope_receipts | api/retest_contract.py |
target_credential_profiles | api/retest_contract.py |
target_endpoint_expectations | api/retest_contract.py |
target_endpoints | db/init.sql |
target_invariant_contracts | api/retest_contract.py |
target_principal_provisioning_attempts | api/retest_contract.py |
target_principals | api/retest_contract.py |
targets | db/init.sql |
tool_receipts | api/retest_contract.py |
18. Where to go deeper
| Topic | Document |
|---|---|
| Agent-facing API how-to (request bodies, examples) | AGENTS.md |
| Getting started, install, product tour | README.md |
| AI-native V2 architecture and trust boundary | ai-native-architecture-rfc.md |
| Scan execution/action/revision schemas | execution.py · action_plan.py · continuation.py |
| Historical pre-V2 mode policy | archive/smart-scan-policy.md |
| OWASP coverage and intentional gaps | owasp-coverage-matrix.md |
| Product direction | product-model.md · architecture documents in this directory |
| Release and publishing process | release-process.md |
| AI test workflows + Honey contract | AI_TEST_WORKFLOWS.md |
| Interactive session compatibility API | Live /session* OpenAPI contract |
| DAST execution and Continuous ASM architecture | dast-asm-architecture.md |
| Connected-device architecture, policies, and safety boundary | connected-device-security.md |
| Multi-node fleet architecture (RFC) | multi-node-architecture.md |
| Multi-node setup and operations | multi-node-guide.md |
Reminder: where any doc and the code disagree, the code, DB schema, and tests win. This reference is a map, not the territory.