Config (Project Shell)

Security — Developer Reference

Security Reference — Developer Guide

Full technical detail is in docs/security.md in the repository root. This entry summarises the key points.

DEBUG Guard

config/settings.py reads DEBUG from the environment (default False). The local .env overrides this to True for development. The file is gitignored and never reaches Render.

SECRET_KEY Fail-Fast Guard

_DEV_SECRET_KEY = "django-insecure-dev-placeholder-change-in-production"
SECRET_KEY = env("SECRET_KEY", default=_DEV_SECRET_KEY)

if not DEBUG and SECRET_KEY == _DEV_SECRET_KEY:
    raise ValueError("SECRET_KEY must be set in production")

This causes an immediate startup crash in production if the env var is missing, rather than silently running with a known-weak key.

GitHub Actions CI

The CI workflow (.github/workflows/ci.yml) sets DEBUG=True and a throwaway SECRET_KEY in the environment for the Django system checks and Django tests steps, so the fail-fast guard does not trigger during automated runs.

HTTP Security Headers

All production-only headers live inside the if not DEBUG: block in config/settings.py (around line 55):

  • CSRF_COOKIE_SECURE = True
  • SESSION_COOKIE_SECURE = True
  • SECURE_CONTENT_TYPE_NOSNIFF = True
  • SECURE_REFERRER_POLICY = "strict-origin-when-cross-origin"
  • SECURE_HSTS_SECONDS = 31536000
  • SECURE_HSTS_INCLUDE_SUBDOMAINS = True
  • SECURE_HSTS_PRELOAD = True

SECURE_SSL_REDIRECT is intentionally absent — Render terminates SSL at the load balancer; enabling the redirect would cause an infinite loop.

Verify Locally

DEBUG=False SECRET_KEY=test python manage.py check --deploy

Also run securityheaders.com against the live URL after each production deploy.