Open Source · MIT · @aegiskit
Aegis — defense-in-depth security for Next.js / Supabase, in one middleware file
An open-source toolkit that automates the controls fast-shipping developers (and AI coding agents) miss. It owns the horizontal controls — security headers/CSP, rate limiting, input validation, CSRF, secrets hygiene — and detects and warns on the vertical risks a library cannot fix for you (broken authorization/IDOR, Supabase RLS design mistakes).
npx @aegiskit/cli scanNo install, no config. It statically analyzes your current project.
It does not “completely protect” anything. No tool can, and any product that claims to is dangerous. Aegis complements secure design — it does not replace it.
Why it exists
“It works in the demo” and “it doesn’t leak in production” are different things
Generative AI writes happy-path code astonishingly fast. But production is decided by how it behaves on malformed input, concurrent access, and a perfectly valid request that points at someone else’s ID. Ship without that and it leaks. This isn’t opinion — it’s the public record.
Object-level authorization flaws (IDOR / BOLA) have ranked #1 — the most common risk — in the OWASP API Security Top 10 since 2019.
Source: OWASP API Security Top 10 — API1:2023 BOLAAn AI-builder platform’s missing RLS let an unauthenticated attacker read and write other users’ data (CVE-2025-48757, CWE-863, CVSS 9.3 CRITICAL).
Source: NVD — CVE-2025-4875745% of AI-generated code contains a known security flaw, and the security pass rate stays flat as models get smarter.
Source: Veracode 2025 GenAI Code Security ReportSupabase’s service_role key runs with PostgreSQL BYPASSRLS and ignores RLS entirely (the security boundary moves to where the key lives).
Source: Supabase Docs — Row Level Security
We dug into this “IDOR that opens outside RLS,” from vulnerable to fixed code, with the detection rules on GitHub.
See the detection rulesWhat Aegis covers (honestly)
The “horizontal” it automates, and the “vertical” it cannot
Security splits into horizontal controls that apply uniformly across an app, and vertical risks that depend on your app-specific “who owns what.” A library can own the former; it cannot own the latter. Aegis does not blur that line.
Horizontal controls
Automated by Aegis
- Security headers / Content-Security-Policy (nonce-aware)
- Rate limiting that actually works on serverless (atomic store, Upstash Redis support)
- CSRF / Origin verification
- A typed env boundary (no direct `process.env` access)
- Input validation at the boundary (Zod) and secure defaults
- Hard-coded secret detection (committed keys & tokens)
Vertical risks
Aegis only detects & warns (the fix is your design)
- Broken authorization / IDOR & BOLA (point at someone else’s ID, touch their data)
- Supabase RLS design mistakes (RLS-off tables, service_role bypass, missing WITH CHECK)
- Business-logic flaws (abusing quantity, price, state transitions)
- Privilege escalation & cross-tenant access
These are not “install a product and you’re covered” risks. A WAF or headers can’t stop them — the attack is a valid request with correct auth and a correct shape. Closing them takes design and review.
What it does
Detect, fix, and keep guarding in CI
Dataflow analysis beyond syntax matching, plus verification of the authorization boundary written in SQL. It suspects statically, confirms dynamically, and auto-fixes only what is provably safe.
Static analysis (taint / dataflow)
Tracks injection classes that syntax matching can’t see, following dataflow within a function. It flags the path where tainted input reaches a dangerous sink without passing a valid sanitizer — with a source→sink trace.
- SQL injection · SSRF · path traversal · open redirect · DOM XSS
- Sanitizer validity is judged per sink (URL-safe ≠ SQL-safe)
- Tainted input with no ownership scope = IDOR detection (authz/idor-tainted-scope)
Supabase RLS / SQL verification
Verifies the authorization boundary written in SQL — where a TypeScript scanner is structurally blind. It reads `supabase/migrations/**.sql` and flags RLS-off tables, missing WITH CHECK, unconditional true, over-broad anon grants, and SECURITY DEFINER functions without a pinned search_path.
- Correlates weak-RLS tables with the non-admin client code that queries them as a confirmed exposure
- Designed to report 0 on a correct production RLS design (real risk, not noise)
- It verifies RLS — it does not replace design or review
Safe auto-fixes + agent integration
Applies only provably-safe transforms (e.g. wrapping a route handler in secureRoute) and presents anything needing human judgment as copy-pasteable steps. It never claims to have fixed what it cannot fix.
- `aegis fix` previews safe diffs; `--write` applies them (review with git diff)
- `--format json` makes the plan machine-readable to hand to a coding agent
Runtime hardening (middleware)
Drops in the controls a library can correctly own, as edge-safe primitives. Add headers/CSP, rate limiting, CSRF, and a typed env boundary with one middleware file and one env module.
- @aegiskit/core is runtime-agnostic (Node / Edge / Browser)
- Fail-secure: on ambiguity or error it errs safe (never emits an unsafe header)
Dynamic analysis (DAST) + SAST↔DAST correlation
Static is a “suspicion,” dynamic is “confirmation.” It sends safe, scoped, non-destructive HTTP to an app you own and promotes anything reproduced at runtime to build-blocking.
- Reflected XSS · open redirect · SQLi (boolean/error inference) · SSRF (OOB canary)
- With test identities supplied, it also checks missing-auth / IDOR (@aegiskit/dast)
- Safe by default: localhost-only, scope-locked, request-budgeted
CI integration (SARIF / blocks high-confidence only)
Only high-confidence findings fail CI, and SARIF uploads to GitHub code scanning. The source→sink dataflow stays as a clickable trace.
- One-step adoption via a GitHub Action (the `aegis ci` wrapper)
- Adds teeth without adding noise — it won’t break your build on false positives
Measured precision
We scanned 450 real, public Supabase apps
Of the 445 that ship RLS, 8.1% had a policy that authenticates but does not authorize. A naive detector over-reports this at 19.3% — about 83% of which are false positives. Aegis eliminated every false-positive class against real data and holds precision 1.0 (zero residual false positives).
- 8.1%have RLS that authenticates but doesn’t scope to the owner
- 450public apps statically scanned
- 0residual false positives (precision 1.0)
“Not owner-scoped” ≠ “vulnerable” — some tables are shared on purpose. That’s why the finding is medium, non-blocking, “verify this is intended,” not fear-mongering.
Read the full studyQuickstart
Start with three commands
No install, no config. First `scan` to surface the current state, then `init` to harden the runtime, then `probe` to confirm at runtime.
- Scan— No install or config — statically analyzes your current project
npx @aegiskit/cli scan - Harden runtime— Adds headers/CSP, rate limiting, CSRF, and a typed env boundary via middleware
npx @aegiskit/cli init - Confirm at runtime— Sends safe, non-destructive probes to your app to confirm static findings at runtime
npx @aegiskit/cli probe http://localhost:3000 --correlate
Add it to CI (SARIF → GitHub code scanning)
Only high-confidence findings fail the build, and the dataflow trace lands in GitHub code scanning as a clickable path.
# .github/workflows/security.yml
name: Security
on: [push, pull_request]
jobs:
aegis:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write # upload SARIF to the Security tab
steps:
- uses: actions/checkout@v4
- uses: tomodahinata/aegis@main
with:
severity: HIGH
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: aegis.sarifHonest scope — what Aegis does NOT do
The “we installed it, so we’re fine” reflex is exactly what produces the worst security outcomes. So here’s what it can’t do, stated first.
- It does not prove your authorization is correct. It reads the shape of a policy or implementation, not the meaning of your business rules and data model.
- Dataflow analysis is intraprocedural (within a function). Flows that cross modules or the framework are missed.
- It does not replace RLS design, code review, threat modeling, or manual penetration testing. It complements them.
- A clean run means “you haven’t hit the common traps,” not “this code is safe.”
Even so, mechanically closing the highest-frequency holes is worth a great deal: detection grows teeth, noise stays low, and people focus on the genuinely hard judgment — design and authorization.
FAQ
Frequently asked questions
Is Aegis free?
Yes. It’s MIT-licensed open source, usable right now via `npx @aegiskit/cli`. Scanning, runtime hardening, and CI integration are all free.
If I add Aegis, is my app “completely safe”?
No — a tool that claims so is dangerous (the “we installed it, so we’re fine” reflex produces the worst outcomes). Aegis automates the horizontal controls and only detects and warns on the vertical risks a library can’t fix (authorization/IDOR, business logic). It complements secure design, code review, and manual pentesting — it does not replace them.
Can I use it outside Next.js / Supabase?
The core (@aegiskit/core) is a set of runtime-agnostic primitives — headers/CSP, rate limiting, typed env, and more are generally usable. The Next.js (App Router) adapter and Supabase RLS verification are the parts optimized for those two.
Will false positives break my CI?
By default only high-confidence findings fail CI. It further promotes a static “suspicion” to build-blocking only when a dynamic probe reproduces it — so it stops real risk without adding noise. Across 450 real public Supabase apps, the flagship rule held zero residual false positives (precision 1.0).
Does it help review AI-generated code?
That’s exactly the use case. It mechanically surfaces the injection, RLS, and authorization traps that AI-generated Next.js × Supabase code routinely creates, and `aegis fix --format json` hands a fix plan to your coding agent.
How do I fix the authorization/IDOR issues it finds?
That part is outside a library’s reach — it’s your design decision. How you write RLS, the ownership checks on service_role paths, and tenant isolation must be closed with design and review. If you need hands, I offer that design review and implementation.
Next step
Try the free OSS right now. And if you need a design review to actually close the “vertical risks” it finds, I take that on.
Request a design review
The vertical risks it found — I’ll close them
Authorization/IDOR, Supabase RLS design, and tenant isolation are outside a library’s reach — they’re design decisions. I review authorization on existing Next.js × Supabase apps and design + implement the fixes for what was found.
See the security auditSpot review from $680 · standard audit from $1,900. Starts with a free 30-min call.
Try it yourself first
Free and open source, right now
No install. Scan your current project with one command. MIT-licensed — modify and use commercially, freely.
npx @aegiskit/cli scanA paid “Aegis Team” tier is in the works.Join the waitlist