Configuration & secrets
Relay reads all configuration through the standard ASP.NET Core stack, so any value can be overridden without editing a committed file.
#Precedence
Highest wins:
- Command-line arguments
- Environment variables
- User-secrets (Development only)
appsettings.{Environment}.jsonappsettings.json
In Development, appsettings.Development.json overrides appsettings.json.
#Secrets
Never commit real secrets. Supply them via environment variables (or Key Vault) in shared/production environments, and user-secrets locally. The repo's docs/secrets.md has the list of what to move and a rotation runbook.
- Provider API keys are stored encrypted at rest. A key pasted into the panel is encrypted with AES-256-GCM (
Encryption:MasterKey) intoProvider.ApiKeyEncrypted, decrypted by the gateway per call, and never returned to the browser. A Provider'sSecretRef— the name of a config key, read byConfigurationProviderSecretResolverat call time — is the fallback for a provider with no stored key, for teams that prefer rotating keys through configuration. A stored key wins overSecretRef; Ollama needs neither. - The encryption master key (
Encryption:MasterKey, base64, 32 bytes) protects every at-rest secret: provider keys, the Azure discovery client secret, connector client secrets and users' OAuth tokens, workflow credentials and webhook tokens. It also derives the HMAC key for the Playground's panel-to-gateway delegation token. It must be identical on theApplicationhost and onApplication.Api, or decryption fails on one side. - MCP server bearer tokens are not encrypted today; treat the MCP registry accordingly.
#Where each app reads config
- Application.Api (gateway) reads
ConnectionStrings:GatewayDb,Encryption:MasterKey, the wholeGateway:*tree (routing, cache, moderation, files, RAG, data app, connectors, workflows, batch/eval, health, alerts, OTLP),ClickHouse:*,Telemetry:*,Qdrant:*, and any providerSecretRef. - Application (panel host) reads
ConnectionStrings:GatewayDbandConnectionStrings:UserManagementDb, the identity-app sign-in settings (Identity:BaseUrl,ClientId,ClientSecret,CallbackPath,Scope),Encryption:MasterKey,Gateway:InternalBaseUrl/Gateway:PublicBaseUrl(to reach the gateway for the Playground, workflow approvals and webhooks),Gateway:Data:*(the dataset picker),Qdrant:*,Connectors:RedirectUri,Telemetry:Panel:ShowBodies,EmailSettings:*, and the sameClickHouse:*/Telemetry:*settings so the dashboard and observability pages can query.
#Common settings
A minimal gateway appsettings.Development.json:
{
"ConnectionStrings": {
"GatewayDb": "Server=127.0.0.1;Database=relay_gateway;Trusted_Connection=True;TrustServerCertificate=True"
},
"Encryption": { "MasterKey": "<base64, 32 bytes — same value on the panel host>" },
"Gateway": {
"DefaultModel": "gpt-4o",
"FallbackModel": "gpt-4o-mini",
"MaxRetries": 2,
"Cache": { "TtlSeconds": 0 }
},
"Qdrant": { "Url": "http://127.0.0.1:6333" },
"ClickHouse": { "ConnectionString": "Host=127.0.0.1;Port=8123;Username=default;Password=;Database=default" }
}
The full list of keys — routing, caching, moderation, files, RAG, dataset agents, connectors, workflows, batch/eval, health probing, alerting, telemetry and OTLP — is in the Configuration reference.
#Dashboard source and OTLP export
Relay always writes its observability store (relay_observation, relay_score) when ClickHouse:ConnectionString is set; the trace, session, score and evaluator pages depend on it. Two independent switches sit beside that:
Gateway:Otlp:Enabled— additionally export traces, logs and metrics over OTLP/HTTP to a ClickStack collector, so HyperDX shows the same trace tree.Telemetry:DashboardSource—clickhouse(default) reads the usage Dashboard and Telemetry pages fromrelay_observation;otelreads those two pages from the collector'sotel_tracestable instead.
Telemetry:Backend, which older builds used for this, is no longer read; a value left in configuration is ignored. See Telemetry & dashboards.