🚧 FastCMS is under active development — not ready for production use. APIs and features may change without notice.
FastCMS
Security

Production Hardening

Security hardening for production deployments — secret rotation, CORS, cookies, API schema protection.

Production Hardening

FastCMS includes several security hardening features that activate automatically in production (ENVIRONMENT=production).

Secret Key Rotation

Rotating SECRET_KEY invalidates all existing JWT tokens, logging out every user. To avoid this, FastCMS supports a previous key for a smooth transition.

Rotation Steps

  1. Copy your current SECRET_KEY to SECRET_KEY_PREVIOUS
  2. Generate a new SECRET_KEY:
    openssl rand -hex 32
  3. Deploy with both keys set
  4. Wait for old tokens to expire (max 30 days for refresh tokens)
  5. Remove SECRET_KEY_PREVIOUS

Configuration

SECRET_KEY=your-new-secret-key-here
SECRET_KEY_PREVIOUS=your-old-secret-key-here

During the rotation period:

  • New tokens are always signed with SECRET_KEY
  • Old tokens validate against SECRET_KEY_PREVIOUS as a fallback
  • This applies to access tokens, refresh tokens, file access tokens, and impersonation tokens

API Schema Protection

In production, the OpenAPI schema and documentation UIs are completely disabled:

RouteDevelopmentProduction
/docs (Swagger UI)AvailableDisabled (404)
/redoc (ReDoc)AvailableDisabled (404)
/openapi.json (Schema)AvailableDisabled (404)

This is controlled by the DEBUG flag:

# Development
DEBUG=true

# Production
DEBUG=false

CORS Configuration

CORS is restricted to specific methods and headers:

Allowed methods: GET, POST, PUT, PATCH, DELETE, OPTIONS

Allowed headers: Authorization, Content-Type, X-API-Key, X-Requested-With, Accept

Configure allowed origins in .env:

# Single origin
CORS_ORIGINS=https://your-app.com

# Multiple origins (comma-separated)
CORS_ORIGINS=https://your-app.com,https://admin.your-app.com

All cookies enforce security attributes based on environment:

CookieHttpOnlySecureSameSite
fastcms_sessionYesProduction onlyLax
oauth_collectionYesProduction onlyLax
  • HttpOnly prevents JavaScript access (XSS protection)
  • Secure ensures cookies are only sent over HTTPS
  • SameSite=Lax prevents CSRF while allowing top-level navigation

Security Headers

All responses include security headers automatically. See Security Headers for details.

ENVIRONMENT=production
DEBUG=false
SECRET_KEY=<generated-with-openssl-rand-hex-32>

# Restrict CORS to your frontend domain
CORS_ORIGINS=https://your-app.com

# Enable rate limiting
RATE_LIMIT_ENABLED=true
RATE_LIMIT_PER_MINUTE=100
RATE_LIMIT_PER_HOUR=1000

# Enable account lockout
ACCOUNT_LOCKOUT_ENABLED=true
ACCOUNT_LOCKOUT_ATTEMPTS=5
ACCOUNT_LOCKOUT_DURATION=1800

# Strong password policy
PASSWORD_MIN_LENGTH=10
PASSWORD_REQUIRE_UPPERCASE=true
PASSWORD_REQUIRE_LOWERCASE=true
PASSWORD_REQUIRE_DIGIT=true
PASSWORD_REQUIRE_SPECIAL=true

Checklist

Before deploying to production:

  • Set ENVIRONMENT=production and DEBUG=false
  • Generate a strong SECRET_KEY with openssl rand -hex 32
  • Restrict CORS_ORIGINS to your frontend domain(s)
  • Configure SMTP for security notification emails
  • Use PostgreSQL instead of SQLite
  • Put FastCMS behind a reverse proxy (nginx, Caddy) for TLS termination
  • Enable rate limiting and account lockout
  • Review IP filtering rules if needed

On this page