Ciicerone is an enterprise-grade cybersecurity threat simulation platform that leverages Large Language Models (LLMs) to generate realistic, context-aware threat scenarios for security training, red team exercises, and compliance testing.
Ciicerone Platform
βββ Core Simulation Engine
β βββ Template Manager (YAML-based scenario definitions)
β βββ Simulation Orchestrator (Execution and workflow management)
β βββ Output Manager (Content generation and storage)
β
βββ LLM Integration Layer
β βββ Multi-Provider Support (OpenAI, Anthropic, OpenRouter, Ollama)
β βββ Connection Pooling (+40% performance improvement)
β βββ Rate Limiting & Retry Logic
β βββ Fallback & Error Handling
β
βββ Dataset Integration
β βββ PhishTank (Phishing intelligence)
β βββ Enron Email Corpus (Email communication patterns)
β βββ MITRE ATT&CK (Threat intelligence framework)
β βββ Extensible processor architecture
β
βββ Integration Layer
β βββ Microsoft 365 (Email deployment)
β βββ Proofpoint (Security platform integration)
β βββ KnowBe4 (Training platform)
β βββ Slack (Collaboration platform)
β βββ Extensible base class for custom integrations
β
βββ API & CLI Interfaces
β βββ FastAPI REST API (Enterprise integration)
β βββ Command-Line Interface (Direct usage)
β βββ Python SDK (Programmatic access)
β
βββ Safety & Compliance
βββ Content Filtering
βββ Audit Logging
βββ GDPR Compliance
βββ Ethical Use Guidelines
git clone https://github.com/ciicerone/ciicerone.git
cd Ciicerone
Windows (PowerShell):
python -m venv .venv
.\.venv\Scripts\Activate.ps1
macOS/Linux:
python -m venv .venv
source .venv/bin/activate
# Production dependencies
pip install -r requirements.txt
# Development dependencies (optional)
pip install -r requirements-dev.txt
# Set your API key as environment variable
export OPENROUTER_API_KEY="your-api-key-here"
# Edit config.yaml with your settings
nano config.yaml
Example Configuration:
llm:
provider: openrouter
openrouter:
api_key: "your-api-key-here"
model: "qwen/qwen-2.5-72b-instruct"
simulation:
output_dir: "./generated_content"
auto_save: true
logging:
level: INFO
file: "./logs/ciicerone.log"
# Check CLI availability
ciicerone --help
# Validate installation
ciicerone templates validate-all
# Test with dry run (no API calls)
ciicerone simulate -s templates/executive_phishing.yaml --dry-run
# List all available templates
ciicerone templates list
# Show template details with validation
ciicerone templates show executive_phishing --validate
# Validate all templates
ciicerone templates validate-all
# Check template ecosystem health
ciicerone templates health
# Run a simulation
ciicerone simulate -s templates/executive_phishing.yaml
# Dry run (no API calls)
ciicerone simulate -s templates/executive_phishing.yaml --dry-run
# Specify output directory
ciicerone simulate -s templates/finance_bec.yaml -o ./output/campaign_001
# Run with specific LLM provider
ciicerone simulate -s templates/it_helpdesk.yaml --provider openai
# Show current configuration
ciicerone config show
# Set configuration value
ciicerone config set llm.provider openrouter
# Validate configuration
ciicerone config validate
# List available datasets
ciicerone datasets list
# Download and process dataset
ciicerone datasets download phishtank
# Show dataset statistics
ciicerone datasets stats enron
# Update all datasets
ciicerone datasets update-all
# Start FastAPI server
ciicerone api start
# Specify host and port
ciicerone api start --host 0.0.0.0 --port 8000
# Start with auto-reload (development)
ciicerone api start --reload
Generate Threat Content:
curl -X POST "http://localhost:8000/llm/generate" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Create a phishing email targeting HR department",
"scenario_type": "phishing",
"max_tokens": 500,
"temperature": 0.7
}'
Create Scenario:
curl -X POST "http://localhost:8000/scenarios" \
-H "Content-Type: application/json" \
-d '{
"name": "Q4 Security Awareness Campaign",
"threat_type": "phishing",
"target_role": "employee",
"severity": "medium"
}'
List Templates:
curl "http://localhost:8000/templates"
API Documentation:
http://localhost:8000/docshttp://localhost:8000/redocfrom ciicerone import CiiceroneClient
# Initialize client
client = CiiceroneClient(api_key="your-api-key", provider="openrouter")
# Load and run simulation
simulation = client.load_template("templates/executive_phishing.yaml")
result = simulation.run()
# Access generated content
print(result.content)
print(result.metadata)
# Save to file
result.save("output/campaign_001.json")
config.yaml (YAML format):
# LLM Provider Configuration
llm:
provider: openrouter # Options: openrouter, openai, anthropic, ollama
openrouter:
api_key: ${OPENROUTER_API_KEY}
model: "qwen/qwen-2.5-72b-instruct"
base_url: "https://openrouter.ai/api/v1"
timeout: 120
openai:
api_key: ${OPENAI_API_KEY}
model: "gpt-4"
anthropic:
api_key: ${ANTHROPIC_API_KEY}
model: "claude-3-opus-20240229"
ollama:
base_url: "http://localhost:11434"
model: "llama3.1:70b"
# Simulation Configuration
simulation:
output_dir: "./generated_content"
auto_save: true
index_enabled: true
max_concurrent: 5
# Dataset Configuration
datasets:
storage_path: "./data"
auto_update: false
phishtank:
enabled: true
update_interval_days: 7
enron:
enabled: true
mitre_attack:
enabled: true
# Deployment Integration
deployment:
enabled: false
microsoft365:
enabled: false
tenant_id: ${M365_TENANT_ID}
client_id: ${M365_CLIENT_ID}
client_secret: ${M365_CLIENT_SECRET}
# Logging Configuration
logging:
level: INFO # DEBUG, INFO, WARNING, ERROR, CRITICAL
file: "./logs/ciicerone.log"
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
rotation: "10 MB"
retention: 30 # days
# Safety Configuration
safety:
content_filtering: true
audit_logging: true
rate_limiting:
enabled: true
requests_per_minute: 60
# LLM Provider Keys
export OPENROUTER_API_KEY="your-key-here"
export OPENAI_API_KEY="your-key-here"
export ANTHROPIC_API_KEY="your-key-here"
# Deployment Integration
export M365_TENANT_ID="your-tenant-id"
export M365_CLIENT_ID="your-client-id"
export M365_CLIENT_SECRET="your-client-secret"
# Application Settings
export CIICERONE_ENV="production"
export CIICERONE_LOG_LEVEL="INFO"
Templates define threat scenarios using YAML format:
# Template metadata
template_id: executive_phishing_v1
name: "Executive Phishing Campaign"
version: "1.0.0"
author: "Security Team"
description: "Sophisticated phishing targeting C-level executives"
# Threat classification
threat_type: phishing
severity: high
complexity: advanced
target_role: executive
# Scenario configuration
scenario:
subject_line: "Urgent: Q4 Financial Review Required"
sender_persona: "CFO Office"
urgency_level: high
social_engineering_tactics:
- authority
- urgency
- fear
context:
company_size: "enterprise"
industry: "technology"
quarter: "Q4"
content_requirements:
tone: "professional"
length: "medium"
technical_details: true
personalization: high
# LLM generation parameters
generation:
max_tokens: 800
temperature: 0.7
top_p: 0.9
# Variables for dynamic content
variables:
ceo_name: "Michael Stevens"
company_name: "TechCorp International"
deadline: "End of week"
fiscal_year: "FY2025"
# Safety controls
safety:
content_filtering: true
pii_masking: true
disclaimer_required: true
cp templates/sample_phishing_template.yaml templates/my_custom_template.yaml
template_id: my_custom_scenario
name: "My Custom Threat Scenario"
threat_type: social_engineering
# ... customize fields
ciicerone templates show my_custom_template --validate
ciicerone simulate -s templates/my_custom_template.yaml
# Build production image
docker build -t ciicerone:latest .
# Build with specific tag
docker build -t ciicerone:v1.0.0 .
# Run with environment variables
docker run -d \
--name ciicerone \
-p 8000:8000 \
-e OPENROUTER_API_KEY="your-key" \
-v $(pwd)/generated_content:/app/generated_content \
-v $(pwd)/logs:/app/logs \
ciicerone:latest
# Run with config file
docker run -d \
--name ciicerone \
-p 8000:8000 \
-v $(pwd)/config.yaml:/app/config.yaml \
-v $(pwd)/generated_content:/app/generated_content \
ciicerone:latest
docker-compose.yml:
version: '3.8'
services:
ciicerone-api:
image: ciicerone:latest
container_name: ciicerone-api
ports:
- "8000:8000"
environment:
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
- CIICERONE_ENV=production
volumes:
- ./config.yaml:/app/config.yaml:ro
- ./generated_content:/app/generated_content
- ./logs:/app/logs
- ./data:/app/data
restart: unless-stopped
ciicerone-worker:
image: ciicerone:latest
container_name: ciicerone-worker
environment:
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
volumes:
- ./config.yaml:/app/config.yaml:ro
- ./generated_content:/app/generated_content
- ./data:/app/data
command: ["python", "-m", "ciicerone.worker"]
restart: unless-stopped
Deploy:
# Start services
docker-compose up -d
# View logs
docker-compose logs -f
# Scale API instances
docker-compose up -d --scale ciicerone-api=3
# Stop services
docker-compose down
k8s/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ciicerone
labels:
app: ciicerone
spec:
replicas: 3
selector:
matchLabels:
app: ciicerone
template:
metadata:
labels:
app: ciicerone
spec:
containers:
- name: ciicerone
image: ciicerone:latest
ports:
- containerPort: 8000
env:
- name: OPENROUTER_API_KEY
valueFrom:
secretKeyRef:
name: ciicerone-secrets
key: openrouter-api-key
volumeMounts:
- name: config
mountPath: /app/config.yaml
subPath: config.yaml
- name: storage
mountPath: /app/generated_content
volumes:
- name: config
configMap:
name: ciicerone-config
- name: storage
persistentVolumeClaim:
claimName: ciicerone-pvc
---
apiVersion: v1
kind: Service
metadata:
name: ciicerone
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8000
selector:
app: ciicerone
Deploy:
# Create namespace
kubectl create namespace ciicerone
# Create secrets
kubectl create secret generic ciicerone-secrets \
--from-literal=openrouter-api-key="your-key" \
-n ciicerone
# Create config map
kubectl create configmap ciicerone-config \
--from-file=config.yaml \
-n ciicerone
# Apply deployment
kubectl apply -f k8s/ -n ciicerone
# Check status
kubectl get pods -n ciicerone
kubectl get svc -n ciicerone
# View logs
kubectl logs -f deployment/ciicerone -n ciicerone
API Key Management:
Network Security:
Access Control:
Data Protection:
Authorized Use Cases:
Prohibited Use Cases:
# Enable metrics endpoint
ciicerone api start --metrics
# Prometheus metrics available at /metrics
curl http://localhost:8000/metrics
# Health check endpoint
curl http://localhost:8000/health
We welcome contributions! Please see our Contributing Guide for details.
# Clone repository
git clone https://github.com/ciicerone/ciicerone.git
cd Ciicerone
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
# Install development dependencies
pip install -r requirements-dev.txt
# Install pre-commit hooks
pre-commit install
# Run tests
pytest
# Run code quality checks
black src/ tests/
isort src/ tests/
flake8 src/ tests/
mypy src/
git checkout -b feature/amazing-featurepytestgit commit -m 'Add amazing feature'git push origin feature/amazing-featureProblem: ciicerone: command not found
Solution: Activate virtual environment
# Windows
.\.venv\Scripts\Activate.ps1
# macOS/Linux
source .venv/bin/activate
Problem: ModuleNotFoundError
Solution: Install requirements in virtual environment
pip install -r requirements.txt
Problem: Configuration file not found
Solution: Create config.yaml from example
cp config.yaml.example config.yaml
Problem: API authentication failed
Solution: Verify API key is set
# Check environment variable
echo $OPENROUTER_API_KEY
# Or set in config.yaml
ciicerone config set llm.openrouter.api_key "your-key"
Problem: Template validation errors
Solution: Validate and fix templates
ciicerone templates show my_template --validate
ciicerone templates fix my_template
Problem: Simulation fails with timeout
Solution: Increase timeout in config
llm:
openrouter:
timeout: 180 # Increase to 180 seconds
logs/ciicerone.logciicerone config validateciicerone llm testThis project is licensed under the MIT License - see the LICENSE file for details.
Ciicerone uses the following open-source libraries:
Full license information available in LICENSE file.
Version 1.1.0 (Q1 2026):
Version 1.2.0 (Q2 2026):
Important Disclaimer
Ciicerone is a simulation tool designed exclusively for:
Users are solely responsible for ensuring compliance with all applicable laws, regulations, and organizational policies in their jurisdiction. Unauthorized use, malicious activities, or misuse of this tool is strictly prohibited and may result in legal consequences.
USE AT YOUR OWN RISK. THE AUTHORS AND CONTRIBUTORS ARE NOT LIABLE FOR ANY MISUSE OR DAMAGES.
Built for the cybersecurity community
375 followers Β· starred Feb 2026
Ciicerone is an enterprise-grade cybersecurity threat simulation platform that leverages Large Language Models (LLMs) to generate realistic, context-aware threat scenarios for security training, red team exercises, and compliance testing.
Ciicerone Platform
βββ Core Simulation Engine
β βββ Template Manager (YAML-based scenario definitions)
β βββ Simulation Orchestrator (Execution and workflow management)
β βββ Output Manager (Content generation and storage)
β
βββ LLM Integration Layer
β βββ Multi-Provider Support (OpenAI, Anthropic, OpenRouter, Ollama)
β βββ Connection Pooling (+40% performance improvement)
β βββ Rate Limiting & Retry Logic
β βββ Fallback & Error Handling
β
βββ Dataset Integration
β βββ PhishTank (Phishing intelligence)
β βββ Enron Email Corpus (Email communication patterns)
β βββ MITRE ATT&CK (Threat intelligence framework)
β βββ Extensible processor architecture
β
βββ Integration Layer
β βββ Microsoft 365 (Email deployment)
β βββ Proofpoint (Security platform integration)
β βββ KnowBe4 (Training platform)
β βββ Slack (Collaboration platform)
β βββ Extensible base class for custom integrations
β
βββ API & CLI Interfaces
β βββ FastAPI REST API (Enterprise integration)
β βββ Command-Line Interface (Direct usage)
β βββ Python SDK (Programmatic access)
β
βββ Safety & Compliance
βββ Content Filtering
βββ Audit Logging
βββ GDPR Compliance
βββ Ethical Use Guidelines
git clone https://github.com/ciicerone/ciicerone.git
cd Ciicerone
Windows (PowerShell):
python -m venv .venv
.\.venv\Scripts\Activate.ps1
macOS/Linux:
python -m venv .venv
source .venv/bin/activate
# Production dependencies
pip install -r requirements.txt
# Development dependencies (optional)
pip install -r requirements-dev.txt
# Set your API key as environment variable
export OPENROUTER_API_KEY="your-api-key-here"
# Edit config.yaml with your settings
nano config.yaml
Example Configuration:
llm:
provider: openrouter
openrouter:
api_key: "your-api-key-here"
model: "qwen/qwen-2.5-72b-instruct"
simulation:
output_dir: "./generated_content"
auto_save: true
logging:
level: INFO
file: "./logs/ciicerone.log"
# Check CLI availability
ciicerone --help
# Validate installation
ciicerone templates validate-all
# Test with dry run (no API calls)
ciicerone simulate -s templates/executive_phishing.yaml --dry-run
# List all available templates
ciicerone templates list
# Show template details with validation
ciicerone templates show executive_phishing --validate
# Validate all templates
ciicerone templates validate-all
# Check template ecosystem health
ciicerone templates health
# Run a simulation
ciicerone simulate -s templates/executive_phishing.yaml
# Dry run (no API calls)
ciicerone simulate -s templates/executive_phishing.yaml --dry-run
# Specify output directory
ciicerone simulate -s templates/finance_bec.yaml -o ./output/campaign_001
# Run with specific LLM provider
ciicerone simulate -s templates/it_helpdesk.yaml --provider openai
# Show current configuration
ciicerone config show
# Set configuration value
ciicerone config set llm.provider openrouter
# Validate configuration
ciicerone config validate
# List available datasets
ciicerone datasets list
# Download and process dataset
ciicerone datasets download phishtank
# Show dataset statistics
ciicerone datasets stats enron
# Update all datasets
ciicerone datasets update-all
# Start FastAPI server
ciicerone api start
# Specify host and port
ciicerone api start --host 0.0.0.0 --port 8000
# Start with auto-reload (development)
ciicerone api start --reload
Generate Threat Content:
curl -X POST "http://localhost:8000/llm/generate" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Create a phishing email targeting HR department",
"scenario_type": "phishing",
"max_tokens": 500,
"temperature": 0.7
}'
Create Scenario:
curl -X POST "http://localhost:8000/scenarios" \
-H "Content-Type: application/json" \
-d '{
"name": "Q4 Security Awareness Campaign",
"threat_type": "phishing",
"target_role": "employee",
"severity": "medium"
}'
List Templates:
curl "http://localhost:8000/templates"
API Documentation:
http://localhost:8000/docshttp://localhost:8000/redocfrom ciicerone import CiiceroneClient
# Initialize client
client = CiiceroneClient(api_key="your-api-key", provider="openrouter")
# Load and run simulation
simulation = client.load_template("templates/executive_phishing.yaml")
result = simulation.run()
# Access generated content
print(result.content)
print(result.metadata)
# Save to file
result.save("output/campaign_001.json")
config.yaml (YAML format):
# LLM Provider Configuration
llm:
provider: openrouter # Options: openrouter, openai, anthropic, ollama
openrouter:
api_key: ${OPENROUTER_API_KEY}
model: "qwen/qwen-2.5-72b-instruct"
base_url: "https://openrouter.ai/api/v1"
timeout: 120
openai:
api_key: ${OPENAI_API_KEY}
model: "gpt-4"
anthropic:
api_key: ${ANTHROPIC_API_KEY}
model: "claude-3-opus-20240229"
ollama:
base_url: "http://localhost:11434"
model: "llama3.1:70b"
# Simulation Configuration
simulation:
output_dir: "./generated_content"
auto_save: true
index_enabled: true
max_concurrent: 5
# Dataset Configuration
datasets:
storage_path: "./data"
auto_update: false
phishtank:
enabled: true
update_interval_days: 7
enron:
enabled: true
mitre_attack:
enabled: true
# Deployment Integration
deployment:
enabled: false
microsoft365:
enabled: false
tenant_id: ${M365_TENANT_ID}
client_id: ${M365_CLIENT_ID}
client_secret: ${M365_CLIENT_SECRET}
# Logging Configuration
logging:
level: INFO # DEBUG, INFO, WARNING, ERROR, CRITICAL
file: "./logs/ciicerone.log"
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
rotation: "10 MB"
retention: 30 # days
# Safety Configuration
safety:
content_filtering: true
audit_logging: true
rate_limiting:
enabled: true
requests_per_minute: 60
# LLM Provider Keys
export OPENROUTER_API_KEY="your-key-here"
export OPENAI_API_KEY="your-key-here"
export ANTHROPIC_API_KEY="your-key-here"
# Deployment Integration
export M365_TENANT_ID="your-tenant-id"
export M365_CLIENT_ID="your-client-id"
export M365_CLIENT_SECRET="your-client-secret"
# Application Settings
export CIICERONE_ENV="production"
export CIICERONE_LOG_LEVEL="INFO"
Templates define threat scenarios using YAML format:
# Template metadata
template_id: executive_phishing_v1
name: "Executive Phishing Campaign"
version: "1.0.0"
author: "Security Team"
description: "Sophisticated phishing targeting C-level executives"
# Threat classification
threat_type: phishing
severity: high
complexity: advanced
target_role: executive
# Scenario configuration
scenario:
subject_line: "Urgent: Q4 Financial Review Required"
sender_persona: "CFO Office"
urgency_level: high
social_engineering_tactics:
- authority
- urgency
- fear
context:
company_size: "enterprise"
industry: "technology"
quarter: "Q4"
content_requirements:
tone: "professional"
length: "medium"
technical_details: true
personalization: high
# LLM generation parameters
generation:
max_tokens: 800
temperature: 0.7
top_p: 0.9
# Variables for dynamic content
variables:
ceo_name: "Michael Stevens"
company_name: "TechCorp International"
deadline: "End of week"
fiscal_year: "FY2025"
# Safety controls
safety:
content_filtering: true
pii_masking: true
disclaimer_required: true
cp templates/sample_phishing_template.yaml templates/my_custom_template.yaml
template_id: my_custom_scenario
name: "My Custom Threat Scenario"
threat_type: social_engineering
# ... customize fields
ciicerone templates show my_custom_template --validate
ciicerone simulate -s templates/my_custom_template.yaml
# Build production image
docker build -t ciicerone:latest .
# Build with specific tag
docker build -t ciicerone:v1.0.0 .
# Run with environment variables
docker run -d \
--name ciicerone \
-p 8000:8000 \
-e OPENROUTER_API_KEY="your-key" \
-v $(pwd)/generated_content:/app/generated_content \
-v $(pwd)/logs:/app/logs \
ciicerone:latest
# Run with config file
docker run -d \
--name ciicerone \
-p 8000:8000 \
-v $(pwd)/config.yaml:/app/config.yaml \
-v $(pwd)/generated_content:/app/generated_content \
ciicerone:latest
docker-compose.yml:
version: '3.8'
services:
ciicerone-api:
image: ciicerone:latest
container_name: ciicerone-api
ports:
- "8000:8000"
environment:
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
- CIICERONE_ENV=production
volumes:
- ./config.yaml:/app/config.yaml:ro
- ./generated_content:/app/generated_content
- ./logs:/app/logs
- ./data:/app/data
restart: unless-stopped
ciicerone-worker:
image: ciicerone:latest
container_name: ciicerone-worker
environment:
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
volumes:
- ./config.yaml:/app/config.yaml:ro
- ./generated_content:/app/generated_content
- ./data:/app/data
command: ["python", "-m", "ciicerone.worker"]
restart: unless-stopped
Deploy:
# Start services
docker-compose up -d
# View logs
docker-compose logs -f
# Scale API instances
docker-compose up -d --scale ciicerone-api=3
# Stop services
docker-compose down
k8s/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ciicerone
labels:
app: ciicerone
spec:
replicas: 3
selector:
matchLabels:
app: ciicerone
template:
metadata:
labels:
app: ciicerone
spec:
containers:
- name: ciicerone
image: ciicerone:latest
ports:
- containerPort: 8000
env:
- name: OPENROUTER_API_KEY
valueFrom:
secretKeyRef:
name: ciicerone-secrets
key: openrouter-api-key
volumeMounts:
- name: config
mountPath: /app/config.yaml
subPath: config.yaml
- name: storage
mountPath: /app/generated_content
volumes:
- name: config
configMap:
name: ciicerone-config
- name: storage
persistentVolumeClaim:
claimName: ciicerone-pvc
---
apiVersion: v1
kind: Service
metadata:
name: ciicerone
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8000
selector:
app: ciicerone
Deploy:
# Create namespace
kubectl create namespace ciicerone
# Create secrets
kubectl create secret generic ciicerone-secrets \
--from-literal=openrouter-api-key="your-key" \
-n ciicerone
# Create config map
kubectl create configmap ciicerone-config \
--from-file=config.yaml \
-n ciicerone
# Apply deployment
kubectl apply -f k8s/ -n ciicerone
# Check status
kubectl get pods -n ciicerone
kubectl get svc -n ciicerone
# View logs
kubectl logs -f deployment/ciicerone -n ciicerone
API Key Management:
Network Security:
Access Control:
Data Protection:
Authorized Use Cases:
Prohibited Use Cases:
# Enable metrics endpoint
ciicerone api start --metrics
# Prometheus metrics available at /metrics
curl http://localhost:8000/metrics
# Health check endpoint
curl http://localhost:8000/health
We welcome contributions! Please see our Contributing Guide for details.
# Clone repository
git clone https://github.com/ciicerone/ciicerone.git
cd Ciicerone
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
# Install development dependencies
pip install -r requirements-dev.txt
# Install pre-commit hooks
pre-commit install
# Run tests
pytest
# Run code quality checks
black src/ tests/
isort src/ tests/
flake8 src/ tests/
mypy src/
git checkout -b feature/amazing-featurepytestgit commit -m 'Add amazing feature'git push origin feature/amazing-featureProblem: ciicerone: command not found
Solution: Activate virtual environment
# Windows
.\.venv\Scripts\Activate.ps1
# macOS/Linux
source .venv/bin/activate
Problem: ModuleNotFoundError
Solution: Install requirements in virtual environment
pip install -r requirements.txt
Problem: Configuration file not found
Solution: Create config.yaml from example
cp config.yaml.example config.yaml
Problem: API authentication failed
Solution: Verify API key is set
# Check environment variable
echo $OPENROUTER_API_KEY
# Or set in config.yaml
ciicerone config set llm.openrouter.api_key "your-key"
Problem: Template validation errors
Solution: Validate and fix templates
ciicerone templates show my_template --validate
ciicerone templates fix my_template
Problem: Simulation fails with timeout
Solution: Increase timeout in config
llm:
openrouter:
timeout: 180 # Increase to 180 seconds
logs/ciicerone.logciicerone config validateciicerone llm testThis project is licensed under the MIT License - see the LICENSE file for details.
Ciicerone uses the following open-source libraries:
Full license information available in LICENSE file.
Version 1.1.0 (Q1 2026):
Version 1.2.0 (Q2 2026):
Important Disclaimer
Ciicerone is a simulation tool designed exclusively for:
Users are solely responsible for ensuring compliance with all applicable laws, regulations, and organizational policies in their jurisdiction. Unauthorized use, malicious activities, or misuse of this tool is strictly prohibited and may result in legal consequences.
USE AT YOUR OWN RISK. THE AUTHORS AND CONTRIBUTORS ARE NOT LIABLE FOR ANY MISUSE OR DAMAGES.
Built for the cybersecurity community
375 followers Β· starred Feb 2026