Skip to content

Brava-Security/cloudots-dsl

Repository files navigation

Cloudots DSL

License Python Version

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.

What CloudOTS DSL Is

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.

Features

  • 📝 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

Quick Start

Installation

# 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]"

Basic Usage

  1. Validate a scenario file:
cloudots-dsl validate examples/phishing_to_exfiltration.yaml
  1. 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
  1. Convert between formats:
cloudots-dsl convert scenario.yaml --to json --out scenario.json
  1. Lint and format a scenario:
cloudots-dsl lint scenario.yaml --fix
  1. Generate an example scenario:
cloudots-dsl example --name phishing-exfil --out my_scenario.yaml

DSL Schema

Scenario Structure

A scenario consists of:

  • Metadata: Title, description, tags, and assumptions
  • Steps: Ordered sequence of attack techniques
  • Dependencies: Prerequisites between steps forming a DAG

Example Scenario

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-data

CLI Commands

cloudots-dsl validate

Validates a scenario file against the schema and custom rules.

cloudots-dsl validate scenario.yaml [--verbose]

cloudots-dsl execute

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-id

Safety Features:

  • Dry-run by default: No real changes without explicit --no-dry-run or --force
  • Interactive mode: Step-by-step confirmation with --interactive
  • Confirmation prompts: Required for non-dry-run execution
  • Detailed logging: Use --verbose for execution details

cloudots-dsl lint

Pretty-prints and normalizes scenario files.

cloudots-dsl lint scenario.yaml [--fix] [--check]

cloudots-dsl render

Generates a Graphviz DOT file from a scenario.

cloudots-dsl render scenario.yaml [--format dot] [--out graph.dot]

cloudots-dsl convert

Converts between YAML and JSON formats.

cloudots-dsl convert scenario.yaml --to json [--out scenario.json]

cloudots-dsl schema

Exports the JSON Schema for validation.

cloudots-dsl schema [--out schema.json]

cloudots-dsl example

Generates example scenarios.

cloudots-dsl example --name phishing-exfil [--out scenario.yaml]
cloudots-dsl list-examples  # Show available examples

Python API

Basic Usage

from 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")

Execution Engine

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()

Provider Adapters

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)

Schema Reference

Step Fields

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

Supported Types

Artifact Types:

  • aws_access_key, azure_sp, gcp_sa_key
  • credential, token, file, url
  • ip, domain, principal, other

Observable Kinds:

  • iam_user, role, principal
  • bucket, vm, function, database
  • ip, cidr, secret, key, other

Cloud Providers:

  • aws, azure, gcp, generic

Development

Setup Development Environment

# 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

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=cloudots_dsl --cov-report=term-missing

# Run specific test file
pytest tests/test_models.py

Code Quality

# Format code
black cloudots_dsl tests
isort cloudots_dsl tests

# Lint code
ruff check cloudots_dsl tests

# Type check
mypy cloudots_dsl

Contributing

We welcome contributions! Please follow these guidelines:

  1. Adding Scenarios: Create new example scenarios in examples/
  2. New Providers: Extend the Provider enum and add validation
  3. Validation Rules: Add custom validation logic in validate.py
  4. Bug Fixes: Include tests for any bugs fixed

Pull Request Process

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes and add tests
  4. Ensure all tests pass and code is formatted
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to your fork (git push origin feature/amazing-feature)
  7. Open a Pull Request

MITRE ATT&CK Framework

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/

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Security

⚠️ IMPORTANT SECURITY NOTICE

Version 2.0+ includes an execution engine that can make real changes to cloud resources.

Safety Guidelines

  1. Always use dry-run mode first

    • Default mode is dry-run for safety
    • Review execution plan before real execution
    • Use --verbose to see detailed actions
  2. 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
  3. Use interactive mode for sensitive operations

    • --interactive flag prompts for each step
    • Allows cancellation at any point
    • Recommended for first-time execution
  4. Provider credentials

    • Store credentials securely
    • Use IAM roles when possible
    • Rotate credentials regularly

Responsible Use

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

Disclaimer

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.

Support

Acknowledgments

  • 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.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages