If you discover a security vulnerability, please do not open a public GitHub issue. Instead, email the maintainers directly so we can investigate and ship a fix before the issue is widely known.
We aim to acknowledge new reports within two business days.
StreamPay Backend handles partner integrations and chain-indexer webhooks. Key security controls include:
- API key authentication with SHA-256 hashes at rest and constant-time
digest comparison (
crypto.timingSafeEqual). The middleware is enforced before JSON/raw-body parsing for protected routes. - HMAC verification of indexer webhook payloads against the raw request
body, using
INDEXER_WEBHOOK_SECRET. - Durable replay protection via a Postgres-backed
processed_indexer_eventsledger keyed by indexereventId. Signature and payload validation run before an event id is recorded, and duplicate ids are rejected atomically by the database unique constraint. - IP-based and API-key-based rate limiting through
express-rate-limit. - Strict CORS allowlists in production (no wildcard).
All routes under /api/v1/* require either x-api-key or
Authorization: ApiKey <key>. Current protected routes are
GET /api/v1/streams, GET /api/v1/streams/:id,
GET /api/v1/streams/:id/accrual-preview, and
PATCH /api/v1/streams/:id. This middleware runs before route handlers and
before JSON body parsing, so unauthenticated requests do not reach validation,
repository, or mutating handlers.
POST /webhooks/indexer requires both API key authentication and the existing
x-indexer-signature HMAC signature. API key authentication runs first, then
the raw JSON body is parsed and passed to HMAC verification. The API key layer is
an additional control and does not replace HMAC verification.
Public operational routes remain unauthenticated: GET /health and
GET /api/openapi.json.
- Dependabot is configured to open weekly PRs for npm updates.
- Run
npm auditperiodically in addition to automated tooling.
- Never commit
.envfiles or hard-code secrets. - Use
.env.exampleas the source of truth for required variables. - Rotate
INDEXER_WEBHOOK_SECRETand API keys whenever team membership changes.