Expand description
§agentsec-core — AgentSec pure-logic library
Pure-Rust logic crate. No rmcp / clap / GUI dependency — the umbrella
binary agentsec is the only transport adapter (see the agentsec
crate for CLI / MCP server / hook wiring).
This crate doc is the single source of truth for the threat model, module roster, and read-only invariants. Module-level docs reference the sections below by anchor (e.g. crate root §Threat surface × vector).
§§Threat surface × vector
Defense is framed as a 2-axis matrix. The vertical axis is where the threat is observed, the horizontal axis is how the injection arrives. Modules cover the following cells:
| Surface | Vector | Module |
|---|---|---|
| L1 Agent config dir | V3 Config tampering | scan |
| L4 Network egress | V1 Prompt injection | web |
| L5 User-facing input | V1 Prompt injection | paste |
Surface key:
- L1 Agent config —
~/.claude/,~/.cursor/,.mcp.json, skills / agents / plugins dirs, dependency manifests, lockfiles,.env - L2 Dependency manifest —
package.json,Cargo.toml, lockfiles (covered byscanas a sub-axis of L1) - L3 Runtime process — Agent / MCP subprocess (not implemented)
- L4 Network egress — outbound URL fetch from Agent context
- L5 User-facing input — pasted text, prompt body, tool args
Vector key:
- V1 Prompt injection — instruction-override text in fetched URL / RAG / pasted content
- V2 Supply chain — typosquat / hijacked package (not implemented)
- V3 Config tampering — newly-installed / mutated config under L1
- V4 Runtime tampering — process injection (not implemented)
§§Module roster
| Module path | Role |
|---|---|
scan | Hash inventory of agent config + lockfiles; diff against the previous snapshot. |
paste | Multi-layer decode + multi-pattern scan + unicode anomaly check; verdict Clean / Suspicious / Blocked. |
web | URL fetch with body cap + 2-layer sanitize (regex then optional LLM) + <untrusted_content> envelope. |
output | Render a scan::ScanOutcome as Markdown. |
registry | Known-good MCP server registry (builtin + cache + net fetch). |
plain_mode | Temporarily disable .mcp.json files via rename + stub. |
emergency_stop | Enumerate Agent / MCP processes by name and SIGTERM them. |
config | Edge-resolved Config (env → struct); the only env-reading code. |
error | Crate-wide error enum. |
§§Runtime data root
All persisted state lives under config::Paths::home, resolved at
the binary’s outer rim by config::Config::from_env as:
$AGENTSEC_HOMEif set (used by integration tests to redirect to a tempdir), else$HOME/.agentsec/, else./.agentsec/(last-resort fallback whenHOMEis unset).
Layout:
<home>/snapshots/<UTC-ts>.json — scan snapshots (scan::snapshot)
<home>/scans/last-session-start.txt — last SessionStart hook summary
<home>/paste_log/<UTC-ts>-<id>.json — paste verdicts
<home>/web_log/<UTC-ts>-<id>.json — sanitize results§§Environment variables
All env reads are funneled through config::Config::from_env (the
only function in this crate that touches std::env). Library
functions take &Config (or sub-references) as a parameter; they do
not consult the process environment at the point of use. See
config for the full mapping and the test-friendly
config::Config::from_env_lookup override.
§§Read-only invariants
scannever mutates any scanned path; it only reads bytes and writes to<home>/snapshots/.pastenever persists the raw input plaintext outside the JSON audit row under<home>/paste_log/.web::fetchenforces a 2 MiB body cap and 15 s timeout; oversized bodies are rejected, not truncated.web::sanitize::semantic_layerfails open: a missing API key or non-2xx response returns the regex-stripped input unchanged. The 1st (regex) layer alone is the floor of protection.- Symbolic links are not followed during
scan::inventory::collect.
Re-exports§
Modules§
- config
- Edge-resolved configuration.
- emergency_
stop - Emergency Stop — enumerate Agent / MCP-server processes by name pattern and send them SIGTERM.
- error
- Crate-wide error type.
- output
- Output renderers for
crate::scan::ScanOutcome. - paste
- Paste-content injection / role-hijack detector. Covers the L5 × V1 cell (cf. crate root §Threat surface × vector).
- plain_
mode - Plain Mode — temporarily disable MCP servers by renaming
.mcp.jsonfiles to.mcp.json.suspectand (optionally) writing an empty stub in their place. - registry
- Known-good MCP server registry.
- scan
- Inventory scan over agent config / dependency manifests / secrets dotfile. Covers the L1 × V3 cell (cf. crate root §Threat surface × vector).
- web
- Web sanitize: URL fetch + 2-layer injection strip + envelope wrap. Covers the L4 × V1 cell (cf. crate root §Threat surface × vector).