Scenario Schema
Complete field reference for scenario configuration files.
Complete field reference for scenario configuration files. For conceptual overview, see scenario 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/scenario.schema.jsonProperties
| Field | Type | Required | Description |
|---|---|---|---|
type | "scenario" | Yes | Discriminator. Must be the literal string scenario. |
description | string | No | Free-text description. Multi-line YAML supported. |
tags | string[] | No | Classification tags (unique values). |
mitre | object | No | MITRE ATT&CK mapping. See mitre. |
state | object | No | Variables initialised once per run. See state. |
steps | Step[] | Yes | Ordered list of emit and wait steps. Min 1. |
mitre
| Field | Type | Required | Description |
|---|---|---|---|
tactics | string[] | No | One or more ATT&CK tactics: reconnaissance, resource-development, initial-access, execution, persistence, privilege-escalation, defense-evasion, credential-access, discovery, lateral-movement, collection, command-and-control, exfiltration, impact. |
techniques | string[] | No | Technique IDs such as T1110 or sub-techniques like T1110.001. |
state
A map of variable names to ExprStr values, evaluated once per run in dependency order. Cycles are a compile-time error.
All ref.* targets must be declared in the same state block — undefined references are rejected at load time, even when a job binding supplies the value at runtime.
pool.* expressions are not allowed in scenario state. Draw from pools in job bindings and reference the result via ref.*.
state:
region: us-east-1 # literal
account_id: "012345678901" # quoted to preserve leading zero
session_id: gen.uuid() # generator
port: gen.int(min=1024, max=65535) # generator with params
actor: gen.aws_identity(type=IAMUser, accountId=ref.account_id) # ref in param
trail_arn: "arn:aws:cloudtrail:${ref.region}:${ref.account_id}:trail/prod" # interpolationJob workload bindings override these defaults at runtime.
Steps
Each step is an object with exactly one key: emit or wait.
EmitStep
Emits a single event through the configured sink.
| Field | Type | Required | Description |
|---|---|---|---|
event_type | string | Yes | Event type ID, optionally versioned: aws.cloudtrail@v1 or bare aws.cloudtrail. |
fields | object | Yes | Event fields as ExprStr values. Nested objects and arrays are supported. |
The engine merges event-type defaults first, then applies scenario fields on top. A timestamp is stamped automatically from the clock. Schema validation runs last.
- emit:
event_type: aws.cloudtrail@v1
fields:
eventID: gen.uuid()
eventName: ConsoleLogin
awsRegion: ref.region
sourceIPAddress: ref.source_ip
userIdentity:
type: ref.actor.type
arn: ref.actor.arn
accountId: ref.actor.accountIdWaitStep
Pauses execution for a duration before the next step.
| Field | Type | Required | Description |
|---|---|---|---|
duration | string | Yes | Go-style single-unit duration: 500ms, 2s, 1m, 3h. Pattern: ^[0-9]+(ns|us|µs|ms|s|m|h)$ |
jitter_pct | number | No | Random variance as a fraction of duration (0–1). Default: 0 (no jitter). |
- wait:
duration: 2s
jitter_pct: 0.4 # actual wait: 1.2s – 2.8s