12 KiB
CyberSim Scenario Format v1.0 — Specification & Author Guide
1. Overview
The CyberSim Scenario Format v1.0 is a declarative, portable, JSON-based format for authoring simulation scenarios in CyberSim OS. It enables scenario designers to construct complete cybersecurity training experiences without writing or modifying CyberSim OS code.
A scenario package defines:
- Simulation identity & metadata (title, description, duration, learner profile, target score)
- Workplace context (people, organizations, domains, department hierarchies)
- Simulated objects (emails, web pages, intranet sites, forms, documents, spreadsheets, files)
- Scheduled & reactive events (timed triggers, action-driven consequences, delays, repetitions)
- Behavior vocabulary & actions (app launches, notifications, alert generation, inbox deliveries)
- Multi-axis behavioral evaluation (scoring rules, pedagogical findings, after-action feedback)
2. Package Structure
A scenario is stored within a self-contained directory:
scenarios/my-scenario/
├── scenario.json # Main manifest & scenario definition (required)
├── assets/ # Local attachments & assets (optional)
└── README.md # Scenario author notes & changelog (optional)
For large scenarios, sub-collections can optionally be split across multiple files using $ref: references:
{
"formatVersion": "1.0",
"id": "enterprise-phish-triage",
"people": "$ref:people.json",
"messages": "$ref:messages.json"
}
Note: All referenced files must reside within the scenario directory tree. Paths with .., absolute paths, and external URL schemes are rejected by the loader.
3. Top-Level Manifest Reference
| Property | Type | Required | Description |
|---|---|---|---|
formatVersion |
string |
Yes | Must be "1.0". |
id |
string |
Yes | Unique identifier (lowercase alphanumeric and hyphens). |
version |
string |
Yes | Semantic version of the scenario (e.g. "1.0.0"). |
title |
string |
Yes | Human-readable title displayed in the launcher and AAR. |
description |
string |
Yes | Overview of the simulation setting and primary challenges. |
durationSeconds |
number |
Yes | Expected run time in seconds (e.g. 900). |
mode |
string |
Yes | Instruction mode: "guided", "practice", or "assessment". |
entryEvent |
string |
Yes | ID of the event executed at scenario start. |
passingScore |
number |
Yes | Minimum score required to pass and earn a certificate (0–100). |
supportedLocales |
array |
No | List of supported language codes (e.g. ["en", "es"]). |
login |
object |
No | Network login metadata: { networkName, networkDescription, networkIcon }. |
engine |
object |
No | Minimum engine version requirements ({ "minimumVersion": "0.2.0" }). |
learner |
object |
No | Initial persona: { name, role, email, department }. |
organizations |
array |
No | List of simulated organizations & trusted domain lists. |
people |
array |
No | Simulated personas and contact directory. |
objectives |
array |
No | Visible shift objectives shown in Start Menu and UI. |
messages |
array |
No | Simulated email messages (Inlook). |
pages |
array |
No | Simulated web pages and browser targets (Navigator). |
files |
array |
No | Virtual filesystem items (Documents, Downloads, Shared). |
notifications |
array |
No | Pre-configured desktop toast notification templates. |
alerts |
array |
No | Security Center alert definitions. |
events |
array |
Yes | Declarative triggers and action lists. |
scoring |
object |
Yes | Category declarations and rule definitions. |
findings |
array |
No | Predefined pedagogical findings and deductions. |
feedback |
array |
No | Performance-conditional after-action remarks. |
completion |
object |
No | Finalization criteria and certificate issuance rules. |
4. Object Types
4.1 Organizations (organizations[])
Defines trusted enterprise domains and third-party corporate entities.
{
"id": "nexacore",
"name": "NexaCore Technologies",
"domains": ["nexacore.internal"],
"departments": ["Finance", "Information Security", "IT Helpdesk"],
"securityContacts": ["[email protected]"]
}
4.2 People (people[])
Defines characters and email identities.
{
"id": "alex-rivera",
"name": "Alex Rivera",
"role": "Chief Information Security Officer",
"email": "[email protected]",
"organization": "nexacore",
"department": "Information Security"
}
4.3 Messages (messages[])
Defines email communications in Inlook.
{
"id": "email_phish_pwreset",
"sender": "NexaCore IT Helpdesk",
"rfcSender": "[email protected]",
"recipient": "[email protected]",
"subject": "URGENT: Password Verification Required",
"date": "09:05 AM",
"folder": "pending",
"unread": true,
"body": "Please confirm credentials at: <a class=\"inlook-msg-link\" data-url=\"http://login-nexac0re-portal.com/auth/login\" data-display=\"https://intranet.nexacore.internal/sso\">https://intranet.nexacore.internal/sso</a>",
"links": [
{
"displayText": "https://intranet.nexacore.internal/sso",
"actualUrl": "http://login-nexac0re-portal.com/auth/login"
}
],
"attachments": []
}
4.4 Pages (pages[])
Defines intranet and external web destinations in Navigator. Form submissions are bound declaratively by ID.
{
"url": "http://login-nexac0re-portal.com/auth/login",
"title": "NexaCore Identity SSO",
"isSecure": false,
"isPhishing": true,
"content": "<div class=\"phish-card\"><form id=\"phish-login-form\">...</form></div>",
"forms": [
{
"id": "phish-login-form",
"onSubmit": {
"emitEvent": "NAV_FORM_SUBMITTED",
"target": "phish_login_form",
"response": {
"type": "pageContent",
"content": "<div>Account Verification Complete</div>"
}
}
}
]
}
4.5 Files (files[])
Virtual files accessible in the Files app and DocViewer.
{
"id": "file_budget",
"name": "Q3_Budget_Forecast.xlsx",
"type": "spreadsheet",
"folder": "Documents",
"size": "48 KB",
"date": "2026-08-20",
"content": {
"title": "Q3 Budget Forecast",
"headers": ["Category", "Q1", "Q2", "Q3"],
"rows": [["Infrastructure", "$142k", "$155k", "$168k"]]
}
}
5. Event System & Behavior Vocabulary
Events are evaluated deterministically on each engine cycle.
{
"id": "deliver-phish-email",
"when": { "elapsedSeconds": 30 },
"actions": [
{ "type": "mail.deliver", "message": "email_phish_pwreset" },
{ "type": "desktop.notify", "title": "Inlook Mail", "body": "New message received.", "type": "info" }
]
}
5.1 Condition Triggers (when)
{ "scenarioStart": true }— Triggers on the initial simulation tick.{ "elapsedSeconds": 45 }— Triggers whensimSeconds >= 45.{ "actionOccurred": { "type": "EMAIL_OPENED", "target": "email_phish" } }— Triggers on user action.{ "stateEquals": { "object": "inlook", "key": "selected", "value": "email_1" } }— Triggers on state match.{ "all": [ condition1, condition2 ] }— Logical AND.{ "any": [ condition1, condition2 ] }— Logical OR.{ "not": condition }— Logical NOT.
5.2 Behavior Vocabulary (Action Whitelist)
Desktop Actions
desktop.notify— Toast alert ({ title, body, type, timeout, icon }or{ notification: "notif_id" }).desktop.openApp— Launch app ({ app: "inlook" | "navigator" | "files" | "security_center" | "docviewer" }).desktop.focusApp— Bring window to focus.desktop.setBadge— Update taskbar/tab badge counter.desktop.endScenario— Complete the session and launch AAR.
Mail Actions
mail.deliver— Deliver message to Inlook inbox ({ message: "msg_id" }).mail.updateMessage— Update message attributes.
Navigator Actions
navigator.open— Open browser to specified URL ({ url: "http://..." }).navigator.redirect— Redirect current browser tab.
Files Actions
files.create— Dynamically inject file into virtual filesystem.files.open— Open document in DocViewer ({ fileId: "file_id" }).
Security Center Actions
security.addAlert— Add security notification item ({ alert: "alert_id" }or inline object).security.updateStatus— Change dashboard threat state.
Evaluation Actions
evaluation.addFinding— Record a pedagogical finding ({ finding: "finding_id" }).evaluation.setState— Set custom runtime state variable.evaluation.completeObjective— Mark a shift task completed ({ objective: "obj_id" }).evaluation.awardPoints— Adjust category points ({ category: "cat_id", points: 10 }).
6. Scoring & Findings Pipeline
Scoring is computed at the end of the shift or on-demand:
{
"scoring": {
"categories": [
{ "id": "threat-detection", "label": "Threat Detection", "maxPoints": 20, "startingPoints": 0 },
{ "id": "safe-handling", "label": "Safe Handling", "maxPoints": 15, "startingPoints": 15 }
],
"rules": [
{
"id": "opened-phish-email",
"condition": { "actionOccurred": { "type": "EMAIL_OPENED", "target": "email_phish_pwreset" } },
"award": { "category": "threat-detection", "points": 10 },
"timeline": { "type": "positive", "text": "Identified and reviewed the password reset notice." }
},
{
"id": "submitted-phish-credentials",
"condition": { "actionOccurred": { "type": "NAV_FORM_SUBMITTED", "target": "phish_login_form" } },
"award": { "category": "safe-handling", "points": -10 },
"timeline": { "type": "critical", "text": "Entered password on untrusted external portal." },
"feedback": "CRITICAL: Never enter credentials into untrusted external sites."
}
]
}
}
7. Cryptographic Fingerprinting & Certificates
When a scenario is loaded, the engine computes a canonical SHA-256 hash across all evaluation-relevant elements (messages, pages, files, events, scoring rules, findings).
Upon completion with a passing score (totalScore >= passingScore), the learner may claim an exportable *.cybercert JSON record. The certificate embeds the scenario fingerprint and an integrity hash that can be verified offline via verify.html.
8. Authoring Diagnostics & Development Mode
To inspect and test scenarios during development, add ?dev=true to the URL:
http://127.0.0.1:8080?scenario=scenarios/my-scenario/scenario.json&dev=true
The diagnostics overlay provides:
- Live structural & semantic validation errors
- Event trigger states and scheduled timers
- Current category score breakdowns and recorded findings
- Scenario SHA-256 fingerprint calculations
9. Scenario Localization & Personalization
9.1 Declaring Supported Locales & Login Presentation
Scenarios declare their supported language codes in scenario.json:
{
"formatVersion": "1.0",
"id": "my-scenario",
"supportedLocales": ["en", "es"],
"login": {
"networkName": "ACME Corporate Network",
"networkDescription": "Simulated Corporate Workplace",
"networkIcon": "corporate"
}
}
9.2 Providing Scenario Translations (locales/<lang>.json)
Translations for scenario-specific content are stored within the scenario package under locales/:
scenarios/my-scenario/
├── scenario.json
└── locales/
├── en.json
└── es.json
The translation catalog can override text properties across messages, pages, files, notifications, alerts, findings, and feedback:
{
"title": "Turno Operativo y Concientización",
"messages": {
"email_welcome": {
"sender": "Morgan Chen (Vicepresidente)",
"subject": "Bienvenido al equipo",
"body": "Hola {{learner.firstName}},\n\n¡Bienvenido!"
}
}
}
9.3 Learner Personalization Variables
The following template variables are available for dynamic interpolation across messages, documents, web pages, notifications, and feedback:
{{learner.firstName}}: Learner's validated first name entered at login (HTML-escaped).{{learner.name}}: Learner's full name.{{learner.email}}: Learner's assigned workplace email address.{{learner.role}}: Learner's assigned workplace job title.{{company.name}}: Primary enterprise organization name.