| name | securityclaw-autonomous-soc-agent |
| description | Deploy and operate SecurityClaw, an autonomous SOC agent with RAG-based threat detection, LLM-powered anomaly analysis, and skill-based security automation |
| triggers | ["set up an autonomous security operations center agent","deploy SecurityClaw for threat detection and anomaly monitoring","configure RAG-based behavioral memory for security analytics","build a skill-based SOC automation framework","integrate LLM-powered threat analysis with OpenSearch","create an AI security agent with anomaly detection","implement automated threat hunting with LangGraph orchestration","set up continuous security monitoring with vector embeddings"] |
SecurityClaw Autonomous SOC Agent
Skill by ara.so — Security Skills collection.
SecurityClaw is a modular, skill-based autonomous Security Operations Center (SOC) agent that monitors OpenSearch/Elasticsearch data, builds RAG-based behavioral memory, and validates real-time anomalies using LLMs. It orchestrates security workflows through LangGraph, maintains conversation-based investigations, and provides both CLI and web interfaces for threat analysis.
Core Capabilities
- Skill-based architecture: Each capability is an isolated module with Python logic + LLM instruction
- RAG behavioral memory: Vector embeddings of network baselines stored in OpenSearch
- Anomaly detection: Scheduled 1-minute watcher polls findings and escalates threats
- LLM-powered analysis: Threat analyst validates anomalies using retrieval-augmented context
- LangGraph orchestration: DECIDE→EXECUTE→EVALUATE supervisor loop with SQLite checkpointing
- Web + CLI interfaces: React UI for chat investigations, CLI for automation
- Provider agnostic: Swap OpenSearch↔Elasticsearch, Ollama↔other LLM providers
Installation
Prerequisites
python --version
curl -fsSL https://ollama.com/install.sh | sh
ollama serve
ollama pull qwen2.5:7b-instruct-q4_K_M
ollama pull nomic-embed-text:latest
Setup
git clone https://github.com/SecurityClaw/SecurityClaw.git
cd SecurityClaw
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python main.py onboard
The onboarding wizard configures:
- OpenSearch/Elasticsearch connection (host, port, SSL, auth)
- LLM provider (Ollama endpoint, model names)
- Optional external APIs (AbuseIPDB, VirusTotal, MaxMind GeoIP)
- Skill-specific environment variables
Outputs config.yaml and .env with validated configuration.
Configuration
config.yaml Structure
database:
provider: opensearch
host: localhost
port: 9200
use_ssl: true
verify_certs: false
username: admin
password_env: OPENSEARCH_PASSWORD
llm:
provider: ollama
base_url: http://localhost:11434
model: qwen2.5:7b-instruct-q4_K_M
temperature: 0.7
max_tokens: 16384
rag:
index_name: securityclaw_baselines
embedding_model: nomic-embed-text:latest
embedding_dimension: 768
top_k: 5
api:
host: 0.0.0.0
port: 7799
enable_cors: true
Environment Variables (.env)
OPENSEARCH_PASSWORD=your_password_here
ABUSEIPDB_API_KEY=${ABUSEIPDB_API_KEY}
VIRUSTOTAL_API_KEY=${VIRUSTOTAL_API_KEY}
MAXMIND_LICENSE_KEY=${MAXMIND_LICENSE_KEY}
ANOMALY_TRIAGE_THRESHOLD=0.7
CLI Commands
Service Management
python main.py service
SECURITYCLAW_API_ONLY=1 python main.py service
python main.py run
python main.py web-dev
Skill Operations
python main.py list-skills
python main.py dispatch network_baseliner
python main.py dispatch threat_analyst
python main.py chat
python main.py status
Configuration Management
python main.py onboard
python main.py validate-config
Skill Development
Creating a New Skill
Skills are directories in skills/ with two required files:
skills/my_skill/instruction.md (LLM guidance + metadata):
---
skill_id: my_skill
display_name: My Custom Skill
version: 1.0.0
schedule_interval_seconds: 3600 # Optional: for scheduled execution
capabilities:
- custom_analysis
prerequisites:
- network_data
required_entities:
- ip_address
artifacts_produced:
- analysis_report
---
# System Prompt for My Skill
You are a security analyst performing custom analysis.
## Task
Analyze network data and produce findings.
## Output Format
Return JSON with "findings" array.
skills/my_skill/logic.py (Python implementation):
from typing import Dict, Any
import logging
logger = logging.getLogger(__name__)
def execute(
db_connector,
llm_provider,
rag_engine,
config: Dict[str, Any],
memory: Dict[str, Any],
**kwargs
) -> Dict[str, Any]:
"""
Skill entrypoint.
Args:
db_connector: OpenSearch/ES client
llm_provider: LLM client
rag_engine: RAG context retrieval
config: Skill-specific config from instruction.md
memory: Shared agent memory (read/write)
**kwargs: Additional context (user_query, conversation_id, etc.)
Returns:
Dict with success status and results
"""
logger.info("Executing my_skill")
query = {
"size": 100,
"query": {"match_all": {}},
"sort": [{"@timestamp": "desc"}]
}
results = db_connector.search(index="network-*", body=query)
context = rag_engine.retrieve("recent network behavior", top_k=3)
prompt = f"""Analyze these network events:
{results['hits']['hits'][:5]}
Baseline context:
{context}
Identify anomalies."""
response = llm_provider.chat([
{"role": "system", "content": config.get(, )},
{: , : prompt}
])
memory.setdefault(, []).append({
: ,
: (results[][])
})
{
: ,
: response[],
: (context)
}
The skill is auto-discovered on next run. Set schedule_interval_seconds in instruction.md to enable automatic execution.
Built-in Skills
network_baseliner (6-hour schedule)
Builds behavioral baselines from network logs:
python main.py dispatch network_baseliner
anomaly_triage (Manual, convertible to scheduled)
Polls OpenSearch Anomaly Detection findings:
python main.py dispatch anomaly_triage
Escalates high-confidence anomalies to memory queue for analysis.
threat_analyst (Manual, convertible to scheduled)
Analyzes escalated findings with RAG context:
python main.py dispatch threat_analyst
opensearch_querier (Manual)
Executes raw database queries:
geoip_lookup (Cron: Tue/Fri 2 AM UTC)
Maintains MaxMind GeoLite2 database:
python main.py dispatch geoip_lookup
API Usage
Chat Endpoint (SSE Streaming)
import requests
import json
url = "http://localhost:7799/chat"
payload = {
"message": "Analyze recent anomalies and check if 192.168.1.100 is malicious",
"conversation_id": "investigation_001"
}
response = requests.post(url, json=payload, stream=True)
for line in response.iter_lines():
if line.startswith(b"data: "):
data = json.loads(line[6:])
if data["type"] == "reasoning":
print(f"[THINK] {data['content']}")
elif data["type"] == "skill_call":
print(f"[SKILL] {data['skill_name']}: {data['reasoning']}")
elif data["type"] == "skill_result":
print(f"[RESULT] {data['summary']}")
elif data["type"] == "final":
print(f"[ANSWER] {data['content']}")
Dispatch Skill
import requests
response = requests.post(
"http://localhost:7799/dispatch",
json={"skill_name": "threat_analyst"}
)
result = response.json()
Query Memory
response = requests.get("http://localhost:7799/memory")
memory = response.json()
LangGraph Orchestration
SecurityClaw uses LangGraph for chat routing with a supervisor pattern:
from langgraph.graph import StateGraph
from langgraph.checkpoint.sqlite import SqliteSaver
class ChatState(TypedDict):
messages: List[Dict]
user_query: str
plan: str
skill_results: List[Dict]
final_answer: str
retry_count: int
def decide_node(state):
"""Supervisor plans which skills to invoke"""
pass
def execute_node(state):
"""Executes planned skills"""
pass
def evaluate_node(state):
"""Checks if answer is complete"""
pass
workflow = StateGraph(ChatState)
workflow.add_node("decide", decide_node)
workflow.add_node("execute", execute_node)
workflow.add_node("evaluate", evaluate_node)
workflow.set_entry_point("decide")
workflow.add_edge("decide", "execute")
workflow.add_conditional_edges(
,
should_continue,
{: , : END}
)
memory = SqliteSaver.from_conn_string()
app = workflow.(checkpointer=memory)
Common Patterns
Building Custom Threat Detection
def execute(db_connector, llm_provider, rag_engine, config, memory, **kwargs):
events = db_connector.search(
index="network-*",
body={
"size": 1000,
"query": {
"range": {"@timestamp": {"gte": "now-1h"}}
}
}
)
baseline = rag_engine.retrieve(
query="normal traffic patterns last 24h",
top_k=5
)
threats = []
for hit in events['hits']['hits']:
event = hit['_source']
prompt = f"""Event: {event}
Baseline: {baseline}
Is this anomalous? Respond JSON: {{"anomalous": bool, "reason": str}}"""
response = llm_provider.chat([
{"role": "user", "content": prompt}
])
analysis = json.loads(response['content'])
if analysis['anomalous']:
threats.append({
"event": event,
"reason": analysis['reason']
})
memory.setdefault("custom_threats", []).extend(threats)
return {
"success": True,
"threats_found": (threats),
: threats
}
Enriching with External Threat Intel
import os
import requests
def execute(db_connector, llm_provider, rag_engine, config, memory, **kwargs):
suspicious_ips = kwargs.get("ip_addresses", [])
enriched = []
for ip in suspicious_ips:
headers = {"Key": os.getenv("ABUSEIPDB_API_KEY")}
response = requests.get(
f"https://api.abuseipdb.com/api/v2/check",
params={"ipAddress": ip, "maxAgeInDays": 90},
headers=headers
)
data = response.json()
enriched.append({
"ip": ip,
"abuse_score": data.get("data", {}).get("abuseConfidenceScore", 0),
"reports": data.get("data", {}).get("totalReports", 0)
})
return {
"success": True,
"enriched_ips": enriched
}
Multi-Skill Investigation Workflow
Troubleshooting
Connection Issues
curl -k -u admin:password https://localhost:9200
curl http://localhost:11434/api/tags
python main.py validate-config
Skill Not Loading
python main.py list-skills
def execute(db_connector, llm_provider, rag_engine, config, memory, **kwargs):
pass
RAG Context Not Used
from core.db_connector import get_db_connector
db = get_db_connector()
indices = db.cat_indices()
python main.py dispatch network_baseliner
ollama list
Memory State Issues
rm data/conversations.db
rm data/conversations.db data/runtime_memory.db
python -c "
from core.memory import AgentMemory
memory = AgentMemory()
print(memory.get_summary())
"
LLM Response Truncation
llm:
max_tokens: 32768
Web UI Not Loading
cd web
npm install
npm run build
python main.py service
api:
enable_cors: true
Testing
pytest tests/ -v
pytest tests/ --cov=core --cov=skills --cov-report=html
pytest tests/test_threat_analyst.py -v
Production Considerations
- Resource limits: 8GB+ RAM recommended for production with multiple concurrent investigations
- Checkpoint cleanup: Prune old conversations in
data/conversations.db periodically
- RAG index maintenance: Archive old baselines, rebuild quarterly for evolving network patterns
- API authentication: Add auth middleware to
web/api/server.py before exposing publicly
- Secrets management: Rotate API keys in
.env, use secret managers for production deployments
- Monitoring: Track skill execution times, LLM token usage, and anomaly escalation rates