YAML scan config
Complex scans — behind-the-login, multi-step auth, with 2FA, scope rules, and source-code access — become unwieldy as JSON body parameters. The YAML scan config format gives you a single reusable file you can commit to your repo and share across runs.
Minimal example
description: "Next.js e-commerce app on PostgreSQL"
authentication:
login_type: form
login_url: "https://app.example.com/login"
credentials:
username: "audit@example.com"
password: "***"
login_flow:
- "Type $username into the email field"
- "Type $password into the password field"
- "Click the 'Sign In' button"
success_condition:
type: url_contains
value: "/dashboard"
With 2FA (TOTP)
authentication:
login_type: form
login_url: "https://app.example.com/login"
credentials:
username: "audit@example.com"
password: "***"
totp_secret: "LB2E2RX7XFHSTGCK" # Base32
login_flow:
- "Type $username into email"
- "Type $password into password"
- "Click Sign In"
- "Enter $totp in the verification code field"
- "Click Verify"
success_condition:
type: url_contains
value: "/dashboard"
$totp gets substituted with a live RFC 6238 code at each login. The Base32 seed is handled by the tenant's Fernet key at rest; it's never logged.
Rules — avoid + focus
Natural-language scope control:
rules:
avoid:
- description: "Skip the logout endpoint"
type: path
url_path: "/logout"
- description: "No DELETE operations on user API"
type: path
url_path: "/api/v1/users/*"
focus:
- description: "Prioritise checkout flow"
type: path
url_path: "/api/checkout"
- description: "Beta admin subdomain"
type: subdomain
url_path: "beta-admin"
Rule shape: {description, type, url_path}. type can be path / subdomain / domain / method / header / parameter. Up to 50 entries per list.
Source-code hook
Combine with white-box mode:
source_code:
repo_url: https://github.com/acme/ecommerce.git
# or
# repo_path: /workspace/acme/ecommerce
Pentestas runs a large-tier code-analyst pass before dynamic probes fire. See Source-code-aware scans.
Submit
From the API
curl -X POST "https://app.pentestas.com/api/scans/yaml?target_url=https://app.example.com" \
-H "X-API-Key: aa_…" \
-H "Content-Type: application/yaml" \
--data-binary @scan-config.yaml
Returns the standard ScanResponse — same shape as POST /api/scans.
From the CLI
pentestas start -u https://app.example.com -c scan-config.yaml -w 1h
Full schema
description: string # <=500 chars
authentication:
login_type: form | sso | api | basic
login_url: string # https:// URL
credentials:
username: string
password: string
totp_secret: string (Base32) # optional
api_key: string # optional, for login_type=api
login_flow: [string] # up to 20 steps, each <=500 chars
success_condition:
type: url_contains | url_equals_exactly | element_present | text_contains
value: string
rules:
avoid: [{description, type, url_path}] # up to 50
focus: [{description, type, url_path}] # up to 50
source_code:
repo_url: string # or
repo_path: string
pipeline:
retry_preset: default | subscription
max_concurrent_pipelines: 1..5
Any field may be omitted; Pentestas merges defaults. The YAML parser enforces all size caps and rejects malformed input before the scan is enqueued.
See also
- Authenticated scans — auth primitives without YAML
- Source-code-aware scans
- Pentestas CLI