AI Context
Per-endpoint AI review context that aggregates guards, callees, sources, sinks, validators, and signals.
Noir can attach a structured AI review context to each endpoint. It groups static signals that LLM-based SAST tools, code reviewers, and security agents commonly need to triage a route, without forcing them to walk the repository themselves.
Use --ai-context to enable it:
noir scan . --ai-context
Pass a comma-separated bucket list to narrow the output to just the categories you care about. The filter applies at the data layer, so JSON / SARIF / YAML / Postman / OAS all see the same selection, not just the plain-text renderer.
noir scan . --ai-context=guards,sinks # auth + sinks, plus linked signals
noir scan . --ai-context=callee # only the 1-hop handler callees
noir scan . --ai-context=all # explicit form of "everything"
noir scan . --ai-context # bare form: also "everything"
Valid feature names: guards, callee, sources, sinks, validators, signals (plus all). Names are case-insensitive.
Derived signals stay linked to their supporting buckets. Selecting signals
keeps the evidence those signals need (for example ssrf keeps
outbound_http sinks), and selecting an evidence bucket keeps only the
signals linked to it (for example guards,sinks still surfaces
authz_absence). The cross-bucket priority_review roll-up is included
when signals is selected explicitly.
In plain output, every endpoint with non-empty context grows an ai_context: block. Model-based formats expose the same structure under standard locations:
| Format | Where AI context appears |
|---|---|
| JSON / JSONL / YAML / TOML | endpoints[].ai_context |
| OpenAPI 2.0 / 3.0 | Operation-level x-noir-ai-context extension |
| SARIF | result.properties.noir.ai_context |
| Postman | Appended to the item description |
| cURL / HTTPie / only-url / only-param | Omitted on purpose (primary output stays stable) |
What goes inside
Every context bucket is a list of entries with kind, name, optional source, description, path, line, confidence, and snippet. The buckets are:
| Bucket | Meaning |
|---|---|
guards |
Authentication / authorization gates detected on the route (middleware, decorators, requires_auth, role checks, etc.) |
callees |
The 1-hop handler callees Noir already collects with --include callee, re-emitted under the AI context structure for one-stop consumption |
sources |
Attacker-controlled inputs that reach the handler: each request parameter, header, cookie, and GraphQL field, plus mobile deep-link payloads. A few server-side value sources worth reviewing (a Spring @Value secret, a WebSocket CORS policy) land here too |
sinks |
Likely dangerous operations inferred from the handler body or callee names (SQL, command execution, deserialization, template rendering, file I/O, redirects, etc.) |
validators |
Input-validation and sanitization signals (schema validators, parameter coercion, allow-listing patterns) that mitigate sink risk |
signals |
Other route-shape hints worth surfacing (state-changing methods without a detected guard, path-id usage suggesting object-level authorization concerns, file-upload behavior, etc.) |
The list is best-effort. Heuristic confidence is exposed on each entry so consumers can filter by threshold. Up to 16 entries per bucket are kept to keep output compact.
Every non-empty context also carries "untrusted_fields": ["name", "path", "snippet"]. Those fields come from the scanned repository as-is, so snippet includes comments and string literals written by whoever controls that code. When you pass this output to an LLM, treat those fields as untrusted data and fence them off from your instructions.
The shape is published as a JSON Schema at schemas/ai-context.schema.json, for validators and for prompts that need a stable contract. The untrusted fields carry "x-noir-untrusted": true there. Entry kind values are an open vocabulary: new ones are added without a schema change.
Typical use cases
- AI SAST: hand the endpoint inventory plus its AI context to an LLM so it can decide where vulnerabilities are reachable from the attack surface without re-discovering the route structure.
- Manual triage: a reviewer skimming a large JSON or SARIF report can sort or filter by sink kind or by
signalslikestate_changing_without_guard. - CI gating: surface
sinksminusvalidatorsto flag risky endpoints in pull requests.
Combine with other flags
# Plain output with both 1-hop callees and the full AI context block
noir scan . --include callee --ai-context
# JSON output suitable for LLM-driven SAST pipelines
noir scan . --ai-context -f json -o noir-context.json
# OpenAPI export with `x-noir-ai-context` on every operation
noir scan . --ai-context -f oas3 -o spec.json
Completeness notes
- AI context is additive: endpoints unaffected by any heuristic come out exactly as they would without the flag (no
ai_contextkey in serialized models). - Heuristics are tuned conservatively. Both false positives and false negatives exist; treat entries as priors, not findings.
- Guard / sink / validator patterns improve over time. The set is intentionally cross-language so a single context schema works across the framework matrix Noir already covers.
- Callee coverage drives much of the AI context. See Callee Coverage for which frameworks expose handler callees today.