Skip to main content

How DIAL Core is configured

DIAL Core takes two kinds of configuration: static settings that shape the running server, and dynamic configuration that defines what it serves. This page explains where each one lives, how Core merges and reloads dynamic configuration, and which page documents each entity. It is for platform engineers who configure Core; it assumes you have read the DIAL Core overview.

Static settings and dynamic configuration​

Static settingsDynamic configuration
What it controlsThe server, outbound clients, storage, Redis, identity providers, encryption, and other runtime behaviorModels, applications, interceptors, routes, toolsets, roles, keys, translators, schemas, and global settings
Where it livesA JSON file named by AIDIAL_SETTINGS, environment variables with the aidial. prefix, and the defaults bundled with CoreJSON config files listed in config.files, and entities stored in the platform bucket of blob storage
When a change appliesAt the next restartWhile Core runs: on the next reload for files, on return for a Configuration API write
ReferenceStatic settingsThe entity pages listed below

File location​

Static settings come from the file named by the AIDIAL_SETTINGS environment variable. Config files are listed in the static setting config.files; Core has no config file by default ([]). This Docker Compose fragment mounts both:

core:
environment:
AIDIAL_SETTINGS: /opt/settings/settings.json
aidial.config.files: '["/opt/config/config.json"]'
volumes:
- ./settings:/opt/settings
- ./core:/opt/config

Where dynamic configuration is stored​

Core builds the dynamic configuration it serves from two sources:

  1. Config files. Core deep-merges the JSON files listed in config.files, in order; a later file overrides keys from an earlier one. Arrays are concatenated unless config.jsonMergeStrategy.overwriteArrays is true. A path that is not found on disk is read from the classpath.
  2. The platform bucket. Entities written through the Configuration API are stored as blobs in Core's blob storage, one blob per entity, under a canonical ID <type>/platform/<name> — for example models/platform/gpt-4o. Secret fields are encrypted before they are stored.

The Configuration API is in preview. Config files remain fully supported, and you can use either source or both.

How the two sources are merged​

Core serves the union of the config files and the platform bucket:

  • A blob replaces the file entity with the same name, as a whole. This applies to models, interceptors, translators, roles, applications, and toolsets; schemas are matched by $id. No field of the file entity survives.
  • Keys and routes are never shadowed. A key is matched by its secret and a route by its paths, so a file entry and a blob entry of the same name both stay in force.
  • Global settings are an overlay. When the blob settings/platform/global exists, Core takes globalInterceptors, retriableErrorCodes, rateLimitSchedule, and spendingLimits from it instead of from the files. Deleting the blob restores the file values. See Global settings.
  • Public resources stay out. Applications and toolsets in the public bucket are not part of the merged configuration.

Secrets at rest​

Core never stores a secret in a blob as plain text:

  • The key of an API key, and the key and secretExtraData of an upstream or interface, are stored as ENC[...].
  • The auth_settings.client_secret and code_verifier of applications and toolsets are stored as base64 ciphertext.

No Configuration API read returns a secret. For applications and toolsets, an admin gets a client_secret_hint instead of the secret. Secrets in config files are read as written, so keep those files in a secret store.

Reload and consistency​

  • Config files are re-read every config.reload milliseconds (default 60000), and the merged configuration is rebuilt from the files and the blobs. If a re-read fails to open, parse, or validate a file, Core keeps the last good configuration and logs a warning.
  • Configuration API writes apply on the instance that served them before it answers, so the next request to that instance sees the change. Other instances apply it when they receive the resource event, and every instance converges on its next full rebuild.
  • On demand, an admin can send POST /v1/ops/config/reload to re-read the files and rebuild the configuration synchronously. The answer is the merged configuration as JSON.

Invalid entities​

config.onInvalidEntity decides what a semantic violation does to a rebuild, such as a duplicate deployment ID:

  • abort (default) fails the rebuild and keeps the previous configuration. At startup, Core does not start.
  • skip drops the offending entity alone and records it as invalid.

A blob that cannot be parsed or decrypted is always skipped and recorded, whatever the mode. GET /v1/admin/health/config reports degraded and lists each skipped entity while any is recorded. The setting is described in Config loading.

Dynamic configuration entities​

Each entity type has the same fields in a config file and in the platform bucket. Deployment IDs are shared: a model, an application, a toolset, and an interceptor cannot have the same name.

EntityWhat it isConfig file keyConfiguration API pathReference
ModelAn LLM or embedding model served through Coremodels/v1/models/platform/{name}Models
UpstreamOne provider endpoint behind a model or route, for load balancingmodels.<name>.upstreams—Load balancing and upstreams
TranslatorA service that converts one AI API into anothertranslators/v1/translators/platform/{name}Translators
ApplicationAn agent or app served through Coreapplications/v1/applications/platform/{name}Applications
Application type schemaA JSON schema that defines a type of schema-rich applicationapplicationTypeSchemas/v1/schemas/platform/{name}Application type schemas
InterceptorA service that processes requests and responsesinterceptors/v1/interceptors/platform/{name}Interceptors
RouteA custom HTTP or WebSocket API proxied through Coreroutes/v1/routes/platform/{name}Routes
ToolsetAn MCP server registered in Coretoolsets/v1/toolsets/platform/{name}Toolsets
RoleLimits and sharing rules for a group of callersroles/v1/roles/platform/{name}Roles
KeyAn API key, its project, and its roleskeys/v1/keys/platform/{name}Keys
Global settingsDeployment-wide interceptors, retriable errors, limit schedule, and spending limitsglobalInterceptors, retriableErrorCodes, rateLimitSchedule, spendingLimits/v1/settings/platform/globalGlobal settings
Catalog schemaA schema for the metadata a deployment shows in the CatalogcatalogSchemas/v1/catalog_schemas/platform/{name}Catalog schemas
note

The Configuration API also stores budget policies and policy assignments (/v1/policies/platform/... and /v1/policy_assignments/platform/...), which config files cannot hold. The Core documentation does not describe their fields yet. Org unit roles (orgUnitRoles) belong to org units, a preview feature off by default.

The Static settings and gflog.xml pages cover the startup configuration.

Working examples​

Complete configuration files are in the AI DIAL repository:

SetupFiles
Echo applicationdial-docker-compose/application/
Azure modelsdial-docker-compose/model/
Ollama (self-hosted)dial-docker-compose/ollama/
Production (Keycloak, DIAL Admin)dial-docker-compose-advanced/dial-2.x/