AI-powered automated penetration testing for your CI pipeline.
ShieldCI scans your application for real security vulnerabilities using offensive security tools β orchestrated by a local LLM that never sees your code leave your machine.
ShieldCI runs entirely on your machine β the engine, the LLM, and all security tooling. This is a deliberate design choice:
| Principle | What it means |
|---|---|
| π Your code never leaves your network | No source code is uploaded to any third-party server. The LLM (Ollama) runs locally, scans happen inside a Docker container, and results stay on disk. |
| π Zero data leakage risk | Unlike cloud-based security scanners, there is no API that receives your codebase. This matters for proprietary, enterprise, and pre-release code. |
| βοΈ Full control | You choose the model, the tools, and the scan depth. Nothing phones home. |
Future: Hosted option for open-source repos
We plan to offer an optional hosted version for projects that don't need code confidentiality (e.g. open-source repositories). The local-first mode will always remain the default for private codebases.
Pipeline flow:
- Read config β parse
shieldci.ymlfor endpoints, build commands, database info - Build & launch β install deps, start the target app in a sandbox
- Generate test plan β dynamic multi-phase plan based on config + codebase analysis
- Execute tools β fire offensive security tools via MCP (JSON-RPC over stdio) through a Kali container
- LLM adaptive strikes β the LLM reviews scan results and picks follow-up targeted attacks
- Generate report β Markdown report with vulnerable code snippets and exact fix suggestions
- Push results β optionally send structured JSON to the ShieldCI dashboard
| Requirement | Version | Notes |
|---|---|---|
| Rust | 1.77+ | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh |
| Docker Desktop | Latest | Must be running |
| Ollama | Latest | ollama pull llama3.1 |
# 1. Build the Rust orchestrator
cargo build --release
# 2. Build the Kali MCP Docker image
docker build -t shieldci-kali-image .
# 3. Add a shieldci.yml to your target repo (see Configuration below)
# 4. Run ShieldCI from your target repo directory
/path/to/shield-ciRun everything in a single container β Rust orchestrator, Kali tools, and Python MCP server. Only Ollama runs on the host.
# Make sure Ollama is running on the host
ollama serve &
# Launch with Docker Compose (one command)
docker compose up --buildOr build and run manually:
docker build -f Dockerfile.allinone -t shieldci-allinone .
docker run --rm \
--network host \
-v /path/to/your/target-repo:/workspace \
-e OLLAMA_HOST=http://host.docker.internal:11434 \
shieldci-allinonecd tests
npm install
cd ..
# Native
cargo run --release
# Or with Docker Compose (mounts ./tests automatically)
docker compose up --buildPlace a shieldci.yml in the root of the repository you want to scan. This tells ShieldCI how to build, run, and attack your app.
# ββ Project metadata ββ
project:
name: "my-app"
framework: "Node.js"
language: "javascript"
# ββ Build & Run ββ
build:
command: "npm install"
run: "node app.js"
port: 3000
# ββ API Endpoints ββ
endpoints:
- path: "/"
method: "GET"
description: "Health check"
- path: "/login"
method: "GET"
params:
- name: "username"
type: "string"
description: "User login name"
description: "User login endpoint - queries database"
- path: "/api/search"
method: "GET"
params:
- name: "query"
type: "string"
description: "Search term"
description: "Search endpoint"
- path: "/api/users"
method: "POST"
params:
- name: "name"
type: "string"
- name: "email"
type: "string"
- name: "password"
type: "string"
description: "User registration"
# ββ Database ββ
database:
type: "sqlite"
orm: false # false = raw SQL queries β HIGH RISK flag
# ββ Authentication ββ
auth:
enabled: false
# ββ Key source files ββ
files:
- "app.js"
- "routes/auth.js"| Section | Field | Type | Required | Description |
|---|---|---|---|---|
project |
name |
string | no | Project name |
project |
framework |
string | no | Framework (Node.js, Python, Rust, etc.) |
project |
language |
string | no | Primary language |
build |
command |
string | no | Build/install command |
build |
run |
string | no | Command to start the app |
build |
port |
integer | no | Port the app listens on (default: 3000) |
endpoints[] |
path |
string | yes | URL path (e.g. /login) |
endpoints[] |
method |
string | no | HTTP method (default: GET) |
endpoints[] |
description |
string | no | What this endpoint does |
endpoints[].params[] |
name |
string | yes | Parameter name |
endpoints[].params[] |
type |
string | no | Parameter type (string, integer, etc.) |
endpoints[].params[] |
description |
string | no | What this parameter is for |
database |
type |
string | no | Database engine |
database |
orm |
boolean | no | true = ORM, false = raw SQL (triggers extra SQLi tests) |
auth |
enabled |
boolean | no | Whether the app uses authentication |
files |
β | string[] | no | Key source files to focus analysis on |
- Endpoints with params β automatically generate
sqlmap_scanattack URLs database.orm: falseβ flags raw SQL usage, prioritizes SQLi testing on all param endpoints- Param names like
username,password,search,query,id,emailβ auto-targeted for injection build.portβ used to construct the target URL- If no
shieldci.ymlexists, ShieldCI falls back to auto-detection viarun.sh
ShieldCI runs a dynamic multi-phase test plan:
| Phase | Tool | What It Does |
|---|---|---|
| π RECON | nmap_scan |
Port scan to discover services |
| π RECON | check_headers |
Check for missing security headers (CSP, X-Frame-Options, etc.) |
| π·οΈ VULN SCAN | nikto_scan |
Scan for known web server vulnerabilities |
| π DISCOVERY | gobuster_scan |
Brute-force hidden directories and files |
| π‘οΈ SQLi | sqlmap_scan |
SQL injection testing on each endpoint with params |
| π§ ADAPTIVE | LLM-guided | LLM analyzes all results and picks additional targeted attacks |
ShieldCI generates two files in the target repo:
| File | Format | Purpose |
|---|---|---|
SHIELD_REPORT.md |
Markdown | Human-readable report |
shield_results.json |
JSON | Structured data for dashboard ingestion |
SHIELD_REPORT.md includes:
- Executive summary of findings
- Scan results per tool with severity ratings
- Vulnerable code snippets β exact lines from your source
- Recommended fixes β corrected code with explanations
- Security header and configuration findings
- Actionable recommendations prioritized by severity
The companion dashboard is at Zenith1415/Shield-CI β a Next.js app that visualizes scan results, tracks vulnerabilities, and manages connected repos.
- Clone and run the dashboard (see its README for setup)
- Set three env vars before running ShieldCI (or add them to your CI secrets):
export SHIELDCI_API_URL=http://localhost:3000 # dashboard URL
export SHIELDCI_API_KEY=your-secret-key # matches the dashboard's key
export SHIELDCI_REPO=owner/repo # e.g. Akshat-Raj/ShieldCI- After a scan completes, push the results:
python3 push_results.pyIn CI, this happens automatically via the GitHub Actions workflow β no manual step needed.
| Variable | Default | Description |
|---|---|---|
OLLAMA_HOST |
http://localhost:11434 |
Ollama API endpoint |
SHIELDCI_LOCAL_TOOLS |
0 |
Set to 1 to run MCP tools natively (no Docker) |
SHIELDCI_MCP_CMD |
python3 kali_mcp.py |
Custom MCP server command |
SHIELDCI_API_URL |
β | Dashboard API URL for result push |
SHIELDCI_API_KEY |
β | Dashboard API key |
SHIELDCI_REPO |
β | Repository identifier for dashboard |
ShieldCI includes a GitHub Actions workflow for automated scanning on every push. It uses a self-hosted runner to keep code local:
# .github/workflows/shieldci.yml triggers on:
on:
workflow_dispatch: # Manual trigger
push:
branches: [main]Setup:
- Add a self-hosted runner to your repo (Settings β Actions β Runners)
- Add
SHIELDCI_API_KEYto repo secrets - Ensure Docker + Ollama are running on the runner machine
- Push to
mainor trigger manually
ShieldCI/
βββ src/main.rs # Rust orchestrator β the brain
βββ kali_mcp.py # Python MCP tool server (runs inside Kali container)
βββ Cargo.toml # Rust dependencies
βββ Dockerfile # Kali Linux container with security tools
βββ Dockerfile.allinone # All-in-one container (Rust + Kali + Python + Node)
βββ docker-compose.yml # One-command launch
βββ entrypoint_allinone.sh # All-in-one container entrypoint
βββ push_results.py # Push structured results to dashboard API
βββ run.sh # Auto-detection fallback script
βββ detector.sh # Full repo profiler
βββ .github/workflows/
β βββ shieldci.yml # GitHub Actions workflow (self-hosted runner)
βββ docs/
β βββ architecture.svg # Architecture diagram
βββ tests/
βββ app.js # Intentionally vulnerable Express.js app (12 vuln types)
βββ shieldci.yml # Example configuration
βββ package.json # Test app dependencies
βββ public/
βββ index.html # Test page for discovery scans
βββ .env # Decoy sensitive file for gobuster
The included tests/app.js is an intentionally vulnerable Express.js application for testing ShieldCI's detection capabilities:
| # | Vulnerability | CWE | Endpoint |
|---|---|---|---|
| 1 | SQL Injection (login) | CWE-89 | GET /login?username= |
| 2 | SQL Injection (search) | CWE-89 | GET /api/search?query= |
| 3 | Reflected XSS | CWE-79 | GET /search?q= |
| 4 | Command Injection | CWE-78 | GET /ping?host= |
| 5 | Path Traversal / LFI | CWE-22 | GET /file?name= |
| 6 | IDOR | CWE-639 | GET /api/users/:id |
| 7 | SSRF | CWE-918 | GET /api/fetch?url= |
| 8 | Open Redirect | CWE-601 | GET /redirect?url= |
| 9 | Sensitive Data Exposure | CWE-200 | GET /debug |
| 10 | Mass Assignment | CWE-915 | POST /api/users |
| 11 | Missing Auth on Admin | CWE-306 | GET /api/secrets |
| 12 | Missing Security Headers | CWE-693 | All responses |