Skip to content

contantlab/reachability

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reachability

Context-aware vulnerability prioritization with attack-path chaining. Self-hosted, no lock-in, swap any scanner.

Reachability ingests vulnerability scan results and re-scores them against a model of your environment - your topology, your controls, your crown-jewel data. It cuts the noise of a "critical and high" backlog down to what is actually exploitable in your stack, and it surfaces the dangerous chains that scanners miss: the two "mediums" that, strung together, reach your database.

Severity is a property of your environment, not of a CVSS score. Reachability treats it that way.


The problem

Run a scanner against a SaaS app and you get hundreds of findings, dozens flagged critical or high. Most teams then spend days manually asking, per finding: Is this even reachable? Is there a WAF in front of it? Does it actually touch sensitive data? Could it be chained with something else? That triage is slow, context-heavy, and rarely finished. So backlogs grow, and the genuinely dangerous combinations - a low-severity SSRF that pivots into an unauthenticated internal admin endpoint - stay buried under noise that was never exploitable to begin with.

What Reachability does

  • Downgrades noise. A critical SQLi behind a blocking WAF on every inbound path, or a dependency CVE on code no internet-facing path ever invokes, is re-scored down - with a written rationale for every move. Nothing is silently suppressed.
  • Upgrades real risk. It models each finding as an attacker step (preconditions -> postconditions) and searches your environment graph for chains that reach sensitive assets. A chain of three mediums that ends at a crown-jewel datastore is reported as critical, regardless of the individual scores.
  • Explains itself. Every re-score carries an auditable trail - which rule fired, which control or path or chain drove it. The explanation is the product.

Principles

  • Self-hostable. docker compose up. Runs on your servers, AWS, Azure, anywhere. No external SaaS dependency, no phone-home, no telemetry.
  • No lock-in. Free, open-source scanners are the defaults. Already pay for a premium scanner? Swap it in by changing one line of config. The reasoning engine never knows the difference.
  • Config as truth. Stack context, scanner choices, and scoring policy are declarative files you own and version-control.
  • No hand-holding. Anyone with the technical skills deploys it solo. No sales call, no customer-success manager, no license key.
  • Deterministic and auditable. Scores are reproducible run to run. A security team can verify every decision.

How it works

  Scanners            Normalize            Context              Reasoning
 (swappable)           findings           graph (yours)          engine
 ┌─────────┐         ┌──────────┐        ┌──────────┐        ┌──────────────┐
 │ nmap    │         │ common   │        │ assets   │        │ reachability │
 │ ZAP     │ ──────► │ finding  │ ─────► │ controls │ ─────► │ + chaining   │
 │ Grype   │         │ schema   │        │ zones    │        │ + policy     │
 │ (yours) │         └──────────┘        │ data     │        └──────┬───────┘
 └─────────┘                             └──────────┘               │
                                                                    ▼
                                              re-prioritized findings + attack chains
                                                  each with a written rationale
  1. Ingest context. A guided questionnaire plus uploads - SBOM (CycloneDX/SPDX), IaC (Terraform), diagrams-as-code - build a graph of your environment. IaC is treated as ground truth; questionnaire answers as lower-confidence.
  2. Scan. Pluggable adapters run your chosen scanners and normalize every result into one schema.
  3. Reason. The engine computes internet-reachability per finding, builds attack chains over the graph, then applies a declarative scoring policy to produce a contextual severity, a delta, and a rationale.
  4. Report. A re-prioritized list and a set of attack chains, each expandable to why.

Swap a scanner

Defaults are all open-source. To use a premium scanner you already license, change one line:

# config/environment.yaml
scanners:
  port: nmap
  dast: zap        # -> burp-enterprise
  sca:  grype      # -> tenable

Most scanners need only a declarative YAML adapter (command + field mappings, no code). Complex ones get a small Python adapter. See docs: writing an adapter.

Repo layout

core/        graph model, reasoning engine, scoring - scanner-agnostic
adapters/    one folder per scanner; OSS defaults + _template scaffold
schema/      normalized finding model, context graph, adapter contract, scoring policy
deploy/      docker-compose, env examples
docs/        self-host guide, "write an adapter in 20 minutes"

Design docs

The contracts everything is built against live in schema/:

Status

Early development. The design contracts are stable; implementation is in progress. Built core-first: context graph and ingestion, then one scanner end-to-end, then the downgrade engine, then attack-path chaining, then live DAST and reporting.

Tech

Python core. Postgres for storage and graph traversal (recursive CTEs) behind a GraphStore interface - no heavyweight graph DB required to self-host, with room to add one for very large environments. Containerized, provider-agnostic.

License

Apache 2.0. Use it, host it, embed it, modify it. No lock-in by design.

Releases

No releases published

Packages

 
 
 

Contributors