One command. Three artifacts.
ApiGate walks a directory and produces exactly this — nothing runs, nothing phones home.
One JSON report
Every endpoint, its auth posture, drift bucket, five 0–100 rubrics, and a headline score — machine-readable for CI dashboards.
One HTML report
Self-contained, zero external assets. Rendered through @stelnyx/report-theme — identical to every Stelnyx surface.
One exit code
0 clean · 1 on open-write endpoints (configurable). Blocks the pipeline — no dashboard babysitting.
Headline Score
Every run scores the API surface 0–100 — the mean of five rubrics. Sample below.
Bands: Strong ≥ 85, Good ≥ 70, Mixed ≥ 50, Weak < 50. The binary gate (exit 1 on open-write methods) is independent of the score — the number is for trend tracking, the exit code blocks CI.
Frameworks it reads
Routes it can't statically resolve are emitted as UNRESOLVED — never guessed.
| Framework | How it's parsed |
|---|---|
| Express | acorn AST for .js/.mjs/.cjs; regex fallback for .ts/.tsx. Resolves app.use('/prefix', router) mounts in the same file. |
| Fastify | acorn AST. Handles fastify.<method>(...) and fastify.route({ method, url, preHandler }). |
| NestJS | Decorator extraction. Pairs @Controller with method decorators; captures class- and method-level guards (@UseGuards, @Auth, @Roles). |
| OpenAPI | Parses *.yaml/*.yml/*.json with swagger: (2.0) or openapi: (3.x) root. Honors operation-level security + root inheritance. |
What this does not prove
ApiGate is a surface auditor, not a runtime scanner or a DAST tool. The report renders this section in every run — it's a printed trust feature, never hidden behind a toggle.
- Static analysis cannot verify runtime authorization. BOLA / object-level access correctness is invisible to ApiGate — it inspects declared posture, not middleware behavior.
- A declared guard is not a correct guard. An endpoint with an auth identifier in its chain is classified
GUARDED; the middleware may still be misconfigured or bypassable at runtime. - Dynamic mounts are reported, not guessed. Computed prefixes and runtime registration surface as
UNRESOLVEDand count against the Inventory rubric. - Public-by-design endpoints are handled honestly. Login / signup / refresh / health / OAuth callbacks are matched by a deterministic, configurable heuristic — visible, not silently dropped.
- Zero network calls — unconditional. No telemetry, no account, no phone-home, no spec fetching from URLs. Air-gapped CI works exactly like a laptop.
Need runtime authorization testing? Use a dynamic scanner. ApiGate complements DAST tooling — it does not replace it.
Drop it into CI
Exit 1 on open-write endpoints blocks the pipeline by default. One line:
# .github/workflows/apigate.yml - name: Run ApiGate run: npx @stelnyx/apigate . # exits 1 on open write endpoints — blocks the pipeline
Tighten the gate without editing config: --fail-on open-write,unknown,drift,missing-spec. PR-aware: --diff main flags routes this branch made unauthenticated. Unknown --fail-on tokens throw — a CI typo can never silently relax policy.
Common questions
- Does my code leave my machine?
- No. ApiGate makes zero network calls — no telemetry, no account, no phone-home. It reads files on disk and writes report files locally. That's unconditional, not a flag.
- Is it deterministic?
- Yes. Same inputs produce JSON- and HTML-byte-identical reports across every run. Three test suites lock the contract —
determinism.mjs,golden-apigate.mjs, and a report-theme contract test. - Is this AI?
- No. ApiGate is deterministic static analysis over acorn ASTs and decorator extraction — no LLM, no model, no inference. Every classification is explainable from the parsed source.
- Will it flag my login endpoint as a failure?
- No. A deterministic, exact-match heuristic marks public-by-design paths (login / signup / refresh / health / OAuth callbacks) and excludes them from the gate. The list is fully overridable in
.apigate.config.json. - What does it cost?
- Nothing. MIT licensed, published on npm with provenance.
npx @stelnyx/apigate .and you're done.
Audit your API surface now
No install, no signup, no config required. Point it at a directory.