Security
Hardcoded secrets, missing auth middleware, permissive CORS, unvalidated input, insecure container base images.
Most code reviews focus on what the code does — correct logic, clean APIs, readable names. But production failures rarely come from wrong logic alone. They come from missing health checks, unencrypted secrets in config, dependency rot, absent rate limiting, no graceful shutdown — the non-functional properties that nobody remembers to check until something breaks at 3am.
nfr-review automates the review of these properties. Point it at a repository, and it produces a structured report covering security, reliability, observability, performance, maintainability, and more — without requiring a running application.
nfr-review ships with 125 rules across categories aligned to ISO 25010 quality attributes:
Security
Hardcoded secrets, missing auth middleware, permissive CORS, unvalidated input, insecure container base images.
Reliability
Missing health checks, no circuit breakers, absent retry policies, unhandled error paths, missing graceful shutdown.
Observability
No structured logging, missing trace propagation, absent metrics endpoints, swallowed exceptions, missing correlation IDs.
Maintainability
Star imports, mutable default arguments, high cyclomatic complexity, missing type hints, test coverage gaps.
It also covers performance, portability, deployment topology, dependency health, CI/CD automation, documentation coverage, and licensing compliance.
nfr-review reads source files and configuration from a repository using collectors (parsers for Python, Java, Go, Dockerfiles, Kubernetes manifests, Terraform, and more). Collectors produce structured evidence — typed data about what they found. Rules evaluate that evidence against known patterns and yield findings with a severity, a recommendation, and a precise source location. Finally, a renderer assembles findings into a report (Markdown, HTML, PDF, CSV, SARIF, or JSONL).
No code execution. No network access to the target. Pure static analysis.
Every finding has a consistent shape:
class Finding(BaseModel):
"""A rule evaluation finding. Field order matches R007 exactly.
The 10 R007 fields in canonical order:
rule_id, rag, severity, summary, recommendation, evidence_locator,
collector_name, collector_version, confidence, pattern_tag.
"""
model_config = ConfigDict(extra="forbid")
rule_id: str
rag: RAG
severity: Severity
summary: str
recommendation: str
evidence_locator: str
collector_name: str
collector_version: str
confidence: float = Field(ge=0.0, le=1.0)
pattern_tag: str
content_hash: str = ""
origin: Origin = "first_party"A real finding might say:
| Field | Example |
|---|---|
rule_id |
PY002 |
rag |
red |
severity |
high |
summary |
Star import obscures dependencies |
recommendation |
Replace from foo import * with explicit imports |
evidence_locator |
src/utils.py:3 |
confidence |
0.95 |
Findings are grouped by RAG status (red / amber / green) in reports and cross-tabulated by category and severity in the summary table.
Running nfr-review report against a repository produces:
In the next chapter, you’ll install nfr-review and run your first scan against a real repository.