A declarative Domain-Specific Language (DSL) for describing and executing cloud attack scenarios. CloudOTS DSL provides a machine-readable schema, parser, validator, execution engine, and CLI tools for working with cloud security scenarios based on the MITRE ATT&CK framework.
CloudOTS DSL IS:
- ✅ A standardized format for describing cloud attack scenarios
- ✅ A validation toolkit ensuring scenarios are well-formed
- ✅ A visualization tool for scenario dependencies and flow
- ✅ An execution engine with safety features
- ✅ A converter between YAML and JSON formats
- ✅ Open-source and extensible
USE WITH CAUTION:
⚠️ The execution engine can make real changes to cloud resources⚠️ Always use dry-run mode first to understand what will happen⚠️ Ensure you have proper permissions and authorization⚠️ Never run against production systems without approval
This tool is designed for authorized security testing, training, and simulation purposes only.
- 📝 Declarative YAML/JSON DSL for cloud attack scenarios
- ✅ Schema validation with detailed error messages
- 🔍 MITRE ATT&CK integration with technique validation
- 📊 Graph visualization with DAG validation and DOT export
- 🔄 Format conversion between YAML and JSON
- 🎨 Pretty-printing and linting capabilities
- 🚀 Type-safe Python API with Pydantic models
- 📦 Ready-to-use examples for common scenarios
# Install from source
git clone https://github.com/Brava-Security/cloudots-dsl.git
cd cloudots-dsl
pip install -e .
# Or install with development dependencies
pip install -e ".[dev]"- Validate a scenario file:
cloudots-dsl validate examples/phishing_to_exfiltration.yaml- Render a scenario as a graph:
cloudots-dsl render examples/phishing_to_exfiltration.yaml --out graph.dot
# Visualize with Graphviz
dot -Tpng graph.dot -o graph.png- Convert between formats:
cloudots-dsl convert scenario.yaml --to json --out scenario.json- Lint and format a scenario:
cloudots-dsl lint scenario.yaml --fix- Generate an example scenario:
cloudots-dsl example --name phishing-exfil --out my_scenario.yamlA scenario consists of:
- Metadata: Title, description, tags, and assumptions
- Steps: Ordered sequence of attack techniques
- Dependencies: Prerequisites between steps forming a DAG
schema_version: "1.0"
scenario: "Phishing to Data Exfiltration"
description: >
Attacker compromises a user through phishing and exfiltrates data
tags:
- aws
- exfiltration
- phishing
steps:
- id: phishing
name: Initial Access via Phishing
technique: T1566.001
tactic: initial_access
artifacts:
- type: aws_access_key
value: AKIAEXAMPLE
sensitivity: high
- id: assume-role
name: Assume Administrative Role
technique: T1078.004
tactic: privilege_escalation
prereqs: [phishing]
action:
provider: aws
service: sts
call: AssumeRole
params:
role_arn: arn:aws:iam::111111111111:role/AdminRole
- id: exfiltrate
name: Exfiltrate S3 Data
technique: T1537
tactic: exfiltration
prereqs: [assume-role]
action:
provider: aws
service: s3
call: GetObject
observables:
- kind: bucket
value: sensitive-dataValidates a scenario file against the schema and custom rules.
cloudots-dsl validate scenario.yaml [--verbose]Execute a scenario with safety features (dry-run by default).
# Dry-run mode (default, safe)
cloudots-dsl execute scenario.yaml
# Execute with verbose output
cloudots-dsl execute scenario.yaml --verbose
# Interactive mode with step-by-step confirmation
cloudots-dsl execute scenario.yaml --interactive
# Generate execution report
cloudots-dsl execute scenario.yaml --report report.json
cloudots-dsl execute scenario.yaml --report report.md --report-format markdown
# DANGER: Real execution (requires confirmation)
cloudots-dsl execute scenario.yaml --no-dry-run
cloudots-dsl execute scenario.yaml --force # Same as --no-dry-run
# Provider configuration
cloudots-dsl execute scenario.yaml --aws-profile myprofile
cloudots-dsl execute scenario.yaml --azure-tenant tenant-id
cloudots-dsl execute scenario.yaml --gcp-project project-idSafety Features:
- Dry-run by default: No real changes without explicit
--no-dry-runor--force - Interactive mode: Step-by-step confirmation with
--interactive - Confirmation prompts: Required for non-dry-run execution
- Detailed logging: Use
--verbosefor execution details
Pretty-prints and normalizes scenario files.
cloudots-dsl lint scenario.yaml [--fix] [--check]Generates a Graphviz DOT file from a scenario.
cloudots-dsl render scenario.yaml [--format dot] [--out graph.dot]Converts between YAML and JSON formats.
cloudots-dsl convert scenario.yaml --to json [--out scenario.json]Exports the JSON Schema for validation.
cloudots-dsl schema [--out schema.json]Generates example scenarios.
cloudots-dsl example --name phishing-exfil [--out scenario.yaml]
cloudots-dsl list-examples # Show available examplesfrom cloudots_dsl import parse_scenario, validate_scenario, dump_scenario
from cloudots_dsl.graph import render_dot
# Parse a scenario
scenario = parse_scenario("path/to/scenario.yaml")
# Validate
findings = validate_scenario(scenario)
for finding in findings:
print(f"{finding.level}: {finding.message}")
# Render as graph
dot_output = render_dot(scenario)
# Convert formats
json_output = dump_scenario(scenario, format="json")from cloudots_dsl import parse_scenario, execute_scenario
from cloudots_dsl.hooks import LoggingHook, InteractiveHook
from cloudots_dsl.report import ExecutionReport
# Parse scenario
scenario = parse_scenario("scenario.yaml")
# Execute with dry-run (safe)
context = execute_scenario(
scenario=scenario,
dry_run=True,
verbose=True,
)
# Check results
summary = context.get_execution_summary()
print(f"Successful: {summary['successful']}/{summary['total_steps']}")
# Generate report
report = ExecutionReport(context)
report.save_report(Path("report.json"), format="json")
# Custom execution with hooks
from cloudots_dsl.executor import ScenarioExecutor
executor = ScenarioExecutor(
scenario=scenario,
dry_run=True,
interactive=False,
)
# Add custom hooks
executor.hook_manager.add_hook(LoggingHook(verbose=True))
executor.hook_manager.add_hook(InteractiveHook())
# Execute
context = executor.execute()from cloudots_dsl.providers import get_provider_adapter
from cloudots_dsl.context import ExecutionContext
# Create context with provider config
context = ExecutionContext(
scenario_id="test",
started_at=datetime.now(),
provider_config={
"aws": {"profile": "myprofile"},
"azure": {"tenant_id": "tenant-123"},
}
)
# Get provider adapter
aws_adapter = get_provider_adapter("aws", context)
# Execute action (dry-run)
from cloudots_dsl.models import Action, Provider
action = Action(
provider=Provider.AWS,
service="s3",
call="ListBuckets",
)
result = aws_adapter.execute_action(action)| Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Unique identifier (kebab-case or snake_case) |
technique |
string | ✅ | MITRE ATT&CK technique ID (e.g., T1566.001) |
name |
string | ❌ | Human-readable name |
tactic |
string | ❌ | MITRE ATT&CK tactic |
description |
string | ❌ | Detailed description |
prereqs |
list[string] | ❌ | Prerequisite step IDs |
artifacts |
list[Artifact] | ❌ | Generated artifacts |
action |
Action | ❌ | Cloud provider action |
observables |
list[Observable] | ❌ | Observable entities |
notes |
string | ❌ | Additional notes |
Artifact Types:
aws_access_key,azure_sp,gcp_sa_keycredential,token,file,urlip,domain,principal,other
Observable Kinds:
iam_user,role,principalbucket,vm,function,databaseip,cidr,secret,key,other
Cloud Providers:
aws,azure,gcp,generic
# Clone the repository
git clone https://github.com/Brava-Security/cloudots-dsl.git
cd cloudots-dsl
# Install with dev dependencies
pip install -e ".[dev]"
# Install pre-commit hooks
pre-commit install# Run all tests
pytest
# Run with coverage
pytest --cov=cloudots_dsl --cov-report=term-missing
# Run specific test file
pytest tests/test_models.py# Format code
black cloudots_dsl tests
isort cloudots_dsl tests
# Lint code
ruff check cloudots_dsl tests
# Type check
mypy cloudots_dslWe welcome contributions! Please follow these guidelines:
- Adding Scenarios: Create new example scenarios in
examples/ - New Providers: Extend the
Providerenum and add validation - Validation Rules: Add custom validation logic in
validate.py - Bug Fixes: Include tests for any bugs fixed
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes and add tests
- Ensure all tests pass and code is formatted
- Commit your changes (
git commit -m 'Add amazing feature') - Push to your fork (
git push origin feature/amazing-feature) - Open a Pull Request
This tool uses MITRE ATT&CK® technique identifiers for categorizing attack steps. We validate the format of technique IDs (e.g., T1566.001) but do not include or license the ATT&CK content itself.
For more information about MITRE ATT&CK, visit: https://attack.mitre.org/
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Version 2.0+ includes an execution engine that can make real changes to cloud resources.
-
Always use dry-run mode first
- Default mode is dry-run for safety
- Review execution plan before real execution
- Use
--verboseto see detailed actions
-
Authorization required
- Only run against systems you own or have explicit permission to test
- Ensure proper IAM permissions are configured
- Never run against production without approval
-
Use interactive mode for sensitive operations
--interactiveflag prompts for each step- Allows cancellation at any point
- Recommended for first-time execution
-
Provider credentials
- Store credentials securely
- Use IAM roles when possible
- Rotate credentials regularly
This tool is intended for:
- ✅ Authorized security testing
- ✅ Training and education
- ✅ Incident response simulation
- ✅ Security control validation
This tool is NOT for:
- ❌ Unauthorized access or attacks
- ❌ Production systems without approval
- ❌ Violating terms of service
- ❌ Any illegal activities
The authors and contributors are not responsible for any misuse or damage caused by this tool. Users are solely responsible for ensuring they have proper authorization and following all applicable laws and regulations.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- MITRE ATT&CK® framework for the technique taxonomy
- The cloud security community for scenario contributions
- Open source contributors
Disclaimer: This tool is provided as-is for educational purposes. The authors and contributors are not responsible for any misuse or damage caused by this tool.