Documentation

Everything you need to get septr running in your app.

Quick start

Install the package and add one line of middleware. Septr starts protecting your app immediately.

$ npm install septr

Add your API key to your environment:

SEPTR_API_KEY=septr_live_...

Then wrap your app with the middleware for your framework:

import { createSeptr } from "septr"

app.use(createSeptr({
  apiKey: process.env.SEPTR_API_KEY
}))
Fail-open guarantee: If Septr ever throws, it logs the error and passes the request through. Your app never goes down because of its bodyguard.

Framework guides

Septr supports Express, Next.js, Hono, Fastify, Flask, FastAPI, Gin, net/http, and Streamlit (via CLI/network). Pick your framework:

Express Next.js Hono Fastify Flask FastAPI Gin net/http Streamlit

Express

import express from "express"
import { createSeptr } from "septr"

const app = express()

app.use(createSeptr({
  apiKey: process.env.SEPTR_API_KEY
}))

app.listen(3000)

Configuration

Pass options to createSeptr() to customize behavior. All engines are enabled by default.

OptionTypeDefaultDescription
apiKeystringenv SEPTR_API_KEYYour project API key
strictModebooleanfalseBlock requests instead of detecting
secretsbooleantrueSecret/PII detection + response scrubbing
bolabooleantrueBOLA/IDOR detection
rateLimitbooleantruePer-route rate limiting
inputSanitizebooleantrueSQLi/XSS/NoSQLi sanitization
ssrfbooleantrueSSRF heuristics
promptInjectionbooleantruePrompt-injection shielding
aiRateLimitbooleantrueRate limiting for AI endpoints
tamperbooleantrueBusiness-logic tamper detection
missingAuthbooleantrueMissing-auth detection
stripFieldsstring[][]Fields to strip from responses
telemetryUrlstringhttps://api.septr.com/v1/eventsTelemetry endpoint
remoteConfigbooleantruePoll backend for live config

Example with all options

app.use(createSeptr({
  apiKey: process.env.SEPTR_API_KEY,
  strictMode: false,
  secrets: true,
  bola: true,
  rateLimit: true,
  inputSanitize: true,
  ssrf: true,
  promptInjection: true,
  aiRateLimit: true,
  tamper: true,
  missingAuth: true,
  stripFields: ["password_hash", "ssn"],
  remoteConfig: true,
}))

Detection engines

Septr runs 12 detection engines in-process. Each one scans every request/response in memory and emits evidence to your dashboard.

Secrets (22 patterns)

Scans response bodies for leaked credentials. Matches against 22 patterns including:

  • OpenAI API keys (sk-)
  • Stripe keys (sk_live_, rk_live_)
  • AWS access keys (AKIA)
  • GitHub tokens (ghp_, gho_)
  • JWTs and private keys
  • Database connection strings

Matched values are replaced with [REDACTED] in the response.

BOLA / IDOR

Compares JWT claims (sub, user_id) against route parameters (:id, :userId). If a user tries to access another user's resource, the request is blocked with a 403.

GET /api/users/8812  Authorization: Bearer eyJ…
jwt.sub=4417 ≠ route.id=8812 → 403 Forbidden

SQLi / XSS

SQLi: 14 patterns — UNION SELECT, OR 1=1, DROP TABLE, WAITFOR DELAY, and more.

XSS: 17 patterns — <script>, onerror, javascript:, event handlers.

Both are detected in request bodies and query strings.

Prompt injection

24 jailbreak patterns including:

  • DAN / "Do Anything Now" prompts
  • Role overrides ("ignore previous instructions")
  • System prompt extraction attempts
  • Tool-call manipulation

SSRF

Blocks requests targeting internal resources:

  • Internal IPs: 127.0.0.0/8, 10.0.0.0/8, 192.168.x.x
  • Cloud metadata: 169.254.169.254
  • Dangerous protocols: file://, gopher://

Rate limiting

Sliding-window rate limiting per IP and route. Default tiers:

Endpoint typeLimit
General60 requests/min
Auth endpoints10 requests/min
AI endpoints5 requests/min

Static assets (/static/, /_next/, images, CSS, JS) bypass the pipeline automatically.

Environment variables

VariableDescription
SEPTR_API_KEYYour project API key (required)
SEPTR_SILENCE_ENV_WARNINGSet to 1 to silence the missing-key warning
SEPTR_REMOTE_CONFIGSet to false to disable remote config polling

Performance

Septr runs entirely in-process with no external calls on the hot path:

  • <5ms p50 overhead per request (measured across all engines)
  • Sub-2ms pattern matching per engine (in-memory regex)
  • Static asset bypass — 14 path prefixes + 13 file extensions skip the pipeline
  • Async telemetry — events buffered in-memory, flushed every 30s or at batch size 50
  • Zero memory growth under sustained load (verified at 1000 rate-limit checks in 0.4ms)

Troubleshooting

Missing API key warning

If you see a warning about SEPTR_API_KEY, make sure the environment variable is set before starting your app. In development:

SEPTR_API_KEY=septr_live_... node app.js

To suppress the warning in environments where the key is injected at runtime:

SEPTR_SILENCE_ENV_WARNING=1

Engine not detecting

All engines are enabled by default. If you disabled one for testing, re-enable it and restart your app. Check your config:

createSeptr({
  apiKey: process.env.SEPTR_API_KEY,
  // make sure these are all true:
  secrets: true,
  bola: true,
  rateLimit: true,
  inputSanitize: true,
  ssrf: true,
  promptInjection: true,
})

Telemetry not reaching dashboard

Make sure:

  • The API key is correct and the project is active
  • Septr middleware is mounted before your routes
  • Your server has outbound access to the telemetry endpoint
  • Restart your app and wait ~30 seconds for the first telemetry flush

Source scanning

Run septr scan . in your project root to scan source files for secrets, SQLi/XSS payloads, and SSRF indicators. Findings are reported with file:line, and the exit code is 1 when findings meet --fail-on (default high) — useful for CI gates.

Excluding files

Test fixtures and generated files can contain intentional attack payloads. Exclusions are explicit and committed, never silent:

  • .septrignore — gitignore-style patterns at your project root. Committed to the repo so exclusions are auditable.
  • --exclude — repeatable CLI flag for one-off runs: septr scan . --exclude "src/__tests__/**"
# .septrignore
# test fixtures contain intentional attack payloads — not vulnerabilities
src/__tests__/
# generated bundles are rebuilt, not fixed
dist/

Test fixture payloads (__tests__/benchmark/**, *-payloads.*, fixtures/**) are skipped by default. Everything else is scanned — including tests — so real secrets in test files are still caught.

npx septr scan . --json emits machine-readable findings; --quiet suppresses the summary.