Skip to main content
The plugins array only controls explicitly opt-in plugins: semantic_cache, otel, maxim, datadog (enterprise), and custom plugins.Telemetry, logging, and governance are auto-loaded built-ins — they are always active and configured via the client block and dedicated top-level keys, not the plugins array.

Auto-Loaded Built-ins

These plugins start automatically. You do not add them to the plugins array.
PluginAlways active?How to configure
Telemetry (Prometheus /metrics)Yes, alwaysclient.prometheus_labels for custom labels; push gateway via plugins entry once DB-backed mode is running
LoggingWhen client.enable_logging: true and logs_store is configuredclient.enable_logging, client.disable_content_logging, client.logging_headers
GovernanceYes, always (OSS)client.enforce_auth_on_inference for VK enforcement; governance.* for virtual keys / budgets / routing rules
See Client Configuration and Governance for full details.

Plugin Array Structure

Every entry in the plugins array supports these common fields:
FieldTypeRequiredDescription
namestringYesPlugin name
enabledbooleanYesEnable or disable this plugin
configobjectVariesPlugin-specific configuration
pathstringNoPath to a custom plugin binary or WASM file
versionintegerNo🛑 DB-Backed Only. Plugin metadata persisted on TablePlugin rather than PluginConfig. Ignored in config.json. Used in UI/DB workflows to force refresh/reload.
placementstringNo🛑 DB-Backed Only. Execution metadata ("pre_builtin", "builtin", "post_builtin") persisted on TablePlugin. Ignored in config.json. Relevant for dynamic plugin ordering in UI/DB mode.
orderintegerNo🛑 DB-Backed Only. Execution metadata persisted on TablePlugin. Ignored in config.json. Within a placement group, lower values run earlier.
name, enabled, path, and config are the core plugin config fields parsed from config.json. version, placement, and order are not valid config.json keys; they are DB-backed metadata persisted on TablePlugin and are only applicable when managing plugins dynamically via the UI or Database.

Semantic Cache

Caches LLM responses by semantic similarity. Returns a cached response when an incoming request is semantically close enough to a previous one.Requires a vector store to be configured.
FieldRequiredDefaultDescription
config.dimensionYesEmbedding dimension. Use 1 for hash-based (exact) caching without an embedding provider
config.providerNoProvider for generating embeddings (required for semantic mode)
config.embedding_modelNoModel for embeddings (required when provider is set)
config.thresholdNo0.8Cosine similarity threshold for a cache hit (0.0–1.0)
config.ttlNo300Cache entry TTL in seconds (or a duration string like "1h")
config.cache_by_modelNotrueInclude model in cache key
config.cache_by_providerNotrueInclude provider in cache key
config.exclude_system_promptNofalseExclude system prompt from cache key
config.conversation_history_thresholdNo3Skip caching for requests with more messages than this
config.default_cache_keyNoDefault cache key when no x-bf-cache-key header is sent
Semantic mode (embedding-based similarity search):
{
  "plugins": [
    {
      "name": "semantic_cache",
      "enabled": true,
      "config": {
        "provider": "openai",
        "embedding_model": "text-embedding-3-small",
        "dimension": 1536,
        "threshold": 0.85,
        "ttl": 300,
        "cache_by_model": true,
        "cache_by_provider": true
      }
    }
  ]
}
Hash mode (exact-match caching, no embedding provider needed):
{
  "plugins": [
    {
      "name": "semantic_cache",
      "enabled": true,
      "config": {
        "dimension": 1,
        "ttl": 1800
      }
    }
  ]
}
You must also configure a vector_store in config.json. See Storage — vector_store.

Custom / Dynamic Plugins

Load a custom Go plugin binary or WASM plugin at startup using the path field. Custom plugins must implement one of the Bifrost plugin interfaces.
{
  "plugins": [
    {
      "name": "my-custom-auth",
      "enabled": true,
      "path": "/app/plugins/my-custom-auth.so",
      "config": {
        "auth_endpoint": "env.AUTH_SERVICE_URL"
      }
    }
  ]
}
WASM plugin:
{
  "plugins": [
    {
      "name": "my-wasm-plugin",
      "enabled": true,
      "path": "/app/plugins/my-plugin.wasm",
      "config": {}
    }
  ]
}
See Writing Go Plugins and Writing WASM Plugins for implementation guides. Placement and ordering (DB-backed only): When creating plugins dynamically via the DB/UI (rather than config.json), you can specify their execution order:
placementWhen it runs
pre_builtinBefore all built-in plugins
builtinAlongside built-in plugins (by order)
post_builtinAfter all built-in plugins (default)
Within a placement group, lower order values run earlier.