Skip to main content

Security Warning: Environment-Specific Authentication

CRITICAL: APP_ENV=dev MUST NEVER be deployed to any public-facing environment

When APP_ENV=dev, the application registers a zero-authentication bypass at /dev-sign-in that grants full dashboard access without any credentials. This is intentional for local development but represents a complete authentication bypass if deployed publicly.

What happens in each environment

EnvironmentAuth MethodSecurity LevelDeployable?
APP_ENV=devMock auth bypass at /dev-sign-in + ClerkZERO AUTH — anyone can enterNO — local only
APP_ENV=testClerk + email allowlist gateRestricted to approved testersYes (staging)
APP_ENV=prodClerk only (standard)Full production authYes

Dev mode bypass details

When APP_ENV=dev:
  1. /dev-sign-in page is registered — allows instant sign-in as demo user with no credentials
  2. AuthState.post_auth accepts MockAuthState.is_authenticated — skips the Clerk redirect for mock-authed sessions
  3. Protected page content wrapper shows content when MockAuthState.is_authenticated is True — bypasses ClerkState.is_signed_in
  4. No rate limiting, no CAPTCHA, no verification on the mock sign-in

How to verify your deployment is safe

# Check what APP_ENV is set on Railway / your deployment platform
echo $APP_ENV
# Must be "test" or "prod" — NEVER "dev"

# Verify /dev-sign-in returns 404 (not registered)
curl -s https://your-deployment.up.railway.app/dev-sign-in | head -5
# Should be a 404 or redirect, NOT a sign-in page

CI/CD safeguards

The GitHub Actions workflow (.github/workflows/deploy.yml) maps branches to environments:
  • mainAPP_ENV=PROD
  • test / dev-*APP_ENV=TEST
APP_ENV=dev is never set in CI/CD. It exists only in envs/dev which is gitignored.

Test environment protections

When APP_ENV=test:
  • Email allowlist gate in AuthState.sync_auth_state — only emails in ADMIN_USER_EMAILS env var (plus hardcoded mymm.psu@gmail.com and nikhil.yadala@gmail.com) can access
  • Unauthorized users are signed out via Clerk.signOut() with “Access restricted” message
  • /dev-sign-in page is NOT registered (only registered when is_dev() returns True)

Files involved

FileDev behavior
pages/user/dev_sign_in.pyRegisters /dev-sign-in page only when is_dev()
states/shared/mock_auth.pyMockAuthState.dev_sign_in — sets auth without Clerk
states/shared/clerk_auth.pypost_auth checks MockAuthState in dev before redirecting
components/layout/page_wrapper.pyContent wrapper accepts MockAuthState in dev