A constitution-bound security scanner that refuses to act outside its charter. Exposes MCP tools for secrets detection (with SHA-256 redaction), obfuscation analysis, dependency checks, Dockerfile linting, and IaC scans across Terraform and GitHub Actions. Every decision lands in an append-only journal. Findings live in a portable SQLite index you can share with teammates to skip rescanning. The CLI runs standalone, the MCP server plugs into Claude Desktop or Cursor via stdio, and an optional LLM advisor step interprets high-severity hits. Blocks network calls unless the host is allowlisted, won't echo credentials into context, and treats prompt injection in scanned files as data. Built for defensive work, evaluated against labeled fixtures with precision and recall metrics in-tree.
A transparent, constitution-bound defensive security copilot. Ships a CLI, an MCP server (Claude Desktop, Claude Code, Codex CLI/Desktop, Cursor, Continue, Zed), an optional cloud or local LLM advisor, an HTML report exporter, and an evaluation harness.
aegis scan ~/some/repo
aegis report --severity critical --html out/report.html
aegis-mcp # stdio MCP server
This project is the inverse of an obfuscated abuse toolkit: defensive only, inspectable by design, and bound by a charter the agent cannot rewrite.
Three ideas guide it:
data/mythos.yaml, hashes it, and refuses to act outside its hard rules.src/aegis/
core/ constitution, journal, policy gate, shared index, llm
scanners/ secrets, obfuscation, dependencies, filesystem, yara
intel/ local_llm, report_html
cli/main.py `aegis` command
mcp/server.py `aegis-mcp` MCP stdio server
data/mythos.yaml the charter; edit to harden, not to weaken
data/yara/ bundled YARA rules (used when yara-python is installed)
docs/ architecture, client configs, marketplace playbook
eval/ labeled fixtures + harness producing JSON precision/recall
tests/ pytest suite, including end-to-end MCP dispatch
python3 -m venv .venv
. .venv/bin/activate
pip install -e .[dev] # core + tests
pip install -e .[all] # core + tests + LLM extras + yara
aegis charter # active constitution + fingerprint
aegis scan ~/some/repo # walk + hash + run all scanners
aegis report --severity critical
aegis report --html out/report.html
aegis advise --severity high # cloud Claude (needs ANTHROPIC_API_KEY)
aegis advise --severity high --local --model llama3.1
aegis serve mcp # stdio MCP for clients
aegis journal --limit 50 # replay every decision
The shared index lives at data/index.sqlite. Copy it to share an audit
baseline; recipients run aegis report against it without rescanning.
Aegis is published to the MCP Registry as
io.github.verrysimatupang99/aegis and to PyPI as
aegis-sec. You don't need to clone
this repo to use it. Same shape works in Claude Desktop, Claude Code, Codex,
Cursor, Continue, and Zed:
{
"mcpServers": {
"aegis": {
"command": "uvx",
"args": ["--from", "aegis-sec", "aegis-mcp"]
}
}
}
Codex uses servers instead of mcpServers but the command is identical.
See docs/clients/README.md for per-client config
file paths and verification steps.
--allow-exfil <host>. Both are journaled.--i-mean-it.mythos.yaml on load and
treats prompt-injection text in scanned files as data, not orders.The first thing Aegis was tested on is the obfuscated loader from the toolkit it replaced. The verdict was unambiguous:
[critical] obfuscation/obfuscated_loader /tmp/arctryx-trash-*/start
entropy: 11.478
exotic_ratio: 0.7442
longest_line: 4_835_152
signals: long_line, danger_tokens, exotic_unicode, high_entropy,
self_extract, anti_debug
If that archive is still present, pytest reruns the smoke test
automatically; otherwise it skips itself.
python -m eval.run --fixtures eval/fixtures --report eval/last_run.json
Three fixture cases ship in-tree (secrets, obfuscation, dependencies). Add
your own by dropping <case>/input/ plus <case>/expected.json. The harness
prints precision/recall/F1 per case and aggregate; the JSON output is what we
publish to leaderboards.
See docs/marketplace.md for the playbook on getting
Aegis listed in MCP marketplaces and where to source third-party accuracy
benchmarks (the "LLM ranking" piece).
aegis scan src # build current index
python -m aegis.cli.diff baseline.sqlite data/index.sqlite \
--fail-on critical,high
Compares two shared indexes by (scanner, rule, fingerprint). The gate exits
non-zero when new findings appear at the requested severities. Drop a
baselines/index.sqlite in your repo and the bundled GitHub Actions
workflow will run the diff on every PR.
We do not chase generic LLM leaderboards for the deterministic detection
layer. For the LLM-mediated aegis advise step we ship our own reproducible
board:
# offline smoke (no API key, no network)
python -m eval.llm_advise.runner --model mock:default \
--out eval/llm_advise/results-mock.json
# any provider that fits the adapter
python -m eval.llm_advise.runner --model anthropic:claude-3-5-sonnet-latest \
--out eval/llm_advise/results-claude35.json
python -m eval.llm_advise.runner --model local:llama3.1 \
--out eval/llm_advise/results-llama3.json
python -m eval.llm_advise.leaderboard eval/llm_advise/results-*.json \
--out eval/llm_advise/leaderboard.json
Each model is scored against rubrics in eval/llm_advise/prompts.jsonl
(must-mention terms, must-not-mention leaks). The leaderboard table is
markdown-friendly and ready to embed in the repo or marketplace listing.
See docs/marketplace.md for the publishing playbook.
| Scanner | What it catches |
|---|---|
secrets | Known-prefix tokens (GH, OpenAI, Anthropic, AWS, Slack, JWT, private keys), entropy-gated. Values redacted to SHA-256. |
obfuscation | Self-extracting JS loaders, exotic-Unicode noise, eval/Function abuse, anti-debug, aes+gunzip pipelines. |
dependencies | Floating npm versions, typosquats (Levenshtein-1), non-registry deps, install hooks. |
filesystem | World-writable, setuid in project, escaping symlinks, committed credential files, backup artifacts. |
dockerfile | FROM :latest, runs as root, secrets in ENV/ARG, `curl |
iac | Terraform: public S3 ACL, open 0.0.0.0/0 ingress, literal secrets. GitHub Actions: pull_request_target, unpinned uses:@branch, `curl |
yara | Optional, opt-in (pip install -e .[yara]). Bundles 3 rules; you drop more in data/yara/. |
.github/workflows/ci.yml runs pytest + eval.run on every push/PR (matrix py3.11+3.12)..github/workflows/pr-comment.yml posts an Aegis defensive diff as a sticky PR comment, fails the build when new critical/high findings appear vs baselines/index.sqlite..github/workflows/release.yml builds, signs with sigstore, and publishes to PyPI via trusted publishing on v* tags.After running the rubric scorer, you can score responses with a judge model:
python -m eval.llm_advise.judge \
--in eval/llm_advise/results-claude35.json \
--out eval/llm_advise/results-claude35.judged.json \
--judge anthropic:claude-3-5-sonnet-latest
# offline path:
python -m eval.llm_advise.judge \
--in eval/llm_advise/results-mock.json \
--out eval/llm_advise/results-mock.judged.json \
--judge mock:strict
Judge output is a strict JSON: accuracy, defensiveness, specificity
(1-5 each), and an explicit leak flag. We aggregate per-model into the
leaderboard.
Aegis is published to the official MCP Registry. Discovery sites (PulseMCP, mcp.so, MCP Hunt, MCP.ing) typically index from there automatically. Smithery and Glama require manual submission via their web UI:
.well-known/mcp/server-card.json
card or point to the PyPI package aegis-sec.Direct discovery URLs once the indices catch up:
MIT.
AEGIS_HOMEProject root containing data/mythos.yaml. Defaults to current working directory.
ANTHROPIC_API_KEYsecretOptional. Only needed if you call the `aegis advise` cloud LLM path.
io.github.ericm1018/skillfm-llm-cost-optimizer-openai-anthropic-usage
io.github.mikerawsonnz/llm-orchestration-agent
io.github.mikerawsonnz/authenticated-llm-agent
labforgedev/copilot-memory-mcp
csoai-org/agent-prompt-injection-firewall-mcp
io.github.mikerawsonnz/authenticated-multi-llm-agent