--- title: "Plugins" description: "Configure Bifrost plugins in Helm — telemetry, logging, semantic cache, OpenTelemetry, Datadog, governance, and custom plugins" icon: "puzzle-piece" --- Plugins are configured under `bifrost.plugins`. Each plugin is independently enabled/disabled. Pre-hooks run in registration order; post-hooks run in reverse order. **Telemetry, logging, and governance are auto-loaded built-ins** — they are always active and do not need to be explicitly enabled. Their configuration lives in `bifrost.client.*` and `bifrost.governance.*`, not in the `plugins` block. The `plugins` block controls the opt-in plugins: `semanticCache`, `otel`, `datadog`, `maxim`, and custom plugins. ```yaml bifrost: plugins: semanticCache: enabled: false otel: enabled: false datadog: enabled: false ``` ```bash # Enable an opt-in plugin at install time helm install bifrost bifrost/bifrost \ --set image.tag=v1.4.11 \ --set bifrost.plugins.otel.enabled=true # Or upgrade to enable a plugin without touching other values helm upgrade bifrost bifrost/bifrost \ --reuse-values \ --set bifrost.plugins.semanticCache.enabled=true ``` --- ### Telemetry (Prometheus) Telemetry is **always active** — it cannot be disabled. You do not need to set `bifrost.plugins.telemetry.enabled`. Exposes Prometheus metrics at `GET /metrics`. Custom labels are set via `bifrost.client.prometheusLabels`: ```yaml bifrost: client: prometheusLabels: - "environment=production" - "region=us-east-1" ``` ```bash # Verify metrics are exposed kubectl port-forward svc/bifrost 8080:8080 & curl http://localhost:8080/metrics | head -30 ``` **With Prometheus Push Gateway** (recommended for multi-replica / HA setups where pull-based scraping can miss pods): ```yaml bifrost: plugins: telemetry: enabled: true config: push_gateway: enabled: true push_gateway_url: "http://prometheus-pushgateway.monitoring.svc.cluster.local:9091" job_name: "bifrost" instance_id: "" # auto-derived from pod name if empty push_interval: 15 basic_auth: username: "" password: "" ``` **ServiceMonitor for Prometheus Operator:** ```yaml serviceMonitor: enabled: true interval: 30s scrapeTimeout: 10s namespace: monitoring # namespace where Prometheus is deployed ``` ### Request/Response Logging Logging is **auto-loaded** when `bifrost.client.enableLogging: true` and a log store is configured. You do not need to set `bifrost.plugins.logging.enabled`. Configure logging via the `client` block: | Parameter | Description | Default | |-----------|-------------|---------| | `bifrost.client.enableLogging` | Enable request/response logging | `true` | | `bifrost.client.disableContentLogging` | Strip message body from logs (HIPAA/PCI) | `false` | | `bifrost.client.loggingHeaders` | HTTP headers to capture in log metadata | `[]` | ```yaml bifrost: client: enableLogging: true disableContentLogging: false # set true for HIPAA/compliance loggingHeaders: - "x-request-id" - "x-user-id" - "x-team-id" ``` ```bash # Verify logs are being written kubectl port-forward svc/bifrost 8080:8080 & curl -s "http://localhost:8080/api/logs?limit=5" | jq . ``` See [Client Configuration](/deployment-guides/helm/client) for the full reference. ### Governance Governance is **always active** for OSS deployments. You do not need to set `bifrost.plugins.governance.enabled`. Virtual key enforcement is controlled by the `client` block: | Parameter | Description | Default | |-----------|-------------|---------| | `bifrost.client.enforceAuthOnInference` | Require a virtual key (`x-bf-vk`) on every inference request | `false` | ```yaml bifrost: client: enforceAuthOnInference: true # require virtual key on all inference requests ``` Define virtual keys, budgets, rate limits, and routing rules in `bifrost.governance.*`. See the [Governance](/deployment-guides/helm/governance) page. ### Semantic Cache Caches LLM responses using vector similarity so semantically equivalent prompts return cached answers. Two modes: - **Semantic mode** (`dimension > 1`): uses an embedding model + vector store for similarity search - **Direct / hash mode** (`dimension: 1`): exact-match hash-based caching, no embedding model needed | Parameter | Description | Default | |-----------|-------------|---------| | `bifrost.plugins.semanticCache.enabled` | Enable semantic caching | `false` | | `bifrost.plugins.semanticCache.version` | Plugin config version for DB-backed update tracking (`1` to `32767`) | `1` | | `bifrost.plugins.semanticCache.config.provider` | Embedding provider | `"openai"` | | `bifrost.plugins.semanticCache.config.embedding_model` | Embedding model name | `"text-embedding-3-small"` | | `bifrost.plugins.semanticCache.config.dimension` | Embedding dimension (`1` = direct/hash mode) | `1536` | | `bifrost.plugins.semanticCache.config.threshold` | Cosine similarity threshold (0–1) | `0.8` | | `bifrost.plugins.semanticCache.config.ttl` | Cache entry TTL (Go duration) | `"5m"` | | `bifrost.plugins.semanticCache.config.conversation_history_threshold` | Number of past messages to include in cache key | `3` | | `bifrost.plugins.semanticCache.config.cache_by_model` | Include model name in cache key | `true` | | `bifrost.plugins.semanticCache.config.cache_by_provider` | Include provider name in cache key | `true` | | `bifrost.plugins.semanticCache.config.exclude_system_prompt` | Exclude system prompt from cache key | `false` | | `bifrost.plugins.semanticCache.config.cleanup_on_shutdown` | Delete cache data on pod shutdown | `false` | **Semantic mode (with OpenAI embeddings + Weaviate):** ```bash kubectl create secret generic semantic-cache-secret \ --from-literal=openai-key='sk-your-openai-embedding-key' ``` ```yaml # semantic-cache-values.yaml image: tag: "v1.4.11" vectorStore: enabled: true type: weaviate weaviate: enabled: true persistence: size: 20Gi bifrost: plugins: semanticCache: enabled: true config: provider: "openai" keys: - value: "env.SEMANTIC_CACHE_OPENAI_KEY" weight: 1 embedding_model: "text-embedding-3-small" dimension: 1536 threshold: 0.85 ttl: "1h" conversation_history_threshold: 5 cache_by_model: true cache_by_provider: true providerSecrets: semantic-cache-key: existingSecret: "semantic-cache-secret" key: "openai-key" envVar: "SEMANTIC_CACHE_OPENAI_KEY" ``` ```bash helm install bifrost bifrost/bifrost -f semantic-cache-values.yaml ``` **Direct / hash mode** (no embedding provider needed): ```yaml bifrost: plugins: semanticCache: enabled: true config: dimension: 1 # triggers hash-based exact matching ttl: "30m" cache_by_model: true cache_by_provider: true ``` The vector store (`vectorStore.*`) must be configured and enabled for semantic mode. Direct/hash mode works without a vector store but still requires a storage backend. ### OpenTelemetry (OTel) Sends distributed traces and push-based metrics to any OTLP-compatible collector (Jaeger, Tempo, Honeycomb, etc.). | Parameter | Description | Default | |-----------|-------------|---------| | `bifrost.plugins.otel.enabled` | Enable OTel tracing | `false` | | `bifrost.plugins.otel.version` | Plugin config version for DB-backed update tracking (`1` to `32767`) | `1` | | `bifrost.plugins.otel.config.service_name` | Service name in traces | `"bifrost"` | | `bifrost.plugins.otel.config.collector_url` | OTLP collector endpoint | `""` | | `bifrost.plugins.otel.config.trace_type` | Trace type (`genai_extension`, `vercel`, or `open_inference`) | `"genai_extension"` | | `bifrost.plugins.otel.config.protocol` | Transport protocol (`grpc` or `http`) | `"grpc"` | | `bifrost.plugins.otel.config.metrics_enabled` | Enable OTLP push-based metrics | `false` | | `bifrost.plugins.otel.config.metrics_endpoint` | OTLP metrics endpoint | `""` | | `bifrost.plugins.otel.config.metrics_push_interval` | Push interval in seconds | `15` | | `bifrost.plugins.otel.config.headers` | Custom headers for the collector | `{}` | | `bifrost.plugins.otel.config.insecure` | Skip TLS verification | `false` | | `bifrost.plugins.otel.config.tls_ca_cert` | Path to CA cert for TLS | `""` | ```yaml # otel-values.yaml image: tag: "v1.4.11" bifrost: plugins: otel: enabled: true config: service_name: "bifrost-production" collector_url: "otel-collector.observability.svc.cluster.local:4317" trace_type: "genai_extension" protocol: "grpc" insecure: true # set false in production with a proper cert metrics_enabled: true metrics_endpoint: "otel-collector.observability.svc.cluster.local:4317" metrics_push_interval: 15 headers: x-honeycomb-team: "env.HONEYCOMB_API_KEY" ``` ```bash helm upgrade bifrost bifrost/bifrost --reuse-values -f otel-values.yaml ``` **With authentication headers from a Kubernetes Secret:** ```bash kubectl create secret generic otel-credentials \ --from-literal=api-key='your-honeycomb-or-grafana-key' ``` ```yaml bifrost: plugins: otel: enabled: true config: collector_url: "api.honeycomb.io:443" protocol: "grpc" headers: x-honeycomb-team: "env.OTEL_API_KEY" providerSecrets: otel-key: existingSecret: "otel-credentials" key: "api-key" envVar: "OTEL_API_KEY" ``` ### Datadog APM Sends traces to a Datadog Agent running in the cluster. | Parameter | Description | Default | |-----------|-------------|---------| | `bifrost.plugins.datadog.enabled` | Enable Datadog tracing | `false` | | `bifrost.plugins.datadog.version` | Plugin config version for DB-backed update tracking (`1` to `32767`) | `1` | | `bifrost.plugins.datadog.config.service_name` | Service name | `"bifrost"` | | `bifrost.plugins.datadog.config.agent_addr` | Datadog Agent address | `"localhost:8126"` | | `bifrost.plugins.datadog.config.env` | Deployment environment tag | `""` | | `bifrost.plugins.datadog.config.version` | Version tag | `""` | | `bifrost.plugins.datadog.config.enable_traces` | Enable trace collection | `true` | | `bifrost.plugins.datadog.config.custom_tags` | Extra tags on all spans | `{}` | The Datadog Agent is typically deployed via the [Datadog Helm chart](https://docs.datadoghq.com/containers/kubernetes/installation/) as a DaemonSet, making it available at the node's hostIP. ```yaml # datadog-values.yaml image: tag: "v1.4.11" bifrost: plugins: datadog: enabled: true config: service_name: "bifrost" agent_addr: "$(HOST_IP):8126" # uses Datadog DaemonSet pattern env: "production" version: "v1.4.11" enable_traces: true custom_tags: team: "platform" region: "us-east-1" # Inject HOST_IP so Bifrost can reach the DaemonSet agent on the same node env: - name: HOST_IP valueFrom: fieldRef: fieldPath: status.hostIP ``` ```bash helm upgrade bifrost bifrost/bifrost --reuse-values -f datadog-values.yaml ``` ### Maxim Observability Sends LLM request/response data to [Maxim](https://getmaxim.ai) for tracing, evaluation, and observability. | Parameter | Description | Default | |-----------|-------------|---------| | `bifrost.plugins.maxim.enabled` | Enable Maxim plugin | `false` | | `bifrost.plugins.maxim.version` | Plugin config version for DB-backed update tracking (`1` to `32767`) | `1` | | `bifrost.plugins.maxim.config.api_key` | Maxim API key (plain text, prefer secret) | `""` | | `bifrost.plugins.maxim.config.log_repo_id` | Maxim log repository ID | `""` | | `bifrost.plugins.maxim.secretRef.name` | Kubernetes Secret name for API key | `""` | | `bifrost.plugins.maxim.secretRef.key` | Key within the secret | `"api-key"` | ```bash kubectl create secret generic maxim-credentials \ --from-literal=api-key='your-maxim-api-key' ``` ```yaml # maxim-values.yaml image: tag: "v1.4.11" bifrost: plugins: maxim: enabled: true config: log_repo_id: "your-log-repo-id" secretRef: name: "maxim-credentials" key: "api-key" ``` ```bash helm upgrade bifrost bifrost/bifrost --reuse-values -f maxim-values.yaml ``` ### Custom / Dynamic Plugins Load a custom Go plugin (compiled `.so` file) at runtime. | Parameter | Description | Default | |-----------|-------------|---------| | `bifrost.plugins.custom[].name` | Unique plugin name | `""` | | `bifrost.plugins.custom[].enabled` | Enable custom plugin | `false` | | `bifrost.plugins.custom[].path` | Path to compiled `.so` file in the container | `""` | | `bifrost.plugins.custom[].version` | Plugin config version (`1` to `32767`) | `1` | | `bifrost.plugins.custom[].config` | Arbitrary plugin-specific configuration | `{}` | ```yaml bifrost: plugins: custom: - name: "my-custom-plugin" enabled: true path: "/plugins/my-plugin.so" version: 1 config: api_endpoint: "https://my-service.example.com" timeout: 5000 ``` Mount the `.so` file via a volume: ```yaml volumes: - name: custom-plugins configMap: name: bifrost-custom-plugins volumeMounts: - name: custom-plugins mountPath: /plugins ``` Or use an init container to download the plugin binary: ```yaml initContainers: - name: download-plugin image: curlimages/curl:8.6.0 command: - sh - -c - | curl -fsSL https://plugins.example.com/my-plugin.so \ -o /plugins/my-plugin.so volumeMounts: - name: plugin-dir mountPath: /plugins volumes: - name: plugin-dir emptyDir: {} volumeMounts: - name: plugin-dir mountPath: /plugins ``` ```bash helm upgrade bifrost bifrost/bifrost --reuse-values -f custom-plugin-values.yaml ``` --- ## All Plugins Together ```yaml # all-plugins-values.yaml image: tag: "v1.4.11" bifrost: encryptionKeySecret: name: "bifrost-encryption" key: "encryption-key" plugins: telemetry: enabled: true config: custom_labels: - name: "environment" value: "production" logging: enabled: true config: disable_content_logging: false logging_headers: - "x-request-id" governance: enabled: true config: is_vk_mandatory: true semanticCache: enabled: true config: provider: "openai" keys: - value: "env.CACHE_OPENAI_KEY" weight: 1 embedding_model: "text-embedding-3-small" dimension: 1536 threshold: 0.85 ttl: "1h" otel: enabled: true config: service_name: "bifrost" collector_url: "otel-collector.observability.svc.cluster.local:4317" protocol: "grpc" insecure: true ``` ```bash helm install bifrost bifrost/bifrost -f all-plugins-values.yaml ```