Overview
Manifest is configured entirely through environment variables. All configuration is read fromprocess.env at application startup.
The backend requires a .env file at packages/backend/.env with at least BETTER_AUTH_SECRET (32+ chars). The auth.instance.ts reads process.env at import time, before NestJS ConfigModule loads .env, so env vars must be available to the Node process.
Core Variables (Required)
These variables must be set for production deployments.BETTER_AUTH_SECRET
Required. Secret for Better Auth session signing and encryption.- Type: String
- Minimum length: 32 characters
- Format: Hex string recommended
- Session token signing
- Cookie encryption
- Provider API key encryption (AES-256-GCM)
DATABASE_URL
Required in production. PostgreSQL connection string.- Type: String
- Format:
postgresql://user:password@host:port/database - Default:
postgresql://myuser:mypassword@localhost:5432/mydatabase
user— PostgreSQL usernamepassword— PostgreSQL passwordhost— Database hostname or IPport— Database port (default: 5432)database— Database name
Server Configuration
PORT
Server listening port.- Type: Number
- Default:
3001
BIND_ADDRESS
Address the server binds to.- Type: String
- Default:
127.0.0.1 - Docker/Railway: Use
0.0.0.0
Use
127.0.0.1 for local development (loopback only). Use 0.0.0.0 for Docker containers and cloud platforms to accept external connections.NODE_ENV
Runtime environment.- Type: String
- Values:
development,production,test - Default:
development
development: CORS enabled, detailed error messagesproduction: CORS disabled, trust proxy enabled, minimal logging
CORS_ORIGIN
Allowed CORS origin (development only).- Type: String or RegExp
- Default:
http://localhost:3000
NODE_ENV !== 'production'. In production, the frontend is served from the same origin as the API.
BETTER_AUTH_URL
Base URL for Better Auth.- Type: String
- Default:
http://localhost:3001 - Format: Full URL including protocol
- OAuth callback URLs
- Email verification links
- Password reset links
FRONTEND_PORT
Extra trusted origin port for Better Auth (optional).- Type: Number
- Default: None
Rate Limiting
THROTTLE_TTL
Rate limit window in milliseconds.- Type: Number
- Default:
60000(1 minute)
THROTTLE_LIMIT
Maximum requests per window.- Type: Number
- Default:
100
Authentication
API_KEY
Secret for programmatic API access viaX-API-Key header.
- Type: String
- Default: None (optional)
- CI/CD automation
- Monitoring scripts
- Programmatic access without user sessions
The API key is checked with timing-safe comparison to prevent timing attacks.
Email Configuration (Optional)
Required for email verification and password reset. Without these, the app runs but email features are silently skipped.MAILGUN_API_KEY
Mailgun API key.- Type: String
- Format: Starts with
key- - Default: None
MAILGUN_DOMAIN
Mailgun sending domain.- Type: String
- Format: Domain name
- Default: None
NOTIFICATION_FROM_EMAIL
Sender email address.- Type: String
- Format: Email address
- Default:
[email protected]
Email features (verification, password reset, notifications) only activate when both
MAILGUN_API_KEY and MAILGUN_DOMAIN are set.OAuth Providers (Optional)
Each provider only activates when bothCLIENT_ID and CLIENT_SECRET are set.
Google OAuth
- Go to Google Cloud Console
- Create OAuth 2.0 Client ID
- Add authorized redirect URI:
{BETTER_AUTH_URL}/api/auth/callback/google
GitHub OAuth
- Go to GitHub Developer Settings
- Create OAuth App
- Set callback URL:
{BETTER_AUTH_URL}/api/auth/callback/github
Discord OAuth
- Go to Discord Developer Portal
- Create Application
- Add redirect:
{BETTER_AUTH_URL}/api/auth/callback/discord
Advanced Configuration
PLUGIN_OTLP_ENDPOINT
Custom OTLP endpoint for the plugin setup UI.- Type: String
- Default: None
SEED_DATA
Seed demo data on startup (development/test only).- Type: Boolean
- Values:
true,false - Default:
false
- Admin user:
[email protected]/manifest - Tenant:
seed-tenant-001 - Agent:
demo-agent - OTLP key:
mnfst_dev-otlp-key-001 - API key:
dev-api-key-manifest-001 - 12 sample security events
- Model pricing for 100+ models
MANIFEST_MODE
Operating mode.- Type: String
- Values:
local,cloud - Default:
cloud
cloud— PostgreSQL + Better Auth (production)local— SQLite + loopback auth (development only)
Local mode uses
sql.js (WASM-based SQLite) with zero native dependencies. It’s designed for development, not production.MANIFEST_DB_PATH
SQLite file path for local mode.- Type: String
- Default:
:memory:(in-memory database)
MANIFEST_MODE=local.
MANIFEST_FRONTEND_DIR
Custom path to frontend dist directory.- Type: String
- Default: Auto-detected
MANIFEST_EMBEDDED
Skip auto-start (used by embedded server).- Type: Boolean
- Values:
true,false - Default:
false
bootstrap() from running automatically. Used when Manifest is embedded in the OpenClaw plugin.
MANIFEST_TELEMETRY_OPTOUT
Disable anonymous product analytics.- Type: Boolean
- Values:
1,0 - Default:
0
Example Configurations
Minimal Development
Production (Docker)
Production with OAuth
Security Best Practices
Secrets Management
Railway: Use the Railway dashboard to set environment variables. They’re encrypted at rest. Docker: Use Docker secrets:Environment File Permissions
Restrict access to.env files:
Rotate Secrets
RotateBETTER_AUTH_SECRET and API_KEY periodically:
- Generate new secrets
- Update environment variables
- Restart the application
- All existing sessions will be invalidated
Validation
Verify your configuration:Next Steps
Database Setup
Configure PostgreSQL, run migrations, and set up backups
Deployment Guide
Deploy Manifest with Docker, Railway, or manual setup