Skip to content

Security

CORS Configuration

The server restricts cross-origin requests to a whitelist of allowed origins. By default only the FRONTEND_URL is allowed.

Env var Default Description
ALLOWED_ORIGINS FRONTEND_URL value Comma-separated list of allowed origins

Origins can also be managed at runtime via Admin > Security Settings in the web UI (settings:manage permission required).

CSRF Protection

State-changing requests (POST, PUT, PATCH, DELETE) require a valid CSRF token when cookie-based sessions are active (OIDC enabled).

  • On login, the server sets a floh_csrf cookie (not httpOnly).
  • The frontend reads this cookie and sends it as the X-CSRF-Token header on mutating requests.
  • The server validates that the header matches the cookie value.
  • CSRF protection is automatically disabled when OIDC is not configured (dev mode).

API clients using Bearer tokens are not affected by CSRF checks.

Webhook Authentication

Connector webhook endpoints require HMAC-SHA256 signature verification.

  1. Configure a webhook secret on the connector (stored encrypted in the DB).
  2. The caller computes HMAC-SHA256(secret, request_body) and sends it as the X-Webhook-Signature header.
  3. The server verifies the signature before processing the event.

Requests without a valid signature receive a 401 Unauthorized response.

Rate Limiting

The server applies rate limiting via @fastify/rate-limit:

Scope Limit Window
Global 200 req 1 minute
/api/auth/* 20 req 1 minute
/api/entitlements/webhook/* 30 req 1 minute

Localhost (127.0.0.1, ::1) is excluded from rate limits during development.

Session Security

Property Value
Cookie name floh_sid
httpOnly true
secure true when FRONTEND_URL starts with https
sameSite lax
TTL 24 hours
Encryption Optional via SESSION_ENCRYPTION_KEY (64-char hex)
Storage Redis with key floh:session:{id}

Dev Auth Bypass Guard

In production (NODE_ENV=production), the server refuses to start if OIDC_ISSUER is not set. This prevents the dev auth bypass from accidentally running in production.

Secret Management

The following secrets must be explicitly set in production. The server will refuse to start if any of them use their default/fallback values:

Secret Env var Default (dev only)
JWT secret JWT_SECRET dev-jwt-secret
Database password DB_PASSWORD floh_secret
Session secret SESSION_SECRET Same as JWT_SECRET
Connector encryption CONNECTOR_ENCRYPTION_KEY Insecure dev key
Session encryption SESSION_ENCRYPTION_KEY Unencrypted storage

Generate encryption keys with:

openssl rand -hex 32

Error Handling

In production, API error responses contain only statusCode, error, and a generic message. Stack traces and internal details are never exposed. In development, stack traces are included when SHOW_ERROR_DETAILS=true.

Production Checklist

  • [ ] NODE_ENV=production
  • [ ] OIDC_ISSUER is set
  • [ ] JWT_SECRET is a strong random value
  • [ ] DB_PASSWORD is not the default
  • [ ] SESSION_SECRET is a strong random value
  • [ ] CONNECTOR_ENCRYPTION_KEY is a 64-char hex key
  • [ ] SESSION_ENCRYPTION_KEY is a 64-char hex key
  • [ ] AUDIT_CHECKPOINT_KEY is a 64-char hex key
  • [ ] ALLOWED_ORIGINS is restricted to known frontend URLs
  • [ ] SHOW_ERROR_DETAILS=false
  • [ ] Rate limiting is enabled