Scan Coverage
Gadriel Code is a code-security scanner. It analyzes source, dependencies, configuration, containers, and API definitions statically — it never executes your application or sends requests to a running service (runtime testing is the job of Preflight, Gadriel's sibling product).
Every scan is organized along two axes:
- Six scan types — what is inspected (SAST, SCA, Secrets, Config, Container, API).
- Eight pillars — why a finding matters (Security, Compliance, Safety, Operational, FinOps, Coherence, Teamwork, Bias).
Every finding carries an ID that encodes both axes:
CODE-W[1-8]-[SCAN]-[NNN]
│ │ │
│ │ └── zero-padded sequence within (pillar × scan-type)
│ └────────── scan-type code (SAST language code, AI, SCA, SECRET,
│ CONFIG, CONTAINER, API, …)
└────────────────── pillar number (W1–W8)
For example, CODE-W1-AI-001 is a Security-pillar, AI-native SAST finding;
CODE-W2-SCA-007 is a Compliance-pillar SCA (typically license) finding. The
grammar is enforced by a regex in gadriel-finding-types at both rule-load
and emit time.
The six scan types
1. SAST — Static Application Security Testing
Tree-sitter AST analysis plus taint/dataflow tracking across the supported languages.
| Crate | gadriel-scanners-sast |
| Inputs | Source files in supported languages (see languages.md) |
| Finding codes | Language codes L1–L9, plus AI, ATLAS, GRAPH, PRED |
What it detects. SAST parses each file with a pinned tree-sitter grammar
into an AST, then evaluates rules against it. Rule pattern types include
ast_call, ast_assign, ast_import, ast_string, and ast_missing for
structural matches, and ast_flow for taint propagation — tracking
user-controlled sources (request bodies, CLI args, env) through assignments
and function calls to dangerous sinks (SQL execution, shell, LLM prompt
construction). It also carries an AI-native rule class (AI) for
LLM/agent/prompt patterns and a MITRE-ATLAS-mapped class (ATLAS) for
adversarial-ML patterns. Graph-derived findings (GRAPH) draw on the 3D
codebase graph for centrality, cycle (SCC), and shortest-path signals.
Key strengths.
- Real taint/dataflow — parameter-bound tracking, not just one-hop substring aliasing. The Python engine, for example, follows a tainted value through a function parameter into a sink.
- Cross-file (workspace) taint for the languages that have a workspace-taint front-end, so a source in one file reaching a sink in another is caught.
- C/C++ has a dedicated precision engine: a
compile_commands.jsoncompile-database loader scopes analysis to real translation units, and a guard-aware dataflow pass reduces false positives.
Honest scope limits.
- Rule coverage varies sharply by language. The AST front-ends and taint engines exist in-tree for many languages, but the shipped GVL rule catalogue is deep only for the primary languages. Rust, in particular, has minimal SAST rule coverage today even though its front-end and taint engine are present. See languages.md for the per-language matrix.
- Findings depend on the policy bundle. SAST rules ship as GVL policies, so coverage grows with the rule repository, not the binary.
- The minified-JS deobfuscation "differentiator" once described for the SAST scanner was never implemented and is formally descoped.
2. SCA — Software Composition Analysis
Dependency vulnerability, license, health, and reachability analysis.
| Crate | gadriel-scanners-sca (with gadriel-osv-client) |
| Inputs | Lockfiles and manifests across ecosystems (see languages.md) |
| Finding code | SCA |
What it detects.
- Vulnerabilities — dependencies are matched against the OSV database (not NVD). OSV is synced wholesale as a local snapshot; there are no per-finding outbound queries (privacy boundary).
- License compliance — flags disallowed or incompatible licenses per the policy bundle. License findings commonly land under the Compliance pillar and can trip a dedicated exit code (see execution-layers.md).
- Dependency health — scoring for abandoned/unmaintained packages, feeding
the
dependency_abandonedamplifier. - Reachability confirmation — the core differentiator: a CVE in a
dependency is checked against the call graph before it is surfaced.
Unreachable CVEs are suppressed, and reachable ones get the
dependency_reachableamplifier.
Key strengths.
- Reachability turns "you depend on a vulnerable package" into "you actually call the vulnerable function," cutting noise dramatically.
- Broad ecosystem parser coverage (Python, JS, Cargo, Go, Maven/Gradle, Composer, Gemfile, NuGet, Conan).
- Drives SBOM generation (SPDX 2.3 + CycloneDX 1.4) directly off the collected dependency graph.
Honest scope limits.
- OSV trust on the default mirror is TLS + SHA-256 integrity pinning, not Ed25519 signatures. The signed witness-chain design is real code but applies only to a non-default legacy mirror; the default Google-CDN path relies on a hash-integrity sidecar, honestly weaker than a signature guarantee.
- Reachability quality tracks the underlying call graph; dynamic dispatch and reflection remain hard for any static reachability engine.
- A stale OSV snapshot (beyond the configured freshness threshold) causes the scan to fail rather than report against outdated data.
3. Secrets
Hardcoded-credential detection across working tree and git history.
| Crate | gadriel-scanners-secrets (with gadriel-secret-detector) |
| Inputs | Source and config text; optionally the full git history |
| Finding code | SECRET |
What it detects. A layered detector combining:
- Regex pattern catalogue — known credential shapes (
sk-ant-…,AKIA…,ghp_…, etc.), including an AI-native key catalogue: LLM API keys, vector-DB keys, MCP auth tokens, and hardcoded system prompts — a class most scanners do not cover. - Entropy analysis — hand-rolled Shannon entropy to catch high-entropy strings that no static pattern matches, with a Bayesian-calibrated threshold.
- Git-history scan — sweeps prior commits so a secret that was committed and later deleted is still surfaced. This is the requirement that distinguishes Gadriel from HEAD-only scanners.
Key strengths.
- AI-native credential coverage.
- Git-history sweep auto-enables at the CI layer (L4) by default, with a
--no-git-historyopt-out. - Redaction discipline: matched secret values are
[REDACTED]infindings.jsonand in PR comments; the prefix is preserved so the reader can identify the key type. Unredacted values are never written to disk unless the operator explicitly passes--include-values. - Documented-sentinel suppression and a
.envconfidence boost reduce false positives.
Honest scope limits.
- Full git-history scanning is L3/L4 only — its cost is unbounded on large repos, so it is not run at Watch (L1) or Pre-Commit (L2).
- Inline
# nosec-style suppression comments are not yet implemented. - Entropy detection produces false positives on legitimately random-looking
data; the sentinel/
.envheuristics mitigate but do not eliminate this.
4. Config
Static analysis of configuration files.
| Crate | gadriel-scanners-config |
| Inputs | CI/CD workflows, .env files, system-prompt files, MCP configs; IaC only under opt-in |
| Finding codes | CONFIG (and CONFIG-AI for AI-infra findings) |
What it detects.
- CI/CD — GitHub Actions (and GitLab CI) workflow security issues.
.envfiles — misconfiguration and credential exposure (secret-class findings are dispatched to the Secrets finding class but discovered by the Config file walker).- System prompts — hardcoded/insecure system-prompt configuration.
- MCP-config security — Model Context Protocol server configuration checks (an AI-native config lane).
- IaC — infrastructure-as-code checks, opt-in only via
--scan-iac.
Key strengths.
- Covers the CI/CD supply-chain surface (workflow permissions, untrusted action pinning) that other code scanners often ignore.
- AI-infra awareness (system prompts, MCP config) fits the AI-native charter.
- Config findings are among the most auto-fixable (low-effort remediation).
Honest scope limits.
- IaC is opt-in (
--scan-iac) and was deliberately de-scoped from the default Config lane; agent manifests and general application-config files were also cut from the default scope. - Docker Compose is not here — container concerns live in the Container scanner.
- OpenAPI files discovered by the Config walker are dispatched to the API scanner, not analyzed as generic config.
5. Container
Dockerfile hardening and base-image CVE analysis.
| Crate | gadriel-scanners-container |
| Inputs | Dockerfiles |
| Finding code | CONTAINER |
What it detects.
- Dockerfile hardening — running as root (missing
USER), unpinned orlatestbase images, secrets baked intoENV/ARG/RUN(cross-linked to the Secrets class), and other directive-level issues. - Base-image CVEs — the base image is resolved and checked against OSV, reusing the SCA OSV client. OS-ecosystem shards cover Debian, Alpine, Ubuntu, Rocky Linux, and AlmaLinux.
Key strengths.
- Reuses the SCA OSV client — one CVE source across dependencies and base images.
- Directive-level hardening rules are highly auto-fixable (add
USER, pin a tag).
Honest scope limits.
- Base-image CVE detection is tag-based. It resolves CVEs from the declared base-image tag, not by pulling and scanning the actual image layers/digest.
- No reachability suppression for container CVEs — the graph query that would suppress present-but-unreachable base-image CVEs is not yet shipped, so container CVE findings are not reachability-filtered the way SCA findings are.
- The Dockerfile parser is a hand-rolled line-based parser, not a full grammar; exotic multi-stage or heredoc constructs may parse imperfectly.
- RHEL proper carries no CVE data — OSV publishes no RHEL product catalog.
- Docker Compose and running containers are out of scope (Compose belongs to Config; runtime is Preflight's domain).
6. API
Static analysis of API definitions and route handlers.
| Crate | gadriel-scanners-api |
| Inputs | OpenAPI specs, GraphQL SDL, and REST route handlers in source |
| Finding codes | API (and API-AI / API-GQL-* variants) |
What it detects.
- OpenAPI — endpoints declared with no
security:(missing-auth), plus an introspection-in-production heuristic. - GraphQL — a real SDL parser feeds mutation-without-auth, subscription-without-auth, and sensitive-field-in-type checks.
- REST — decorator/route-handler detection (shared with SAST) surfaces source-defined endpoints into the graph for API-specific rules.
- AI-agent-endpoint detection — the intersection of
Endpoint,RouteHandler, andLlmCallgraph nodes flags routes where user input can reach an LLM invocation; these attract heavy risk amplifiers.
Key strengths.
- AI-agent endpoint detection is the standout — it links the user-input →
endpoint →
llm.invokepath via the codebase graph. - Every API finding carries a populated
confidence_tier, so API results participate in cross-scanner precision reporting.
Honest scope limits.
- Auth analysis is presence-based, not authorization-logic-based. It detects whether an auth declaration/decorator is present; it does not perform BOLA (broken object-level authorization) or BFLA (broken function-level authorization) analysis.
- No requests are ever sent — this is static analysis of definitions and source; runtime API testing is Preflight's job.
- Out of scope / deferred: Swagger 2.0 parsing, non-Python framework extraction, mass-assignment and rate-limit checks, spec-vs-code drift detection, and the GraphQL depth/complexity config lane.
The eight pillars
Pillars answer why a finding matters and map to the W1–W8 segment of the
finding ID. Every scan type can emit findings under any pillar.
| # | Pillar | What it captures |
|---|---|---|
| W1 | Security | Exploitable vulnerabilities — injection, unsafe sinks, missing auth, leaked credentials, reachable CVEs. |
| W2 | Compliance | Regulatory and policy alignment — license obligations, framework mappings (OWASP, CWE, EU AI Act, NIST AI RMF, ISO 42001). |
| W3 | Safety | AI/agent safety — unsafe autonomy, missing guardrails, insecure system prompts, unbounded tool access. |
| W4 | Operational | Operational robustness — reliability, resilience, and scan-latency/budget signals. |
| W5 | FinOps | Cost exposure — token-spend and resource patterns that create unbounded or runaway cost. |
| W6 | Coherence | Structural health — complexity, coupling, and maintainability signals derived from the codebase graph. |
| W7 | Teamwork | Collaboration hygiene — review, ownership, and process signals across contributors. |
| W8 | Bias | Fairness and bias risk in AI-facing code and data handling. |
Related documentation
- languages.md — per-language SAST/taint depth and SCA ecosystem coverage.
- execution-layers.md — the four execution layers
(Watch, Pre-Commit, Pull Request, CI/CD), the
--layerflag, and exit codes.
