Job Schema
Complete field reference for job configuration files.
Complete field reference for job configuration files. For conceptual overview, see job concepts.
IDE Integration
Add this directive to the top of your YAML file for autocomplete and validation:
# yaml-language-server: $schema=https://tracemill.dev/schemas/job.schema.jsonProperties
| Field | Type | Required | Description |
|---|---|---|---|
type | "job" | Yes | Discriminator. |
description | string | No | Free-text description. |
tags | string[] | No | Classification tags (unique values). |
mitre | object | No | MITRE ATT&CK mapping. Same structure as scenario mitre. |
state | object | No | Job-level variables. See state. |
pools | object[] | No | Pool registry. See pools. |
workloads | object[] | Yes | Min 1. See workload. |
state
A map of variable names to ExprStr values, evaluated once before workloads start.
Unlike scenario state, pool.* expressions are allowed here. Job state is available to workload bindings via ref.*, but does not flow to scenarios implicitly — use explicit bindings (e.g. account_id: ref.account_id).
state:
account_id: "000000000000"
region: us-east-1
api_endpoint: "https://api.example.com:8443"pools
An array of pool entries. Each entry is either an inline pool definition or a reference to an external pool file. See pool schema for the full pool configuration.
Inline pool
Defines the pool directly in the job file. The type field is optional for inline pools.
pools:
- id: threat-ips
sampling:
mode: random
seed: 42
ip_range:
cidrs:
- 198.51.100.0/24External pool reference
Points to a standalone pool file by path or content ID. The job entry's id is used regardless of what id the file contains.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Pool ID for this job. Pattern: ^[a-zA-Z][a-zA-Z0-9_-]*$ |
description | string | No | |
path | string | Yes | Content ID (e.g. resources/pools/threat-ips) or file path (starting with ./, ../, /, or ~). |
pools:
- id: users
path: ./pools/users.yamlworkload
Each workload runs a scenario with optional concurrency, looping, and bindings.
| Field | Type | Required | Description |
|---|---|---|---|
scenario | string | Yes | Scenario to run: a content ID (e.g. aws/scenarios/brute-force) or a file path (starting with ./, ../, /, or ~). |
concurrency | integer | No | Parallel goroutines running the scenario. Default: 1. Min: 1. |
loop | integer | "infinite" | No | Repetitions: 0 or 1 = run once, N = run N times, "infinite" or -1 = run until cancelled. Default: 0. Mutually exclusive with matrix. |
start_after | string | No | Delay before this workload starts, relative to job start. Duration format. |
eps | number | No | Events-per-second rate limit. 0 = unlimited. Min: 0. |
matrix | object | No | Parameterised axes. Each key is an axis name; the value is an inline list or pool.<id> reference. The scenario runs once per cartesian-product combination. Mutually exclusive with loop. |
bindings | object | No | State variable overrides as ExprStr values. Only explicit bindings flow to the scenario, overriding its state defaults. Can reference job state via ref.* and pools via pool.*. |
fields | object | No | Static fields injected into every event from this workload. Event-level fields win on conflict. |
Example
workloads:
- scenario: ./scenarios/brute-force.yaml
concurrency: 2
bindings:
source_ip: pool.threat-ips
username: pool.target-usernames
account_id: ref.account_id
- scenario: ./scenarios/api-calls.yaml
loop: 10
eps: 50
start_after: 5s
fields:
environment: production