Configuration

Diminuendo is configured entirely through environment variables, loaded at startup via Effect’s Config module. There are no configuration files, no YAML, no JSON. Every configurable value has a sensible default, and the gateway will start with zero environment variables set (in dev mode).

Environment Variables

VariableTypeDefaultDescription
PORTnumber8080HTTP/WebSocket server port
HOSTNAMEstring0.0.0.0Server bind address
NODE_ENVstringdevelopmentEnvironment identifier
DEV_MODEbooleanfalseEnable dev mode (overrides NODE_ENV check)
AUTH_CLIENT_IDstring""Auth0 client ID for JWT verification
AUTH_CLIENT_SECRETRedacted""Auth0 client secret
AUTH_URLstring""Auth0 domain URL
ALLOWED_ORIGINSstring""Comma-separated list of allowed CORS/CSRF origins
PODIUM_URLstringhttp://localhost:5082Podium coordinator base URL
PODIUM_API_KEYRedacted""Podium API bearer token
PODIUM_ADMIN_API_KEYRedacted""Podium admin key for agent deployment
PODIUM_SECRETS_KEYRedacted""Podium encryption key for secrets management
ENSEMBLE_URLstringhttp://localhost:5180Ensemble inference proxy base URL
ENSEMBLE_API_KEYRedacted""Ensemble API bearer token
E2B_API_KEYRedacted""E2B sandbox API key
E2B_DOMAINstringe2b-dev.igent.devE2B sandbox domain
DATA_DIRstring./dataRoot directory for SQLite databases
LOG_LEVELstringinfoMinimum log level (trace, debug, info, warning, error, fatal)
OTEL_EXPORTER_OTLP_ENDPOINTstring(none)OpenTelemetry collector endpoint. Tracing is disabled if unset
OTEL_SERVICE_NAMEstringdiminuendo-gatewayService name for OTel spans

Dev Mode

Dev mode is enabled when either DEV_MODE=true or NODE_ENV=development. It activates several behaviors that simplify local development:

Auth Bypass

Authentication is bypassed entirely. Every WebSocket connection is automatically authenticated with a dev identity (dev-user-001, developer@example.com, tenant dev).

All Origins Allowed

CSRF and origin checks are disabled. The gateway accepts WebSocket upgrades from any origin, enabling connections from localhost dev servers on any port.

Pretty Logging

Log output uses Effect’s pretty-print logger instead of JSON, making log lines readable in a terminal.

Insecure Protocol Warnings Suppressed

Warnings about using HTTP (vs HTTPS) for upstream service URLs are relaxed.
Never enable dev mode in a production deployment. It disables all authentication and authorization checks.

Secrets Management

Five configuration values are stored as Effect Redacted<string> values: AUTH_CLIENT_SECRET, PODIUM_API_KEY, PODIUM_ADMIN_API_KEY, PODIUM_SECRETS_KEY, and ENSEMBLE_API_KEY. The Redacted wrapper prevents accidental logging — if the config object is logged (intentionally or via error serialization), redacted fields render as <redacted> rather than exposing the secret value.
// Secrets are loaded as Redacted
authClientSecret: yield* Config.redacted("AUTH_CLIENT_SECRET")
  .pipe(Config.withDefault(Redacted.make("")))

// Access the underlying value explicitly
const apiKey = Redacted.value(config.podiumApiKey)
The Redacted.value() call makes the secret extraction explicit in code, making it easy to audit where secrets are consumed. Grep for Redacted.value to find every point where a secret is unwrapped.

Data Directory Structure

The DATA_DIR environment variable (default: ./data) defines the root directory for all persistent storage. The gateway creates the following directory structure on startup:
$DATA_DIR/
  tenants/
    {tenantId}/
      registry.db          # Session metadata (SQLite, WAL mode)
  sessions/
    {sessionId}/
      session.db           # Conversation history, events, turn usage (SQLite, WAL mode)

Registry Database

Each tenant has a registry.db containing:
  • sessions table — session metadata: id, name, agent type, status, timestamps, archived flag
  • tenant_members table — membership records: user ID, role, timestamps

Session Database

Each session has a session.db containing:
  • messages table — conversation history: role, content, metadata, turn ID, timestamps
  • events table — persistent gateway events: type, sequence number, payload JSON, timestamps
  • turn_usage table — per-turn token usage: model, input/output tokens, cached tokens, cost
Databases are created lazily on first access. A newly created tenant has no registry.db until the first session is created. A newly created session has no session.db until the first message or event is persisted.

Configuration Loading

The configuration is loaded as an Effect Layer, meaning it participates in the dependency injection graph:
export class AppConfig extends Context.Tag("AppConfig")<AppConfig, AppConfigShape>() {}

export const AppConfigLive = Layer.effect(AppConfig, configEffect)
Every service that needs configuration declares AppConfig as a dependency. The Layer graph wires it in at composition time. No service reads environment variables directly — all access goes through the typed AppConfigShape interface.

Validation

The configuration layer performs validation during construction:
  • If ENSEMBLE_URL is set to a non-default value but ENSEMBLE_API_KEY is empty, a warning is logged
  • If PODIUM_URL uses HTTP (not HTTPS) in non-dev mode, a warning is logged
  • Invalid values for typed fields (e.g., non-numeric PORT) cause the Effect config to fail, which prevents the gateway from starting with misconfigured values

Minimal Production Configuration

A minimal production deployment requires:
# Required for authentication
AUTH_CLIENT_ID=your-auth0-client-id
AUTH_CLIENT_SECRET=your-auth0-client-secret
AUTH_URL=https://your-tenant.auth0.com

# Required for agent orchestration
PODIUM_URL=https://podium.example.com
PODIUM_API_KEY=your-podium-api-key

# Required for security
ALLOWED_ORIGINS=https://app.example.com

# Recommended
DATA_DIR=/var/lib/diminuendo/data
LOG_LEVEL=info
NODE_ENV=production
All other variables have sensible defaults and can be omitted unless the deployment requires specific customization.