Skip to content

Scan Profiles

A scan profile is an ordered list of plugin IDs that the worker executes when a scan starts. Profiles balance coverage, speed, and noise for different scan use cases.

Scan profiles are configuration-driven. The source of truth is backend/configs/config.yaml:

scan_profile_order:
  - quick
  - default
  - deep

scan_profiles:
  quick:
    name: Quick
    description: Fast low-noise discovery
    plugins:
      - subfinder
      - dnsx
      - httpx

After editing profile configuration, restart both API and worker so they load the same profile registry.

Runtime Behavior

When a scan is created, the API stores the selected profile ID with the scan record and queues that profile ID for the worker. The worker resolves the plugin execution order from the loaded profile registry.

Plugin order matters. Each plugin runs after the previous plugin and can add normalized assets to the running scan scope, which later plugins may consume.

If a future scan request uses an unknown profile ID, the API rejects it. If an old queued or scheduled scan references a profile that has been removed from config, the worker marks that scan failed with an unknown profile error instead of silently falling back to another profile.

Historical scans keep their stored profile ID and can still be displayed even if that ID is no longer configured.

Validation Rules

API and worker startup fail if scan profile configuration is invalid.

Validation rules:

  • scan_profiles must not be empty.
  • Profile IDs must be non-empty and use lowercase letters, numbers, _, or -.
  • name must be non-empty.
  • plugins must contain at least one plugin.
  • Plugin names must be non-empty.
  • Duplicate plugin names inside one profile are rejected.
  • Every plugin referenced by a profile must be registered in the plugin registry.
  • If scan_profile_order is set, it must include every configured profile exactly once.

Example startup error:

scan profile "deep" references unregistered plugin "foobar"

API

GET /api/v1/scan-profiles returns the configured profile definitions in scan_profile_order order:

[
  {
    "id": "quick",
    "name": "Quick",
    "description": "Fast low-noise discovery",
    "plugins": ["subfinder", "dnsx", "httpx"]
  }
]

The frontend should render the profiles returned by this endpoint instead of hardcoding profile options.

Built-in Profiles

The default backend/configs/config.yaml ships with these profiles. Keep the IDs stable because scan records store profile IDs.

ID Name Plugin order
quick Quick subfinder -> dnsx -> httpx
default Default subfinder -> dnsx -> httpx -> naabu -> nuclei
deep Deep subfinder -> amass -> dnsx -> naabu -> nmap -> httpx -> tlsx -> katana -> nuclei
stealth Stealth subfinder -> amass -> httpx
recon_nmap Recon + Nmap subfinder -> dnsx -> nmap
tls_audit TLS Audit subfinder -> dnsx -> httpx -> tlsx
web_discovery Web Discovery subfinder -> dnsx -> httpx -> katana -> nuclei
port_discovery Port Discovery subfinder -> dnsx -> naabu -> nmap
vuln_scan Vulnerability Scan httpx -> nuclei
recon_expanded Recon Expanded subfinder -> amass -> dnsx -> httpx -> tlsx
screenshot Screenshot subfinder -> dnsx -> httpx -> httpx_screenshot

Pipeline Chaining

The worker merges successful plugin output into the scan scope. Later plugins can consume assets produced earlier in the same scan.

Produced asset type Added to scope as
domain domain
subdomain subdomain
ip ip
cidr cidr
url url
service service

Example chain:

domain
  -> subfinder creates subdomains
  -> dnsx resolves subdomains to IPs
  -> naabu/nmap discover services
  -> httpx creates URLs
  -> katana discovers paths and URLs
  -> nuclei creates vulnerabilities

Adding a Custom Profile

Add the profile to backend/configs/config.yaml:

scan_profile_order:
  - quick
  - default
  - custom_tls

scan_profiles:
  custom_tls:
    name: Custom TLS Audit
    description: Custom certificate inventory
    plugins:
      - subfinder
      - dnsx
      - httpx
      - tlsx

Rules for custom profiles:

  • Choose a stable ID. Renaming it will not rename historical scan records.
  • List plugins in the exact order they should run.
  • Only reference registered plugin IDs.
  • Add the new ID to scan_profile_order if that setting is present.
  • Restart API and worker after editing config.

Removing or Disabling a Profile

To remove a profile from future scan creation, delete it from scan_profiles and remove it from scan_profile_order.

Existing scans are not deleted. Historical scan pages can still show the raw stored profile ID. Scheduled scans using a removed profile should be updated before they run again; otherwise the worker will fail them with an unknown profile error.

Adding a Plugin to a Profile

  1. Implement the wrapper in backend/internal/plugins/wrappers/.
  2. Register it in backend/internal/plugins/wrappers/defaults.go.
  3. Add tool installer configuration if the wrapper runs an external binary.
  4. Add the plugin ID to one or more scan_profiles entries in backend/configs/config.yaml.
  5. Restart API and worker.

Profile validation requires every referenced plugin to be registered. Missing plugin IDs are startup errors, not runtime warnings.

Plugin Catalog

See Plugin Catalog for per-plugin input, output, graph, artifact, dependency, and profile usage details.