Demo Mode
Demo mode provides a shared, read-only application session for product demonstrations. Visitors
enter through /demo.php, which validates a designated Read-Only Admin, issues a short-lived signed
session cookie, and redirects to the application.
Use demo mode only in a dedicated demo environment. Leave its variables unset in environments that should require normal Clerk authentication.
Prerequisites
Before enabling demo mode:
- Create or select a user whose Clerk user ID is present in the RepoRisk
userstable. - Assign the user the Read-Only Admin role.
- Confirm the user is active and their invitation has not been revoked.
- Confirm the Web and API services use the same PostgreSQL database.
Required Environment Variables
Set these values on both the Web and API services:
DEMO_USER=user_replace_with_the_designated_clerk_user_id
DEMO_AUTH_SECRET=replace_with_a_64_character_random_hex_secret
DEMO_COOKIE_DOMAIN=
DEMO_USERmust be the full Clerk user ID stored inusers.clerk_user_id, not the numeric database ID.DEMO_AUTH_SECRETmust have the same value on both services. Generate it withopenssl rand -hex 32and store it as a protected deployment secret.- Leave
DEMO_COOKIE_DOMAINempty when Web and API requests use one host. For sibling subdomains such asapp.example.comandapi.example.com, set it to.example.comon both services.
The Web service also requires:
DATABASE_URL=postgresql://user:password@host:5432/database
API_BASE_URL=https://api.example.com/api/v1
For a separate API origin, set API_CORS_ORIGINS on the API to the exact Web origin so credentialed
requests are accepted:
API_CORS_ORIGINS=https://app.example.com
Start a Demo Session
After redeploying both services, open:
https://app.example.com/demo.php
A successful request redirects to the application. Demo sessions expire after one hour. Opening
/demo.php again issues a fresh session.
Disable Demo Mode
Remove DEMO_USER, DEMO_AUTH_SECRET, and DEMO_COOKIE_DOMAIN from both services and redeploy.
Removing or changing the user or secret invalidates existing demo sessions.
Troubleshooting
Call to undefined function pg_connect()
Rebuild and redeploy the Web service from the current Dockerfile.web. The shipped image includes
PHP's PostgreSQL extension; an older cached image does not. The CI web-image job verifies that
pg_connect() exists in every newly built production image.
APCu warning or production 503
Rebuild the Web image. Current Web images install and enable APCu for the shared validation cache and rate limiter.
Demo user validation returns 403
Confirm that DEMO_USER matches users.clerk_user_id, the user has the Read-Only Admin role, the
user is active, and the Web service's DATABASE_URL points to the correct database.
API requests return 401
Confirm that DEMO_USER, DEMO_AUTH_SECRET, and DEMO_COOKIE_DOMAIN are identical on Web and API.
For split subdomains, also confirm that the cookie domain covers both hosts.
Settings keeps loading or the custom logo falls back
Redeploy both services from the current release. Demo sessions use their signed cookie for
authenticated organization settings, including custom branding, and the Settings page supports
authentication that finishes before its page-specific scripts load. If the problem remains, check
the browser network log for /api/v1/auth/me and /api/v1/settings/branding; a 401 indicates that
the API did not receive or could not validate the shared demo cookies.
Related Features
- Read-Only Roles — Understand the permissions enforced for the demo user
- Team Management — Assign and manage user roles
- Account Security — Review authentication and account security controls