API Reference¶
Auto-generated from source docstrings.
Models¶
agentscanner.models
¶
Core data model: severities, artifact types, the normalized resource IR, and findings.
Design note: the Resource IR carries a line lookup from day one so every
finding can cite file:line (see DESIGN.md §6). v1 uses raw-text re-find for
line mapping, which is accurate enough for the distinctive strings checks search
for (rule text, URLs, env values).
Resource
dataclass
¶
One parsed artifact file — the unit a Check runs against.
Source code in src/agentscanner/models.py
line_of(needle, default=1)
¶
1-based line number of the first line containing needle.
Source code in src/agentscanner/models.py
Scope
¶
Bases: str, Enum
Where the artifact lives. Discovery tags each resource so the same engine cleanly scans repo + user (+ managed/plugin) config in one run.
Source code in src/agentscanner/models.py
Severity
¶
Bases: IntEnum
Ordered so thresholds can be compared numerically (CRITICAL highest).
Source code in src/agentscanner/models.py
Discovery¶
agentscanner.discovery
¶
Discover and parse Claude Code artifacts across scopes.
Scope-driven and modular: each scope (user / project / local / managed / plugin) is an independent source. The CLI selects which scopes are active, so the same engine cleanly scans a repo, the user's ~/.claude, or both in one run — every resource is tagged with its Scope.
discover(repo_root=None, include_user=False, user_home=None)
¶
Return parsed resources for the selected scopes.
- repo_root: scan
<repo>/.claude,<repo>/.mcp.json,<repo>/CLAUDE.mdand the.claude-pluginmarketplace manifest if present. - include_user: additionally scan
~/.claude.
Source code in src/agentscanner/discovery.py
Engine¶
agentscanner.engine
¶
Scan engine: dispatch resources to applicable checks and collect findings.
apply_model_tier(findings, tier)
¶
Bump the severity of model_sensitive findings by one level when
tier is "low".
Baseline severities assume a frontier-capable model. Content that relies
on the model to resist an embedded instruction (prompt injection,
social-engineering framing, obfuscated payloads, injected hook context)
is measurably more exploitable against a smaller / less-aligned model —
this reflects that without needing to actually run the model (see the
probe command for that). No-op when tier is "high" (default).
Source code in src/agentscanner/engine.py
filter_by_threshold(findings, threshold)
¶
Return only findings at or above threshold severity.
run_checks(resources, only=(), skip=())
¶
Run all registered checks against resources and return sorted findings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
resources
|
Iterable[Resource]
|
Parsed artifacts from :func: |
required |
only
|
Iterable[str]
|
If non-empty, run only checks whose IDs are in this iterable. |
()
|
skip
|
Iterable[str]
|
Check IDs to exclude from the run. |
()
|
Returns:
| Type | Description |
|---|---|
List[Finding]
|
Findings sorted by descending severity, then check ID, then file path. |
List[Finding]
|
A buggy check never aborts the scan — it produces an INFO finding instead. |
Source code in src/agentscanner/engine.py
Checks¶
Base¶
agentscanner.checks.base
¶
Check abstract base class + registry.
Each check declares the artifact types it applies to and yields Findings. The engine instantiates every registered check once and dispatches resources to it.
Check
¶
Abstract base class for all agentscanner checks.
Subclass this, declare the class attributes, implement :meth:analyze,
and decorate with :func:register to add a check to the scanner.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Unique check identifier (e.g. |
severity |
Severity
|
Default severity for findings emitted by this check. |
title |
str
|
Short human-readable name shown in the CLI table. |
applies_to |
Set[ArtifactType]
|
Artifact types this check runs against. |
remediation |
str
|
Actionable fix guidance included in every finding. |
framework |
str
|
Comma-separated OWASP/NIST framework references. |
Source code in src/agentscanner/checks/base.py
analyze(resource)
¶
Inspect resource and yield zero or more :class:~agentscanner.models.Finding objects.
finding(resource, message, line=1)
¶
Build a :class:~agentscanner.models.Finding pre-populated with this check's metadata.
Source code in src/agentscanner/checks/base.py
get_checks(only=(), skip=())
¶
Return registered checks filtered by only / skip ID sets, sorted by ID.
Source code in src/agentscanner/checks/base.py
register(cls)
¶
Class decorator that instantiates and registers a :class:Check subclass.
Raises ValueError if the check has no id or its ID is already taken.
Source code in src/agentscanner/checks/base.py
Hooks¶
agentscanner.checks.hooks
¶
Hook checks (AS-HOOK-*).
Hooks run arbitrary commands at lifecycle events — the highest-impact artifact. We inspect the command strings as DATA only; agentscanner never executes them. Hooks can live in settings.json and in agent frontmatter, so checks iterate both.
iter_hooks(resource)
¶
Yield (event_name, hook_entry) for every command-type hook in a resource.
Source code in src/agentscanner/checks/hooks.py
Permissions¶
agentscanner.checks.permissions
¶
Permission & permission-mode checks (AS-PERM-*).
Grounded in verified Claude Code matching semantics (DESIGN.md §11):
- Bash rule wildcards are space-boundary aware; Bash(*) / Bash(:*) match
effectively everything.
- Resolution is deny > ask > allow; we only inspect allow for over-grant.
MCP¶
agentscanner.checks.mcp
¶
MCP server checks (AS-MCP-*).
MCP servers are arbitrary processes (stdio) or remote endpoints (http/sse). Risks: plaintext secrets, cleartext transport, auto-trust, unpinned supply chain.
Environment & Secrets¶
agentscanner.checks.env_secrets
¶
Environment-posture and hardcoded-secret checks (AS-ENV-, AS-SECRET-).
Agents & Skills¶
agentscanner.checks.agents_skills
¶
Agent & skill privilege checks (AS-AGENT-*).
Prompts¶
agentscanner.checks.prompts
¶
Prompt-content checks for steering files (AS-PROMPT-*).
Scans the prose body of agents, skills, commands, and CLAUDE.md for prompt- injection / steering indicators and hidden unicode. Patterns are deliberately specific to keep false positives low (security docs legitimately mention "exfiltrate" etc., so we require imperative phrasing).