A comprehensive Detection as Code (DaC) repository that converts vendor-agnostic Sigma detection rules into Wazuh-compatible XML format with automated CI/CD pipelines.
Status: Production Ready | License: NopelCyber | Wazuh Version: 4.7.0+
This repository implements a complete Detection as Code workflow:
Sigma Rules (YAML) β Validate β Convert to Wazuh XML β Deploy to Wazuh Manager
- β Vendor-Agnostic Detection Rules - Write once in Sigma format, deploy anywhere
- β Automated Conversion - Python-based converter transforms Sigma β Wazuh XML
- β Continuous Integration - GitHub Actions validates, converts, and deploys automatically
- β REST API Deployment - JWT token-based secure deployment to Wazuh Manager
- β Rule Versioning - Complete git history of all detection rules
- β Easy Maintenance - Never manually edit converted rules
detection-as-code/
βββ .github/
β βββ workflows/ # GitHub Actions CI/CD pipelines
β βββ validate-rules.yml
β βββ convert-rules.yml
β βββ deploy-rules.yml
βββ sigma-rules/ # Source Sigma detection rules (vendor-agnostic)
β βββ process_creation/
β βββ file_access/
β βββ registry_event/
β βββ network_connection/
βββ converted-rules/
β βββ wazuh/
β βββ rules/ # Auto-generated Wazuh XML rules (DO NOT EDIT)
β βββ decoders/
βββ converters/
β βββ sigma-to-wazuh.py # Python converter script
βββ scripts/
β βββ validate.sh # Validate Sigma rules syntax
β βββ convert-all.sh # Convert Sigma to Wazuh XML
β βββ deploy.sh # Deploy rules to Wazuh Manager
βββ tests/
β βββ test_rule_coverage.py # Unit tests for rule conversion
βββ docs/
β βββ README.md
β βββ contributing.md
β βββ rule-writing-guide.md
βββ requirements.txt # Python dependencies
βββ docker-compose.yml # Local Wazuh testing environment
βββ .gitignore
- Python 3.7+
- Git
- Bash shell
- Curl (for API calls)
- Wazuh Manager instance (4.7.0+)
git clone https://github.com/yourusername/detection-as-code.git
cd detection-as-codepip install -r requirements.txtSet environment variables for deployment:
export WAZUH_MANAGER_HOST="your-wazuh-url.com"
export WAZUH_JWT_TOKEN="your-jwt-token-here"Or create a .env file:
cat > .env << 'EOF'
WAZUH_MANAGER_HOST=your-wazuh-url.com
WAZUH_JWT_TOKEN=your-jwt-token-here
EOF
source .env# Validate all Sigma rules
bash scripts/validate.sh
# Convert Sigma rules to Wazuh XML
bash scripts/convert-all.sh
# Deploy to Wazuh Manager
bash scripts/deploy.sh# Authenticate to Wazuh API
curl -k -X POST "https://your-wazuh-url.com:55000/security/user/authenticate" \
--header "Content-Type: application/json" \
-d '{"username":"admin","password":"your_password"}'
# Response includes "token" field - copy and use itCreate a new file sigma-rules/process_creation/my_rule.yml:
title: Suspicious PowerShell Execution
id: 12345678-1234-1234-1234-123456789012
status: test
description: Detects suspicious PowerShell command execution
logsource:
product: windows
category: process_creation
detection:
selection:
CommandLine|contains:
- 'powershell.exe'
- 'Invoke-WebRequest'
Image|endswith:
- 'cmd.exe'
- 'powershell.exe'
condition: selection
falsepositives:
- System administrators
- Automated scripts
level: high
tags:
- attack.execution
- attack.t1059# 1. Validate YAML syntax and schema
bash scripts/validate.sh
# Output should show:
# π Validating Sigma rules...
# β
All validations passed!
# 2. Convert Sigma to Wazuh XML
bash scripts/convert-all.sh
# Output should show:
# π Converting Sigma rules to Wazuh format...
# β Converted: Suspicious PowerShell Execution
# β ./converted-rules/wazuh/rules/suspicious_powershell_execution.xml
# β
Conversion complete!
# 3. Deploy to Wazuh Manager
bash scripts/deploy.sh
# Output should show:
# π Deploying rules to Wazuh Manager via API...
# Deploying rules to: https://your-wazuh-url.com:55000
#
# π€ Uploading: suspicious_powershell_execution.xml (XXX bytes)
# Response Code: HTTP 200
# β Successfully deployed to: https://your-wazuh-url.com:55000/rules/files/...
#
# π Deployment Summary:
# β Deployed: 1
# β Failed: 0
# β
All rules deployed successfully!title: Rule Title (Required)
id: unique-uuid-here (Required)
status: test|production|deprecated (Required)
description: Detailed description (Required)
logsource:
product: windows|linux|macos|web
category: process_creation|file_access|registry_event|network_connection
detection:
selection:
field|modifier: value
field2: [value1, value2]
condition: selection
falsepositives:
- Common false positive scenario 1
- Common false positive scenario 2
level: informational|low|medium|high|critical
tags:
- attack.discovery
- attack.t1087CommandLine|contains: 'powershell' # Contains string
Image|endswith: '.exe' # Ends with
CommandLine|startswith: 'cmd' # Starts with
CommandLine|all:
- 'net.exe'
- 'user' # Contains all stringsExample 1: Process Creation Detection
title: Suspicious cmd.exe Execution with Encoded Command
id: 3a1234f5-a678-4321-b123-c4d5e6f7g8h9
status: production
description: Detects cmd.exe executed with encoded PowerShell commands
logsource:
product: windows
category: process_creation
detection:
selection:
Image|endswith:
- 'cmd.exe'
CommandLine|contains:
- 'powershell.exe -enc'
- 'powershell.exe -e'
- '/c powershell'
condition: selection
level: high
falsepositives:
- Legitimate admin scripts
tags:
- attack.execution
- attack.t1086Example 2: File Access Detection
title: Suspicious File Access to SAM Database
id: 5b2345g6-b789-5432-c234-d5e6f7g8h9i0
status: production
description: Detects unauthorized access to Windows SAM registry file
logsource:
product: windows
category: file_access
detection:
selection:
TargetFilename|contains: 'SAM'
Action: 'CreateKey'
condition: selection
level: critical
falsepositives:
- Authorized backup tools
tags:
- attack.credential_access
- attack.t1003Input Sigma Rule:
title: Clear Logs Process Execution
level: high
detection:
selection:
CommandLine|contains: 'wevtutil cl'
Image|endswith: 'cmd.exe'
condition: selectionOutput Wazuh XML:
<group name="sigma">
<rule id="600123" level="7">
<decoded_as>json</decoded_as>
<match>wevtutil cl</match>
<match>cmd.exe</match>
<description>Clear Logs Process Execution (from Sigma conversion)</description>
<options>no_full_log</options>
</rule>
</group>| Sigma Level | Wazuh Level |
|---|---|
| informational | 2 |
| low | 3 |
| medium | 5 |
| high | 7 |
| critical | 15 |
- Rule IDs start at 600000+ to avoid conflicts with built-in Wazuh rules
- IDs are generated from Sigma rule title hash (consistent across conversions)
- Format:
600000 + abs(hash(title)) % 10000
- Create empty GitHub repository (without README)
- Push code to repository:
git remote add origin https://github.com/yourusername/detection-as-code.git git branch -M main git push -u origin main
- Add GitHub Secrets:
- Go to Settings β Secrets and variables β Actions
- Click "New repository secret"
- Add
WAZUH_MANAGER_HOST(your Wazuh URL without https://) - Add
WAZUH_JWT_TOKEN(your JWT token)
Validation Workflow (on every push):
Push β Validate Sigma YAML syntax β Check schema compliance
Conversion Workflow (on every push):
Push β Validate β Convert Sigma to Wazuh XML β Generate artifacts
Deployment Workflow (on push to main only):
Push to main β Validate β Convert β Deploy via Wazuh API β Verify
View workflow runs:
- Go to GitHub repo β Actions tab
- Click workflow name to see details
- Each job shows logs and status
Run complete Wazuh stack locally:
# Start Wazuh Manager and Indexer
docker-compose up -d
# Wait for services to start (2-3 minutes)
sleep 180
# Check status
docker-compose ps
# Access Wazuh Dashboard
# URL: https://localhost
# Default credentials: admin/SecurePassword123# Check YAML syntax
python3 -c "import yaml; yaml.safe_load(open('sigma-rules/process_creation/my_rule.yml'))"
# Run full validation
bash scripts/validate.sh# List all converted rules
ls -la converted-rules/wazuh/rules/
# View specific rule
cat converted-rules/wazuh/rules/my_rule.xml
# Count total rules
ls -1 converted-rules/wazuh/rules/ | wc -l- Be Specific - Use multiple conditions to reduce false positives
- Document Everything - Include clear descriptions and false positive scenarios
- Test Thoroughly - Validate against real logs before production deployment
- Version Control - Always commit with meaningful messages
- Tag Properly - Use MITRE ATT&CK tags for better organization
- Use Meaningful Titles - Rule titles should describe the detection clearly
- Never manually edit converted XML - Always modify the Sigma YAML source
- Use status field - Mark rules as test/production/deprecated
- Track false positives - Document common false positive scenarios
- Review before merge - Use pull requests for all changes
- Keep rules organized - Use proper directory structure by category
- Test in non-prod first - Deploy to test environment before production
- Monitor after deployment - Check Wazuh logs for rule triggers
- Maintain backups - Keep version history in git
- Document changes - Use commit messages to track changes
- Regular audits - Review rule effectiveness quarterly
Issue: "WAZUH_MANAGER_HOST not set"
# Solution: Set environment variable
export WAZUH_MANAGER_HOST="your-wazuh-url.com"
export WAZUH_JWT_TOKEN="your-token"Issue: "XML syntax error" from Wazuh API
# Solution: Verify converted XML is valid
cat converted-rules/wazuh/rules/your_rule.xml
# Should start with <group> tag, NOT <?xml declaration>Issue: "Invalid JWT Token"
# Solution: Regenerate token (tokens expire after 15 minutes)
curl -k -X POST "https://your-wazuh-url.com:55000/security/user/authenticate" \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"your_password"}'Issue: "Connection refused"
# Solution: Verify Wazuh Manager is running and accessible
curl -k https://your-wazuh-url.com:55000/security/user/authenticateIssue: GitHub Actions won't deploy
# Solution: Check that secrets are properly set
# Go to Settings β Secrets and variables β Actions
# Verify WAZUH_MANAGER_HOST and WAZUH_JWT_TOKEN are present- Fork the repository
- Create a feature branch (
git checkout -b feature/new-detection-rule) - Add your Sigma rule to appropriate directory
- Test locally (
bash scripts/validate.sh && bash scripts/convert-all.sh) - Commit with clear message (
git commit -m "Add: Detection for suspicious process X") - Push to branch (
git push origin feature/new-detection-rule) - Create Pull Request with description of detection rule
- β YAML syntax is valid
- β Rule is tested against real logs
- β Description is clear and detailed
- β False positives are documented
- β Commit message is descriptive
- Project Lead: Asish Verma
- Contributors: Security Engineering
- Maintainer: NopelCyber
For issues, questions, or contributions:
- GitHub Issues: Report bugs or feature requests
- Discussions: Ask questions
- Email: asish.verma@nopalcyber.com
- Never commit credentials - Always use environment variables or GitHub Secrets
- JWT tokens are sensitive - Rotate tokens regularly
- Validate all inputs - Ensure Sigma rules are from trusted sources
- Monitor deployments - Review Wazuh logs after each deployment
| Metric | Value |
|---|---|
| Total Sigma Rules | N/A |
| Converted to Wazuh | N/A |
| CI/CD Automation | β Active |
| Last Update | TBD |
| Deployment Method | REST API + JWT |
| Wazuh Version | 4.7.0+ |
Last Updated: 2025-01-15 | Version: 1.0.0 | Status: Production Ready
# Setup
pip install -r requirements.txt
source .env
# Development
bash scripts/validate.sh # Validate rules
bash scripts/convert-all.sh # Convert to Wazuh
bash scripts/deploy.sh # Deploy to Wazuh
# Testing
docker-compose up -d # Start local Wazuh
docker-compose down # Stop local Wazuh
# Git
git add .
git commit -m "Add: rule description"
git push origin mainHappy Detection Engineering! ππ