Metadata-Version: 2.4
Name: aegis-sec
Version: 0.1.2
Summary: Aegis - a transparent, constitution-bound defensive security copilot with MCP server
Author: mrtrickster99
License: MIT
Project-URL: Homepage, https://github.com/verrysimatupang99/aegis
Project-URL: Source, https://github.com/verrysimatupang99/aegis
Keywords: security,ai,mcp,defensive,audit,copilot,claude,codex
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyyaml>=6.0
Provides-Extra: llm
Requires-Dist: anthropic>=0.39; extra == "llm"
Provides-Extra: yara
Requires-Dist: yara-python>=4.5; extra == "yara"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Provides-Extra: all
Requires-Dist: anthropic>=0.39; extra == "all"
Requires-Dist: yara-python>=4.5; extra == "all"
Requires-Dist: pytest>=8.0; extra == "all"
Dynamic: license-file

<!-- mcp-name: io.github.verrysimatupang99/aegis -->

# Aegis

[![PyPI](https://img.shields.io/pypi/v/aegis-sec?label=aegis-sec)](https://pypi.org/project/aegis-sec/)
[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-io.github.verrysimatupang99%2Faegis-7c3aed)](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.verrysimatupang99/aegis)
[![CI](https://github.com/verrysimatupang99/aegis/actions/workflows/ci.yml/badge.svg)](https://github.com/verrysimatupang99/aegis/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)


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
```

## Why this exists

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:

- **Project Glasswing (Anthropic)** - defensive collaboration and shareable
  security artifacts. Aegis stores findings as a portable SQLite index and
  records every decision in an append-only journal.
- **Claude Mythos** - the constitution-as-character idea. Aegis loads
  `data/mythos.yaml`, hashes it, and refuses to act outside its hard rules.
- **JetBrains Shared Indexes** - heavy analysis, computed once, shared. Aegis
  ships its index in the same shape so a teammate can clone the audit
  baseline without re-scanning.

## Layout

```
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
```

## Quick start

```bash
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.

## Connecting to MCP clients

Aegis is published to the MCP Registry as
`io.github.verrysimatupang99/aegis` and to PyPI as
[`aegis-sec`](https://pypi.org/project/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:

```jsonc
{
  "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`](docs/clients/README.md) for per-client config
file paths and verification steps.

## Design rules

1. **Defensive only.** The charter blocks any action that resembles spam,
   doxing, exploitation against third parties, or ban tooling.
2. **No silent network.** Outbound calls require a host on the charter
   allowlist or an explicit `--allow-exfil <host>`. Both are journaled.
3. **No secret echoing.** Detected credentials are SHA-256 fingerprinted
   before they touch the index, the journal, or any LLM context.
4. **Reversible first.** Destructive tools require `--i-mean-it`.
5. **Charter immutable at runtime.** Aegis hashes `mythos.yaml` on load and
   treats prompt-injection text in scanned files as data, not orders.

## Smoke test against a known-bad sample

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.

## Evaluation

```
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`](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).


## Differential gate

```bash
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.

## LLM-advise leaderboard

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:

```bash
# 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`](docs/marketplace.md) for the publishing playbook.


## Scanners shipped

| 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|sh`, `chmod 777`, `ADD` with remote URL. |
| `iac`         | Terraform: public S3 ACL, open 0.0.0.0/0 ingress, literal secrets. GitHub Actions: `pull_request_target`, unpinned `uses:@branch`, `curl|sh` in run blocks. |
| `yara`        | Optional, opt-in (`pip install -e .[yara]`). Bundles 3 rules; you drop more in `data/yara/`. |

## CI integration

- `.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.

## LLM-as-judge phase 2

After running the rubric scorer, you can score responses with a judge model:

```bash
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.

## Marketplace listings

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:

- Submit to [Smithery](https://smithery.ai) — upload the `.well-known/mcp/server-card.json`
  card or point to the PyPI package `aegis-sec`.
- Submit to [Glama](https://glama.ai/mcp/servers) — fill the form linking
  to https://github.com/verrysimatupang99/aegis and the PyPI package.

Direct discovery URLs once the indices catch up:

- MCP Registry: https://registry.modelcontextprotocol.io/v0/servers?search=io.github.verrysimatupang99/aegis
- PyPI: https://pypi.org/project/aegis-sec/

## Roadmap

- More scanners (Dockerfile hardening, IaC misconfig, browser extension
  manifests, mobile app permissions).
- Differential mode: compare two indexes and surface only newly-introduced
  findings (CI gate).
- Signed releases (sigstore / cosign).
- Web UI on top of the shared index.

## License

MIT.
