Skip to main content

levo-dast.yml schema reference

Every top-level key in levo-dast.yml, grouped by concern. Unknown keys cause a load error (extra = "forbid"), so typos surface immediately.

Top-level keysโ€‹

KeyPurpose
versionSchema version. Always "1" for now.
nameLogical scan / app name used in reports.
targetURL and scope (capture / exclude domains).
crawlCrawler type, bounds, and crawl timeout.
authStrategy + non-secret auth fields.
scanPhase toggles, injection controls, timeouts, and per-category active-test flags.
cveJS, DOM, and nuclei CVE checks.
chatbotInline chatbot testing.
aiLLM provider (key stays in env).
satelliteOn-prem traffic export.
What's NOT at the top level

app.*, vulnerabilities.*, timeouts.*, env.*, and levo.* are not top-level blocks โ€” the loader rejects them. version and name are the only top-level scalars; everything else (target, crawl, auth, scan, cve, chatbot, ai, satellite) is a nested block. Active-test categories nest inside scan.active_testing_categories; timeouts nest inside scan and crawl; Levo IDs are secrets and come from CLI/env.


version, nameโ€‹

version: "1"
name: "acme-webapp"
FieldTypeDefaultNotes
versionstringrequiredSchema version.
namestringrequiredLogical name used in reports.

The Levo env-id (which environment a scan reports findings against) is a Levo identity value and comes from --env-id / LEVOAI_ENV_ID, not from this file.

targetโ€‹

target:
url: "https://app.example.com"
start_page: "/login"
ignore_third_party: true
capture_domains:
- "*.example.com"
exclude_domains:
- "analytics.example.com"
FieldTypeDefaultNotes
urlstringrequiredBase URL. Domain must be an owned domain.
start_pagestring/Path to start crawling from.
ignore_third_partybooltrueSkip hosts outside your org.
capture_domainsstring[][]Extra in-scope hosts (glob patterns).
exclude_domainsstring[][]Hosts to skip.

crawlโ€‹

crawl:
type: "hybrid"
max_depth: 5
max_pages: 200
max_clicks_per_page: 30
max_global_clicks: 1000
ai_form_filling: true
ai_form_policy: "moderate"
timeout: 900
FieldTypeDefaultNotes
typeenumstandardstandard ยท ai ยท hybrid ยท legacy.
max_depthint3Link-depth cap.
max_pagesint100Upper bound on unique pages.
max_clicks_per_pageint20AI-assisted click budget per page.
max_global_clicksint500Click budget across the scan.
ai_form_fillingboolfalseLet an LLM fill unknown forms.
ai_form_policyenummoderateconservative ยท moderate ยท aggressive.
timeoutint900Crawl phase timeout, seconds.

authโ€‹

auth:
strategy: "form"
username: "${SCAN_USERNAME}"
login_url: "https://app.example.com/login"
wait_for_mfa: false
headers:
- "X-Scan-Source: shadownet"
# custom_instructions: "Click the 'Continue with email' button first."
# session_file: "session.json" # only for strategy: session_transplant
FieldTypeDefaultNotes
strategyenumnonenone ยท form ยท token ยท ai ยท session_transplant.
usernamestringโ€”Non-secret half of form auth.
login_urlstringโ€”Required for form and most ai flows.
wait_for_mfaboolfalsePause for MFA in interactive mode.
headersstring[][]Extra request headers. Non-secret only. CR/LF rejected.
custom_instructionsstringโ€”Free-text guidance surfaced to the LLM during AI-guided login (strategy: ai only). Max 4000 chars.
session_filestringโ€”Relative path to a Levo-extension-exported session JSON. Pairs with strategy: session_transplant. Equivalent to --auth-session-file.

Strategiesโ€‹

StrategyWhen to pick it
nonePublic site, or you want crawl-only.
formUsername/password login via a normal form.
tokenAPI with Authorization: Bearer โ€ฆ.
aiLLM walks the login flow โ€” useful for unusual UIs, SSO that fits in a single browser.
session_transplantYou have a session.json exported from the Levo browser extension. Scanner skips auth entirely and reuses your cookies + storage.
Danger

password, token, raw cookie values, and local_storage_b64 are rejected. Use --password, --token, --auth-session-file, or env vars (SCAN_PASSWORD, SCAN_TOKEN, โ€ฆ).

scanโ€‹

scan:
enable_passive: true
enable_active: true
enable_websocket: true
enable_graphql: true
enable_ai: false
attack_strength: "medium"
max_payloads: 100
active_delay_ms: 50
http_methods: ["GET", "POST", "PUT", "DELETE"]
inject_locations: ["query", "body", "header", "path"]
depth: "thorough"
tech_aware: true
timeout: 3600
test_timeout: 30
probe_timeout: 15

active_testing_categories:
xss: true
sqli: true
path_traversal: true
ssrf: true
xxe: true
command_injection: true
open_redirect: true
csrf: true
idor: true
FieldTypeDefaultNotes
enable_passivebooltrueResponse analysis only (prod-safe).
enable_activebooltrueSends injection payloads.
enable_websocketbooltrueTest WS/WSS endpoints.
enable_graphqlbooltrueIntrospect and fuzz GraphQL.
enable_aiboolfalseLLM triage of findings.
attack_strengthenummediumlow ยท medium ยท high ยท insane.
max_payloadsint50Active payloads per endpoint.
active_delay_msint0Throttle between payloads.
http_methodsstring[]["GET","POST","PUT"]Verbs to exercise.
inject_locationsstring[]["query","body","header","cookie","path"]Injection points.
depthenumsmartsmart (default) ยท thorough.
tech_awarebooltrueSkip tests irrelevant to detected stack.
timeoutint3600Overall scan budget, seconds.
test_timeoutint30Per-test timeout, seconds.
probe_timeoutint15Per-probe timeout, seconds.
active_testing_categoriesmapall truePer-category toggles; only applied when enable_active: true. Omit categories to keep them on.

scan.active_testing_categoriesโ€‹

Nested map controlling individual active-test categories:

KeyDefaultTests
xsstrueCross-site scripting (reflected, stored).
sqlitrueSQL injection (error-based, time-based, union).
path_traversaltrue../ / LFI / directory traversal.
ssrftrueServer-side request forgery.
xxetrueXML external entity.
command_injectiontrueOS command injection.
open_redirecttrueUnvalidated redirects.
csrftrueCSRF token absence / weakness.
idortrueInsecure direct object reference.

cveโ€‹

cve:
js: true
dom: true
nuclei_templates: "cves/,exposures/"
FieldTypeDefaultNotes
jsboolfalseJavaScript library CVE scanning.
domboolfalseDOM-based XSS and client injection.
nuclei_templatesstringโ€”Nuclei template paths (comma-separated).

chatbotโ€‹

chatbot:
inline: true
test_timeout: 120
max_count: 5
FieldTypeDefaultNotes
inlineboolfalseTest embedded chatbot widgets.
test_timeoutint60Per-turn timeout (seconds).
max_countint3Cap on detected chatbots to test.

aiโ€‹

ai:
provider: "anthropic"
FieldTypeDefaultNotes
providerenumanthropicanthropic ยท openai. API key in env (ANTHROPIC_API_KEY / OPENAI_API_KEY).

satelliteโ€‹

See Install Satellite for how to stand one up.

satellite:
enabled: true
url: "https://satellite.levo.ai"
span_buffer_size: 1000
flush_interval: 10
FieldTypeDefaultNotes
enabledboolfalseRoute scan traffic through a Levo Satellite.
urlstringโ€”Satellite HAProxy URL.
span_buffer_sizeint1000In-memory span buffer.
flush_intervalint10Flush interval, seconds.

Secrets โ€” never in YAMLโ€‹

These must come from CLI flags or env vars, not the file:

CategoryKeys / env vars
Levo identity--org-id / LEVOAI_ORG_ID, --workspace-id / LEVOAI_WORKSPACE_ID, --env-id / LEVOAI_ENV_ID, --app-id / LEVOAI_APP_ID, LEVOAI_AUTH_KEY
Auth creds--password / SCAN_PASSWORD, --token / SCAN_TOKEN, raw cookies, local_storage_b64
LLM / third-partyANTHROPIC_API_KEY, OPENAI_API_KEY, CAPSOLVER_API_KEY, INTERACTSH_SERVER_URL, INTERACTSH_SERVER_AUTH_TOKEN

Validation errorsโ€‹

The loader reports errors with the YAML path of the offending field:

levo-dast.yml:scan.attack_strength: value 'extreme' is not a valid enum
(expected: low, medium, high, insane)

Typos surface the same way (thanks to extra = "forbid"):

levo-dast.yml: unknown field 'scann' at top level
(did you mean 'scan'?)

Secret keys are rejected with an actionable hint:

levo-dast.yml:auth.password: secrets not allowed in YAML
โ†’ use --password or SCAN_PASSWORD env var

Nextโ€‹

Was this page helpful?