ReferenceConfig File

Config File

Authoritative reference for gestaltd configuration.

Top-Level Shape

auth: {}
datastore: {}
secrets: {}
telemetry: {}
providers: {}
bindings: {}
server: {}
egress: {}
ui: {}

Load Semantics

  • ${ENV_VAR} expansion happens before YAML decode
  • If ${ENV_VAR} is unset and ENV_VAR_FILE is set, Gestalt reads the value from that file path
  • Unknown YAML fields are rejected
  • server.port defaults to 8080
  • secrets.provider defaults to env
  • telemetry.provider defaults to stdout
  • Relative paths resolve relative to the config file directory
  • secret://... values are resolved during bootstrap, not during YAML parsing

server

server:
  port: 8080
  base_url: https://gestalt.example.com
  encryption_key: secret://gestalt-encryption-key
  api_token_ttl: 30d
FieldRequiredDefaultPurpose
portNo8080HTTP listen port.
base_urlNoDerives OAuth callback URLs when explicit redirect URLs are omitted.
encryption_keyYesRoot deployment secret. Used for encryption and derived session material.
api_token_ttlNo30dLifetime of newly issued API tokens. Accepts Go duration strings (1h, 720h) and day suffixes (30d).

auth

none

auth:
  provider: none

Disables platform authentication. Every request is treated as a single anonymous user.

local

auth:
  provider: local
  config:
    email: local@example.com
FieldRequiredDefaultPurpose
emailNolocal@gestalt.localIdentity of the single local user.

google

auth:
  provider: google
  config:
    client_id: ${GOOGLE_CLIENT_ID}
    client_secret: secret://google-client-secret
    redirect_url: https://gestalt.example.com/api/v1/auth/login/callback
    allowed_domains:
      - example.com
FieldRequiredDefaultPurpose
client_idYesGoogle OAuth client ID.
client_secretYesGoogle OAuth client secret.
redirect_urlNoDerived from server.base_urlLogin callback URL.
allowed_domainsNoRestrict login to specific email domains.

Google checks email_verified on every login. Unverified accounts are rejected.

oidc

auth:
  provider: oidc
  config:
    issuer_url: https://login.example.com
    client_id: ${OIDC_CLIENT_ID}
    client_secret: secret://oidc-client-secret
    redirect_url: https://gestalt.example.com/api/v1/auth/login/callback
    allowed_domains:
      - example.com
    scopes:
      - openid
      - email
      - profile
    session_secret: secret://oidc-session-secret
    session_ttl: 24h
    pkce: true
    display_name: Company SSO
FieldRequiredDefaultPurpose
issuer_urlYesOIDC discovery base URL.
client_idYesOIDC client ID.
client_secretConditionalOIDC client secret. May be omitted for PKCE-only public clients.
redirect_urlNoDerived from server.base_urlLogin callback URL.
allowed_domainsNoEmail-domain allowlist.
scopesNoopenid, email, profileOIDC scopes to request.
session_secretYesSecret for signing session tokens.
session_ttlNo24hSession token lifetime.
pkceNofalseEnable PKCE for the login flow.
display_nameNoSSOName shown in the login UI.

OIDC checks email_verified when the claim is present. Unverified accounts are rejected.

datastore

datastore:
  provider: postgres
  config:
    dsn: ${DATABASE_URL}
ProviderConfig fieldsPurpose
sqlitepathDefaults to ./gestalt.db. Single-node deployments.
postgresdsnRecommended production datastore.
mysqldsnSQL-backed production option.
dynamodbtable, region, endpointtable defaults to gestalt.
mongodburi, databasedatabase defaults to gestalt.
oracledsnEnterprise SQL option.
firestoreproject_id, databaseFirestore-backed deployment.
sqlserverdsnSQL Server-backed deployment.

secrets

secrets:
  provider: file
  config:
    dir: /etc/gestalt-secrets
ProviderConfig fieldsPurpose
envprefixReads secrets from environment variables.
filedirReads one secret per file from a base directory. Works with Kubernetes volume-mounted secrets.
google_secret_managerproject, versionGoogle Cloud Secret Manager. version defaults to latest.
aws_secrets_managerregion, version_stage, endpointAWS Secrets Manager. version_stage defaults to AWSCURRENT.
vaultaddress, token, mount_path, namespaceHashiCorp Vault KV v2. mount_path defaults to secret.
azure_key_vaultvault_url, versionAzure Key Vault. version defaults to latest.

telemetry

Controls distributed traces, metrics, and structured logs. Gestalt uses OpenTelemetry under the hood. Every HTTP request, broker invocation, and plugin gRPC call is automatically traced.

stdout

telemetry:
  provider: stdout
  config:
    format: text
    level: info
FieldRequiredDefaultPurpose
formatNotexttext or json.
levelNoinfodebug, info, warn, or error.

Outputs structured logs to standard output. Traces and metrics use noop providers to keep terminal output clean. Default provider when telemetry is omitted.

otlp

telemetry:
  provider: otlp
  config:
    endpoint: otel-collector:4317
    protocol: grpc
    service_name: gestaltd
    insecure: false
    headers:
      Authorization: Bearer ${OTEL_TOKEN}
    resource_attributes:
      deployment.environment: production
      service.version: "1.0.0"
    traces:
      sampling_ratio: 1.0
    metrics:
      interval: 60s
    logs:
      level: info
FieldRequiredDefaultPurpose
endpointNoSDK defaultOTLP collector address.
protocolNogrpcgrpc or http.
service_nameNogestaltdOpenTelemetry service name.
insecureNofalseSkip TLS verification.
headersNoExtra headers on every export request.
resource_attributesNoKey-value pairs attached as resource attributes.
traces.sampling_ratioNo1.0Fraction of traces to sample, 0.0 to 1.0.
metrics.intervalNo60sMetric export interval.
logs.levelNoinfoMinimum exported log level.

Exports to any OpenTelemetry-compatible collector (Jaeger, Grafana Alloy, Datadog Agent).

noop

telemetry:
  provider: noop

Disables all telemetry. Instrumentation points remain but produce zero overhead.

Trace spans

LayerSpan nameKey attributes
HTTPgestaltd: {method} {route}Standard HTTP semantic conventions
Brokerbroker.invokegestalt.provider, gestalt.operation, gestalt.user_id, gestalt.connection_mode
gRPC pluginPer-RPC spansStandard gRPC semantic conventions

Audit logs

Audit records are emitted as structured log entries with log.type=audit. Route them to a dedicated audit backend using OTel Collector attribute-based filtering. See Observability for details.

providers

Config uses a top-level providers: map. Each provider entry is provider-shaped directly: there is no nested plugin: block anymore.

providers:
  github:
    display_name: GitHub
    description: Public GitHub operations
    icon_file: ./icons/github.svg
    connections:
      public:
        mode: none
        auth:
          type: none
    surfaces:
      openapi:
        document: ./openapi/github.yaml
        connection: public
    allowed_operations:
      repos.get:
        alias: get_repo
    mcp:
      enabled: true
      tool_prefix: github_

The config key is providers, but the HTTP API and client CLI still refer to these named entries as integrations.

Provider fields

FieldPurpose
display_nameUI and API display name override.
descriptionUI and API description override.
icon_fileSVG icon path resolved from the config directory.
configProvider-specific config passed into packaged providers.
fromOptional packaged/executable source. Omit it for fully inline providers.
connectionsNamed connections. default is the primary connection entry.
headersStatic headers applied to declarative or spec-backed requests.
managed_parametersFixed header or path values injected before exposure.
response_mappingData and pagination mapping for OpenAPI or GraphQL providers.
allowed_operationsSurface allowlist plus alias and description overrides.
surfacesDeclarative REST, OpenAPI, GraphQL, and MCP surfaces.
exposeMCP exposure settings such as tool prefix.

providers.*.from

Use from when the provider is backed by an executable or packaged plugin.

from:
  command: ./bin/provider
  args:
    - --debug
  env:
    LOG_LEVEL: debug
FieldPurpose
commandExecute a local binary directly.
packageLoad a local directory, local archive, or HTTPS archive.
sourceResolve a versioned plugin source during init. Format: github.com/<org>/<repo>/<plugin>.
versionRequired with source. Invalid with command or package.
argsExtra process arguments for command.
envExtra environment variables for executable providers.
allowed_hostsOptional network allowlist for sandboxed plugin processes.

command, package, and source are mutually exclusive.

Auth shapes inside connections

Every connection auth block uses the same shape:

connections:
  default:
    auth:
      type: oauth2
      authorization_url: https://provider.example.com/oauth/authorize
      token_url: https://provider.example.com/oauth/token
      client_id: ${CLIENT_ID}
      client_secret: ${CLIENT_SECRET}
      client_auth: body
      token_exchange: form
      scopes:
        - read
        - write
      scope_param: user_scope
      scope_separator: ","
      pkce: true
      authorization_params:
        audience: https://api.example.com
      token_params:
        resource: api
      refresh_params: {}
      accept_header: application/json
      token_metadata:
        - workspace_id
FieldPurpose
typeoauth2, manual, bearer, none, or mcp_oauth.
authorization_urlOAuth authorization endpoint.
token_urlOAuth token endpoint.
client_id, client_secretOAuth client credentials.
redirect_urlOverride the derived callback URL.
client_authHow client credentials are sent: body (default) or header.
token_exchangeToken request encoding: form (default) or json.
scopesOAuth scopes to request.
scope_paramQuery parameter name for scopes. Defaults to scope. Set to user_scope for Slack and other providers that use a non-standard parameter.
scope_separatorSeparator between scope values. Defaults to space.
pkceEnable Proof Key for Code Exchange.
authorization_paramsExtra query parameters on the authorization request.
token_paramsExtra parameters on the token exchange request.
refresh_paramsExtra parameters on the token refresh request.
accept_headerAccept header for the token endpoint.
token_metadataFields to extract from the token response and store as connection metadata.

mcp_oauth is an advanced mode for MCP-driven OAuth discovery. It delegates authorization URL and token URL resolution to the upstream MCP server.

Manual auth with custom credential fields

For manual-auth connections, you can customize the credential input form with credentials. Each entry defines a field the user must fill in, with an optional label, description, and help URL.

Single credential with a custom label:

connections:
  default:
    auth:
      type: manual
      credentials:
        - name: token
          label: API Access Token
          help_url: https://app.example.com/settings/tokens

Multiple credentials require auth_mapping to map each field to an HTTP header:

connections:
  default:
    auth:
      type: manual
      credentials:
        - name: api_key
          label: API Key
          help_url: https://us5.datadoghq.com/organization-settings/api-keys
        - name: app_key
          label: Application Key
          help_url: https://us5.datadoghq.com/organization-settings/application-keys
      auth_mapping:
        headers:
          DD-API-KEY: api_key
          DD-APPLICATION-KEY: app_key
FieldNotes
credentials[].nameInternal identifier for the field. Must be unique, lowercase with underscores.
credentials[].labelDisplay label shown in the UI. Falls back to name if omitted.
credentials[].descriptionHint text shown below the label. Supports inline links via [text](url).
credentials[].help_urlLink displayed next to the label for where to find the credential.
auth_mapping.headersMaps credential field names to HTTP headers. Required when multiple credentials are declared.

credentials is required when auth.type is manual.

connections

connections:
  default:
    mode: user
    auth:
      type: oauth2
      authorization_url: https://accounts.example.com/oauth/authorize
      token_url: https://accounts.example.com/oauth/token
      client_id: ${CLIENT_ID}
      client_secret: ${CLIENT_SECRET}
    params:
      tenant:
        required: true
        description: Tenant identifier
  mcp:
    mode: user
    auth:
      type: mcp_oauth

Only connections.default may define:

  • params
  • discovery

Connection modes:

  • none
  • user
  • identity
  • either

If you omit connections.default and use only named connections, every configured surface must set its own connection.

Post-connect discovery

connections:
  default:
    mode: user
    auth:
      type: oauth2
      authorization_url: https://accounts.example.com/oauth/authorize
      token_url: https://accounts.example.com/oauth/token
    params:
      workspace_id:
        required: true
        description: Workspace chosen after connect
        from: discovery
    discovery:
      url: https://api.example.com/workspaces
      id_path: id
      name_path: name
      metadata:
        workspace_id: id

surfaces

surfaces.rest, surfaces.openapi, and surfaces.graphql are mutually exclusive. surfaces.mcp can be added alongside any of them.

Declarative REST

surfaces:
  rest:
    base_url: https://api.support.example.com
    operations:
      - name: list_tickets
        method: GET
        path: /tickets
      - name: get_ticket
        method: GET
        path: /tickets/{ticket_id}

Each declarative operation accepts:

  • name
  • description
  • method
  • path
  • parameters

Parameter locations can be query, body, or path.

OpenAPI, GraphQL, and MCP

surfaces:
  openapi:
    document: ./openapi/workspace.yaml
    connection: default
  mcp:
    url: https://mcp.example.com/mcp
    connection: mcp
Surface fieldPurpose
surfaces.rest.base_urlBase URL for declarative REST operations.
surfaces.rest.operationsInline declarative REST operations.
surfaces.openapi.documentOpenAPI document URL or local file path.
surfaces.openapi.base_urlOptional runtime base URL override for OpenAPI.
surfaces.graphql.urlGraphQL endpoint URL.
surfaces.mcp.urlUpstream MCP endpoint URL.
surfaces.*.connectionConnection name for that surface.

Managed parameters

connections:
  default:
    mode: none
    auth:
      type: none
surfaces:
  openapi:
    document: https://api.example.com/openapi.json
managed_parameters:
  - in: header
    name: X-API-Version
    value: "2026-04-01"
  - in: path
    name: account_id
    value: primary

Managed parameter locations can be header or path.

Response mapping

connections:
  default:
    auth:
      type: bearer
      credentials:
        - name: token
          label: API Token
surfaces:
  graphql:
    url: https://api.example.com/graphql
response_mapping:
  data_path: data.items
  pagination:
    has_more_path: pageInfo.hasNextPage
    cursor_path: pageInfo.endCursor

mcp

mcp:
  enabled: true
  tool_prefix: github_

bindings

bindings:
  inbound:
    type: webhook
    providers:
      - github
    config:
      path: /events/github
      provider: github
      operation: issues_listForAuthenticatedUser
      auth_mode: signed
      signing_secret: secret://webhook-secret
bindings:
  outbound_proxy:
    type: proxy
    providers:
      - github
    config:
      path: /proxy
      instance: default

Common binding fields

FieldPurpose
typewebhook or proxy.
providersAllowlist of providers the binding can access.
configBinding-type-specific config.

Webhook binding config

FieldPurpose
pathRequired. Must start with /.
providerOptional target provider for forwarding.
instanceOptional provider instance.
operationOptional target operation.
auth_modepublic, signed, or trusted_user_header.
signing_secretRequired for signed.
signature_headerHeader carrying the HMAC signature. Defaults to X-Signature.
user_headerRequired for trusted_user_header.
trusted_sourcesSource IP allowlist for trusted_user_header.

Proxy binding config

FieldPurpose
pathRequired. Must start with /.

Proxy bindings may declare zero or one provider in bindings.<name>.providers. Webhook forwarding requires the forwarded provider to be present in the binding allowlist.

egress

egress:
  default_action: deny
  policies:
    - action: allow
      subject_kind: user
      provider: github
      method: GET
      host: api.github.com
      path_prefix: /repos
  credentials:
    - host: api.github.com
      secret_ref: github-api-key
      auth_style: bearer
    - host: api.openai.com
      secret_ref: openai-api-key
      auth_style: bearer

policies

FieldPurpose
actionallow or deny.
subject_kindMatch a subject kind.
subject_idMatch a specific subject.
providerMatch a provider name.
operationMatch an operation name.
methodMatch an HTTP method.
hostMatch an outbound host.
path_prefixMatch a path prefix.

credentials

FieldPurpose
secret_refRequired. Secret manager key resolved at request time.
auth_styleHow the resolved secret is injected: bearer, basic, or raw. Defaults to bearer.
subject_kindOptional subject filter.
subject_idOptional subject filter.
operationOptional operation filter.
methodOptional HTTP-method filter.
hostOptional host filter.
path_prefixOptional path filter.

ui

ui:
  plugin:
    package: ./my-ui-plugin
ui:
  plugin:
    source: github.com/your-org/your-repo/console
    version: 1.0.0
FieldPurpose
plugin.packageLocal directory, local archive, or HTTPS URL. Mutually exclusive with source.
plugin.sourceManaged plugin source address. Requires version.
plugin.versionRequired with source. Must be valid SemVer without leading v.

When ui is omitted, gestaltd serves the embedded frontend. When ui.plugin is configured, the plugin’s assets are served instead. See UI Plugins for the full workflow.

Validation Rules

Structural validation runs at config load time (init, validate, serve). Runtime validation runs only at serve time.

Structural

  • Provider entries are decoded directly; there is no nested plugin block
  • Exactly one of from.command, from.package, or from.source per packaged provider
  • from.version is required with from.source and invalid with from.command or from.package
  • from.args are only valid with from.command
  • Plain http:// package URLs are rejected
  • surfaces.rest, surfaces.openapi, and surfaces.graphql are mutually exclusive
  • Only connections.default may define params or discovery
  • All connections in a provider must share the same mode
  • surfaces.*.connection must reference a declared connection when present
  • URL templates in spec surfaces and auth URLs must reference required params
  • egress.default_action and policy action must be allow or deny
  • ui.plugin requires exactly one of package or source
  • ui.plugin.version is required with source and invalid with package

Runtime

  • auth.provider is required
  • datastore.provider is required
  • server.encryption_key is required