Environment Variables
Complete reference of all environment variables used by CORTEX services.
Core Service Variables
Required Variables
| Variable | Description | Example |
|---|---|---|
DATABASE_URL | PostgreSQL connection string | postgresql://user:pass@host:5432/cortex |
JWT_SECRET | Access token signing secret (min 32 chars) | your-super-secret-jwt-key-at-least-32-chars |
JWT_REFRESH_SECRET | Refresh token signing secret | your-refresh-secret-key-at-least-32-chars |
Server Configuration
| Variable | Default | Description |
|---|---|---|
PORT | 8091 | HTTP server port |
NODE_ENV | development | Environment (development, staging, production) |
CORS_ORIGINS | http://localhost:3090 | Comma-separated allowed origins |
API_PREFIX | /api/v1 | API route prefix |
JWT Configuration
| Variable | Default | Description |
|---|---|---|
JWT_ACCESS_EXPIRY | 15m | Access token lifetime |
JWT_REFRESH_EXPIRY | 7d | Refresh token lifetime |
JWT_ALGORITHM | HS256 | JWT signing algorithm |
Security Configuration
| Variable | Default | Description |
|---|---|---|
RATE_LIMIT_TTL | 60 | Rate limit window (seconds) |
RATE_LIMIT_MAX | 100 | Max requests per window |
LOCKOUT_THRESHOLD | 5 | Failed attempts before lockout |
LOCKOUT_DURATION_MINUTES | 15 | Lockout duration |
BCRYPT_ROUNDS | 12 | Password hashing rounds |
Redis Configuration
| Variable | Default | Description |
|---|---|---|
REDIS_URL | - | Redis connection URL |
REDIS_HOST | localhost | Redis host (if not using URL) |
REDIS_PORT | 6379 | Redis port |
REDIS_PASSWORD | - | Redis password |
REDIS_TLS | false | Enable TLS for Redis |
Logging Configuration
| Variable | Default | Description |
|---|---|---|
LOG_LEVEL | info | Log level (debug, info, warn, error) |
LOG_FORMAT | json | Log format (json, pretty) |
Frontend Variables
Next.js Environment
| Variable | Description |
|---|---|
NEXT_PUBLIC_API_URL | Backend API URL |
NEXT_PUBLIC_APP_NAME | Application name |
NEXT_PUBLIC_ENVIRONMENT | Current environment |
Example .env Files
Development (.env.development)
# Server
NODE_ENV=development
PORT=8091
# Database
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/cortex?schema=public"
# JWT
JWT_SECRET="development-jwt-secret-key-at-least-32-characters"
JWT_REFRESH_SECRET="development-refresh-secret-key-at-least-32-characters"
JWT_ACCESS_EXPIRY=1h
JWT_REFRESH_EXPIRY=7d
# Security (relaxed for dev)
RATE_LIMIT_MAX=1000
LOCKOUT_THRESHOLD=10
# CORS
CORS_ORIGINS=http://localhost:3090,http://localhost:3000
# Redis (optional in dev)
# REDIS_URL=redis://localhost:6379
# Logging
LOG_LEVEL=debug
LOG_FORMAT=pretty
Production (.env.production)
# Server
NODE_ENV=production
PORT=8091
# Database (from Azure Key Vault)
DATABASE_URL="${AZURE_DATABASE_URL}"
# JWT (from Azure Key Vault)
JWT_SECRET="${AZURE_JWT_SECRET}"
JWT_REFRESH_SECRET="${AZURE_JWT_REFRESH_SECRET}"
JWT_ACCESS_EXPIRY=15m
JWT_REFRESH_EXPIRY=7d
# Security (strict)
RATE_LIMIT_TTL=60
RATE_LIMIT_MAX=100
LOCKOUT_THRESHOLD=5
LOCKOUT_DURATION_MINUTES=15
# CORS
CORS_ORIGINS=https://app.cortex.purplelab.ai
# Redis
REDIS_URL="${AZURE_REDIS_URL}"
REDIS_TLS=true
# Logging
LOG_LEVEL=info
LOG_FORMAT=json
Azure Key Vault Integration
Store sensitive variables in Key Vault:
// Fetch from Key Vault at startup
const { DefaultAzureCredential } = require('@azure/identity');
const { SecretClient } = require('@azure/keyvault-secrets');
const credential = new DefaultAzureCredential();
const client = new SecretClient('https://cortex-kv.vault.azure.net/', credential);
async function loadSecrets() {
const jwtSecret = await client.getSecret('jwt-secret');
process.env.JWT_SECRET = jwtSecret.value;
}
Variable Validation
CORTEX validates environment variables at startup:
// src/config/configuration.ts
import { plainToClass } from 'class-transformer';
import { IsString, MinLength, validateSync } from 'class-validator';
class EnvironmentVariables {
@IsString()
DATABASE_URL: string;
@IsString()
@MinLength(32)
JWT_SECRET: string;
@IsString()
@MinLength(32)
JWT_REFRESH_SECRET: string;
}
export function validate(config: Record<string, unknown>) {
const validatedConfig = plainToClass(EnvironmentVariables, config);
const errors = validateSync(validatedConfig);
if (errors.length > 0) {
throw new Error(errors.toString());
}
return validatedConfig;
}
Generating Secrets
# Generate secure random string
openssl rand -base64 32
# Generate UUID
uuidgen
# Generate strong password
openssl rand -base64 24 | tr -d '+/'