AI-Powered Security Operations with Splunk as the Operational Brain
Every pull request is automatically reviewed for vulnerabilities. Findings stream into Splunk in real time. Before issuing a verdict, the agent queries Splunk for historical context. Security teams see org-wide threat posture. Developers see inline code comments.
Demo video: https://youtu.be/DapPyns2628
When a developer opens a pull request, BattleOps:
- Fetches the diff via GitHub App webhook
- Scans for secrets with gitleaks and checks dependencies against the OSV vulnerability database
- Queries Splunk via MCP — asks whether files in this diff have had prior confirmed findings, and whether any CVEs match known alerts in the environment
- Runs the AI analysis agent (DeepSeek) with Splunk historical context baked into its reasoning
- Verifies every finding — an adversarial verifier agent challenges every HIGH/CRITICAL result to reduce noise, then maps confirmed findings to attack chains across the diff
- Pushes every finding to Splunk HEC as a structured security event, in real time
- Posts inline review comments back to the PR on GitHub, anchored to the exact lines
- Anomaly detection runs on the Splunk side — the AI Toolkit flags PRs whose risk score is statistically anomalous for that repository
Security teams get a live Splunk dashboard showing findings by severity, risk score trends, CVE hit rates, and anomaly alerts. Developers get inline PR feedback. Both audiences can now keep the same reference per issue very easily. See our open PRs for sample reviews.
See architecture_diagram.md at the root of this repo.
GitHub PR opened
│
▼
GitHub App Webhook
│
▼
BattleOps API (Bun + Hono)
│
├─── gitleaks secret scan
├─── OSV CVE dependency check
│
▼
[NEW] Splunk MCP pre-query
"Prior findings on these files? Known CVE alerts?"
│
▼
AI Analysis Agent (DeepSeek)
← Splunk historical context injected into reasoning
│
├─── [NEW] Splunk HEC push (each finding → Splunk event)
│
▼
Verdict + Risk Score
│
├─── GitHub inline review comments posted
│
└─── [NEW] Splunk dashboard updated live
│
└─── [NEW] Anomaly detection (AI Toolkit)
flags statistically unusual PRs
Every finding is pushed to Splunk's HTTP Event Collector immediately after analysis. Custom sourcetype battleops:finding with structured fields:
{
"sourcetype": "battleops:finding",
"event": {
"severity": "high",
"category": "injection",
"file": "src/api/auth.ts",
"line": 47,
"message": "SQL injection via unsanitized user input",
"cve_id": "CVE-2024-1234",
"risk_score": 78,
"repo": "org/repo",
"pr_number": 142,
"run_id": "run_abc123",
"verified": true
}
}Before the AI agent generates its verdict, it calls the Splunk MCP Server as a tool:
Tool: splunk_search
Query: search index=battleops file="src/api/auth.ts" severity IN ("high","critical")
| stats count by severity, category
| sort -count
The agent receives historical frequency data and adjusts its confidence and risk score accordingly. A file with 5 prior confirmed high findings in the last 90 days is treated differently than a file with no history.
After findings are pushed, an SPL scheduled search uses Splunk's ML toolkit to detect anomalous risk scores per repository:
index=battleops
| timechart span=1d avg(risk_score) as avg_risk by repo
| anomalydetection avg_risk
| where isOutlier=1
Anomalous PRs generate a Splunk alert that links back to the GitHub PR and the BattleOps run report.
A pre-built dashboard (splunk/dashboard.xml) ships with the repo. Import it into your Splunk instance to get:
- Findings by severity (last 30 days)
- Risk score trend per repository
- Top vulnerable files across all PRs
- CVE hit rate over time
- Anomaly alerts with PR links
| Layer | Technology |
|---|---|
| API server | Bun + Hono |
| Database | PostgreSQL (findings, runs, CVE hits) |
| Cache / fast lookups | Redis |
| Secret scanning | gitleaks |
| Dependency CVEs | OSV API |
| AI analysis | DeepSeek |
| Splunk ingest | HTTP Event Collector (HEC) |
| Splunk query | Splunk MCP Server (Splunkbase app 7931) |
| Splunk ML | AI Toolkit anomaly detection |
| GitHub integration | GitHub App (webhook + review API) |
Note on
@battleops/cf-compat: an internal abstraction package that maps a Cloudflare-style env interface (KV, R2, Workflows) to Redis, S3, and Postgres respectively. It is transparent to the Splunk integration and does not affect the data flow described above.
This project existed prior to the hackathon submission period. The following were built or substantially reworked after May 18:
- Splunk HEC integration — new, purpose-built for this submission
- Splunk MCP mid-loop tool call — new agent tool that queries Splunk before verdict
- Splunk AI Toolkit anomaly detection — new SPL scheduled searches and alert
- Splunk dashboard — new, ships as importable XML
- Platform migration — migrated from Cloudflare Workers + D1 to Bun/Node server with PostgreSQL and Redis, enabling persistent queryable schema (
pr_runs,pr_findings,pr_cve_hits) that backs the Splunk historical queries - Agentic analysis pipeline — replaced 7 one-shot LLM calls with a self-directed tool-calling agent that reads full source files and traces taint flows
- Verifier agent — adversarial second-pass agent that challenges HIGH/CRITICAL findings before they ship
- Denoise on re-run — old GitHub reviews updated with links to the new review, reducing PR noise
- Report endpoint —
GET /pr/:prNumber/reportandGET /runs/:runId/reportfor structured finding retrieval
- Bun v1.0+
- Docker + Docker Compose
- PostgreSQL 15+
- Redis 7+
- Splunk Enterprise (free trial) with:
- Splunk MCP Server installed
- Splunk AI Toolkit installed
- HEC token configured
- GitHub App (for webhook integration)
- DeepSeek API key
git clone https://github.com/digitaldrreamer/battleops.git
cd battleops
bun install# Root .env — used by Docker Compose (DB_PASSWORD, SPLUNK_*, GITHUB_APP_*)
cp .env.example .env
# API .env — used when running the API directly outside Docker
cp apps/api/.env.example apps/api/.envEdit .env (Docker Compose values) and apps/api/.env (direct API run):
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/battleops
# Redis
REDIS_URL=redis://localhost:6379
# AI
DEEPSEEK_API_KEY=...
DEEPSEEK_MODEL=deepseek-reasoner
DEEPSEEK_FLASH_MODEL=deepseek-chat
# GitHub App
GITHUB_APP_ID=...
GITHUB_APP_PRIVATE_KEY=...
GITHUB_WEBHOOK_SECRET=...
# Splunk
SPLUNK_HEC_URL=https://your-splunk:8088/services/collector
SPLUNK_HEC_TOKEN=your-hec-token
SPLUNK_MCP_URL=http://your-splunk:8000/services/mcp
SPLUNK_MCP_TOKEN=your-splunk-token
SPLUNK_INDEX=battleops
# Feature flags
AGENTIC_REVIEW_ENABLED=truedocker compose up -d postgres redis# Docker Compose (recommended — starts postgres, redis, api, web together)
docker compose -f docker-compose.prod.yml up -d
# OR run the API directly for development
cd apps/api && bun run devThe API runs on http://localhost:3000.
Database migrations: the schema is applied automatically on first startup via
ensureAppSchema. No separate migration step is needed.
cd apps/web && bun run devThe web UI runs on http://localhost:5173.
- Install Splunk Enterprise free trial: https://www.splunk.com/en_us/download/splunk-enterprise.html
- Request Developer License: https://dev.splunk.com/enterprise/dev_license
- Install Splunk MCP Server from Splunkbase
- Install Splunk AI Toolkit from Splunkbase
- Create HEC token: Settings → Data Inputs → HTTP Event Collector → New Token
- Import the dashboard: Settings → User Interface → Views → Import → select
splunk/dashboard.xml - Import the anomaly detection saved search:
splunk/anomaly_search.xml
- Create a GitHub App at https://github.com/settings/apps/new
- Set webhook URL to
https://your-domain/webhook/github - Subscribe to:
pull_requestevents - Generate and download private key
- Install the app on your target repositories
- Log in to the hosted instance (URL provided on the submission form)
- The dashboard shows org-wide findings streamed from prior runs — severity breakdown, risk score trends, and anomaly flags
- Navigate to PR Reviews to see a completed run — click any finding to view the full AI reasoning trace, verifier agent challenge, and final verdict
- Open the linked GitHub PR to see inline review comments posted directly on the changed lines
- In Splunk, run
search index=battleops | table severity category file line run_idto see the structured events streamed via HEC
Triggering a new run:
Open a pull request in a repository where the GitHub App is installed. The workflow fires automatically via webhook. Findings appear in the web UI, Splunk dashboard, and GitHub PR within seconds of the agent completing.
apps/
└── api/
└── src/
├── index.ts # Hono app, webhook handler
├── workflows/
│ └── prReview.ts # Full PR review workflow
├── agents/
│ └── RepoAgent.ts # Per-repo run state manager (PostgreSQL-backed)
├── lib/
│ ├── github.ts # GitHub API helpers
│ ├── schema.ts # Postgres schema bootstrap
│ ├── splunk-client.ts # [NEW] HEC push + MCP query client
│ └── deepseek.ts # LLM client (OpenAI-compatible)
└── tools.ts # Agent tool implementations
splunk/
├── dashboard.xml # [NEW] Importable Splunk dashboard
└── anomaly_search.xml # [NEW] Scheduled anomaly detection search
architecture_diagram.md # System architecture diagram (Mermaid)
MIT — see LICENSE
- Splunk Hackathon: https://splunk.devpost.com/
- Splunk MCP Server docs: https://help.splunk.com/en/splunk-cloud-platform/mcp-server-for-splunk-platform/1.1/about-mcp-server-for-splunk-platform
- Splunk AI Toolkit: https://splunkbase.splunk.com/app/2890
- OSV vulnerability database: https://osv.dev/
- gitleaks: https://github.com/gitleaks/gitleaks