Patent pending — USPTO 19/649,210

Catch the security bugs that live between your microservices.

Snyk scans one repo. Semgrep scans one file. CrossGraph builds one call graph across every service you own, propagates taint across HTTP / gRPC / shared-DB boundaries, and uses your OpenTelemetry traces to keep false positives below 5 %.

Seven things happen on every pull request.

CrossGraph is the GitHub App that does one job — it catches a finding that would have only shown up in production, and it does it before the PR merges.

01 · DISCOVER

Walk the repos.

Every package.json or pyproject.toml becomes a service. Every openapi.yaml, .proto, and source file maps to an edge candidate.

02 · PARSE

Find the taint.

Tree-sitter extractors on TypeScript + Python surface sources (req.body, env vars,request.form) and sinks (SQL interpolation, exec, egress, file writes, logs).

03 · EDGE

Build the call graph.

OpenAPI endpoints + .proto methods + inferred client calls become directed edges between services. Shared Postgres tables become FK + shared-state edges.

04 · PRUNE

Pair it with reality.

Edges with 0 production calls in 24 h drop to 20 % confidence. Cold edges (1-9) to 70 %. Hot edges at full. This is the patent-distinguishing element — and why the PR check doesn't spam.

05 · TAINT

Propagate across services.

BFS from every labeled source, across every edge, until it hits a sink. Cross-service paths only — intra-service work belongs in Semgrep.

06 · DIFF

Report only net-new.

Base-branch findings don't spam the PR. Findings the PR removed get celebrated. The check reports only what this change introduced.

What the developer sees.

One Check Run summary + one inline PR comment per net-new finding, anchored to the sink line. Path shown, runtime evidence attached, suggested fix specific.

🔴 CrossGraph — 1 new cross-service vulnerability (blocking)

CG-001 — cross-service SQL injection (critical)

checkout-api/src/routes/checkout.ts:47 passes req.body.coupon_code
(user-input, unsanitized) via HTTP POST /orders to orders-writer.
The receiving handler in orders-writer/app/orders.py:112 interpolates
it directly into a SQL query.

Cross-service path (3 hops):
  1. checkout-api   src/routes/checkout.ts:47   → source: user-input
  2. orders-writer  HTTP POST /orders            → edge
  3. orders-writer  app/orders.py:112            → sink: SQL

Runtime evidence: 1,247 production calls in the last 24h.
Confidence: 92 %.

Suggested fix: parameterized query at orders-writer/app/orders.py:112.

Built for teams that already moved past single-repo scanners.

Cross-service vulnerabilitySingle-repo scanner?CrossGraph?
SQL injection across an internal HTTP hop✓ CG-001
Command execution from a shared queue payload✓ CG-002
SSRF via an internal proxy service✓ CG-003
PII logged on a downstream service✓ CG-004
Secret exfiltrated through an outbound egress✓ CG-005
Shadow API edges (in runtime but not in OpenAPI)✓ CG-050

Get early access.

We're onboarding 3-5 design partners in Q2 2026. Series B-D startups running Node and Python microservices at 20-150 service count, already paying Snyk or Semgrep — but still shipping cross-service bugs to production.