Skip to content

Security Hardening

LaunchKit Pro includes a configurable security foundation — rate limiting, optional CAPTCHA, security headers, CORS strict mode, and expanded audit logging.

Defaults (safe install)

FeatureDefaultNotes
Rate limitingRATE_LIMIT_ENABLED=trueIn-memory IP/user buckets
CAPTCHACAPTCHA_ENABLED=falseForms work without external provider
CAPTCHA providerMOCKNo keys required
Security headersSECURITY_HEADERS_ENABLED=trueHelmet on API, conservative headers on Next.js
CORS strict modeCORS_STRICT_MODE=trueOnly allowed origins (+ FRONTEND_URL)
Audit loggingAUDIT_LOG_ENABLED=trueSecrets never stored in metadata

No paid CAPTCHA or external security service is required for a normal install.

Rate limiting

See Rate Limiting for tier details and env vars.

Friendly 429 response:

json
{
  "statusCode": 429,
  "message": ["Too many requests. Please try again later."]
}

CAPTCHA

Providers: MOCK, TURNSTILE, RECAPTCHA.

  • CAPTCHA_ENABLED=false — verification skipped; forms unchanged.
  • CAPTCHA_PROVIDER=MOCK — accepts test tokens (mock-valid, mock_*); no external API.
  • Turnstile/reCAPTCHA — foundation only; set secret keys on backend when ready.

Applied only when configured:

  • Contact form (CAPTCHA_REQUIRED_FOR_CONTACT)
  • Support tickets (CAPTCHA_REQUIRED_FOR_SUPPORT)
  • Registration (CAPTCHA_REQUIRED_FOR_SIGNUP)

Public status: GET /security/status
Admin status: GET /admin/security/status
Frontend admin page: /admin/security

CAPTCHA secret keys stay backend-only.

Security headers

Backend (NestJS): Helmet when SECURITY_HEADERS_ENABLED=true; X-Powered-By disabled; JSON body limit 1mb.

Frontend (Next.js): X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy.

A strict Content-Security-Policy is not enabled by default — it can break API calls, uploads, and docs embeds. Add CSP in production when you have tested your asset origins.

CORS

Allowed origins: FRONTEND_URL, CORS_ALLOWED_ORIGINS, and http://localhost:3000.

With CORS_STRICT_MODE=true, development localhost bypass on arbitrary ports is disabled — add extra origins to CORS_ALLOWED_ORIGINS (e.g. http://localhost:5173 for local docs).

Rejected origins return: Origin not allowed by CORS.

Audit logs

See Audit Logs. Metadata is sanitized — passwords, tokens, API keys, license keys, and webhook secrets are never logged.

Production recommendations

  1. Keep RATE_LIMIT_ENABLED=true behind Nginx with TRUST_PROXY=true.
  2. Enable CAPTCHA on public contact when exposed to the internet.
  3. Set CORS_STRICT_MODE=true and list only your app/docs origins.
  4. Set API_DOCS_ENABLED=false in production if Swagger is not needed.
  5. Use strong JWT secrets and rotate provider keys via env — never commit .env.

LaunchKit Pro by LaunchKit Labs — buyer documentation. No secrets in this site.