1524 lines
56 KiB
YAML
1524 lines
56 KiB
YAML
# Default values for Bifrost
|
|
# This is a YAML-formatted file.
|
|
# Declare variables to be passed into your templates.
|
|
|
|
# Bifrost application configuration
|
|
replicaCount: 1
|
|
|
|
image:
|
|
# Container image repository
|
|
# Default: Docker Hub public image
|
|
# For enterprise customers with private registry, use full URL:
|
|
# repository: us-west1-docker.pkg.dev/bifrost-enterprise/your-org/bifrost
|
|
# repository: your-registry.example.com/your-org/bifrost
|
|
# repository: 123456789.dkr.ecr.us-east-1.amazonaws.com/bifrost
|
|
repository: docker.io/maximhq/bifrost
|
|
pullPolicy: IfNotPresent
|
|
# REQUIRED: Specify the image tag (e.g., v1.5.0, latest)
|
|
# Docker images are tagged with v prefix (e.g., v1.5.0)
|
|
# See available tags at: https://hub.docker.com/r/maximhq/bifrost/tags
|
|
tag: ""
|
|
|
|
imagePullSecrets: []
|
|
nameOverride: ""
|
|
fullnameOverride: ""
|
|
|
|
serviceAccount:
|
|
# Specifies whether a service account should be created
|
|
create: true
|
|
# Automatically mount a ServiceAccount's API credentials?
|
|
automount: true
|
|
# Annotations to add to the service account
|
|
annotations: {}
|
|
# The name of the service account to use.
|
|
# If not set and create is true, a name is generated using the fullname template
|
|
name: ""
|
|
|
|
rbac:
|
|
podDiscovery:
|
|
# Create Role/RoleBinding to allow pod discovery in-cluster.
|
|
# This is rendered only when:
|
|
# - bifrost.cluster.enabled=true
|
|
# - bifrost.cluster.discovery.enabled=true
|
|
# - bifrost.cluster.discovery.type=kubernetes
|
|
enabled: true
|
|
|
|
# Annotations to add to the deployment metadata
|
|
# Useful for tools like Keel (keel.sh) for automatic image updates
|
|
# Example:
|
|
# deploymentAnnotations:
|
|
# keel.sh/policy: force
|
|
# keel.sh/trigger: poll
|
|
deploymentAnnotations: {}
|
|
|
|
# Labels to add to the deployment metadata (in addition to default labels)
|
|
deploymentLabels: {}
|
|
|
|
podAnnotations: {}
|
|
podLabels: {}
|
|
|
|
podSecurityContext:
|
|
fsGroup: 1000
|
|
runAsUser: 1000
|
|
runAsNonRoot: true
|
|
|
|
securityContext:
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
readOnlyRootFilesystem: false
|
|
runAsNonRoot: true
|
|
runAsUser: 1000
|
|
|
|
service:
|
|
type: ClusterIP
|
|
port: 8080
|
|
annotations: {}
|
|
|
|
# Single ingress (legacy format):
|
|
ingress:
|
|
enabled: false
|
|
className: ""
|
|
# Meesho Contour HTTPProxy compatibility settings.
|
|
ingressClassName: ""
|
|
servicePortNumber: 8080
|
|
enableWebsocket: false
|
|
slowStart:
|
|
enabled: false
|
|
window: "120s"
|
|
aggression: 1
|
|
minPercent: 10
|
|
annotations: {}
|
|
hosts:
|
|
- host: bifrost.local
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
tls: []
|
|
# Named ingresses map (new format) — replaces the single ingress above.
|
|
# Each key becomes a separate Ingress resource named "<release>-<key>".
|
|
# Use this when you need multiple ingress controllers (e.g. public + internal).
|
|
# ingress:
|
|
# public:
|
|
# enabled: true
|
|
# className: nginx-public
|
|
# annotations: {}
|
|
# hosts:
|
|
# - host: bifrost.example.com
|
|
# paths:
|
|
# - path: /
|
|
# pathType: Prefix
|
|
# tls: []
|
|
# internal:
|
|
# enabled: true
|
|
# className: nginx-internal
|
|
# annotations: {}
|
|
# hosts:
|
|
# - host: bifrost.internal.example.com
|
|
# paths:
|
|
# - path: /
|
|
# pathType: Prefix
|
|
# tls: []
|
|
|
|
# Meesho Contour HTTPProxy integration. These templates are intentionally
|
|
# retained in this fork and render independently from the upstream Ingress.
|
|
httpProxy:
|
|
enabled: false
|
|
createContourGateway: false
|
|
namespace: ""
|
|
contourResponseTimeout: false
|
|
|
|
resources:
|
|
limits:
|
|
cpu: 2000m
|
|
memory: 2Gi
|
|
requests:
|
|
cpu: 500m
|
|
memory: 512Mi
|
|
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: http
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: http
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
|
|
autoscaling:
|
|
enabled: false
|
|
minReplicas: 1
|
|
maxReplicas: 10
|
|
targetCPUUtilizationPercentage: 80
|
|
targetMemoryUtilizationPercentage: 80
|
|
# HPA scaling behavior configuration
|
|
# Controls how quickly the HPA scales up/down to prevent connection disruption
|
|
behavior:
|
|
scaleDown:
|
|
# Stabilization window prevents rapid scale-down oscillation.
|
|
# The HPA will wait this long after the last scale event before scaling down again.
|
|
# Important for long-lived streaming connections (e.g. SSE for LLM inference).
|
|
stabilizationWindowSeconds: 300
|
|
policies:
|
|
- type: Pods
|
|
value: 1
|
|
periodSeconds: 120
|
|
scaleUp:
|
|
stabilizationWindowSeconds: 30
|
|
|
|
# Additional volumes on the output Deployment definition.
|
|
volumes: []
|
|
|
|
# Additional volumeMounts on the output Deployment definition.
|
|
volumeMounts: []
|
|
|
|
nodeSelector: {}
|
|
|
|
tolerations: []
|
|
|
|
affinity: {}
|
|
|
|
# Deployment rolling update strategy. Applies to the Deployment only (not the
|
|
# StatefulSet used for sqlite-with-persistence). Rendered verbatim into spec.strategy.
|
|
# Empty ({}) uses the Kubernetes default (RollingUpdate, maxSurge 25%, maxUnavailable 25%).
|
|
# For HA gateway deployments, surge-only rollouts avoid dropping capacity:
|
|
# strategy:
|
|
# type: RollingUpdate
|
|
# rollingUpdate:
|
|
# maxSurge: 100%
|
|
# maxUnavailable: 0%
|
|
strategy: {}
|
|
|
|
# Graceful shutdown configuration for long-lived connections (SSE streaming)
|
|
# When a pod is terminated (e.g. during HPA scale-down), active streaming connections
|
|
# are severed abruptly. This causes clients to lose their SSE stream mid-response.
|
|
# The preStop hook and termination grace period give in-flight requests time to complete.
|
|
terminationGracePeriodSeconds: 60
|
|
lifecycle:
|
|
preStop:
|
|
exec:
|
|
# Sleep allows the pod to be removed from the Service endpoints and load balancer
|
|
# before the process starts shutting down, preventing new connections from arriving
|
|
# while existing ones drain.
|
|
command: ["sh", "-c", "sleep 15"]
|
|
|
|
# Bifrost specific configuration
|
|
# You can find entire schema at https://getbifrost.ai/schema
|
|
bifrost:
|
|
# Application settings
|
|
appDir: /app/data
|
|
port: 8080
|
|
# 0.0.0.0 binds IPv4 interfaces only; use "::" for dual-stack/IPv6-only clusters
|
|
host: 0.0.0.0
|
|
logLevel: info
|
|
logStyle: json
|
|
# envLabel: staging # Short label (max 10 chars) shown in the UI sidebar to identify the environment
|
|
|
|
# Controls how config.json is reconciled with the database on startup.
|
|
# "split" (default): existing merge behavior — file and DB rows coexist.
|
|
# "config.json": sections explicitly present in the file are authoritative;
|
|
# database-only rows for those sections are pruned on startup.
|
|
# sourceOfTruth: "config.json"
|
|
|
|
# Encryption key for sensitive data
|
|
# Can be set as a secret or environment variable
|
|
encryptionKey: ""
|
|
|
|
# Use an existing Kubernetes secret for the encryption key.
|
|
# When `name` is set, takes precedence over `encryptionKey`: the chart
|
|
# injects BIFROST_ENCRYPTION_KEY into the pod via secretKeyRef and writes
|
|
# `encryption_key: "env.BIFROST_ENCRYPTION_KEY"` in the rendered config.json.
|
|
encryptionKeySecret:
|
|
name: ""
|
|
key: "encryption-key"
|
|
|
|
# Authentication configuration (top-level)
|
|
# This controls authentication for Bifrost API and dashboard
|
|
authConfig:
|
|
adminUsername: ""
|
|
adminPassword: ""
|
|
isEnabled: false
|
|
# Use existing Kubernetes secret for admin credentials
|
|
existingSecret: ""
|
|
usernameKey: "username"
|
|
passwordKey: "password"
|
|
|
|
# Feature flag boot overrides. Flags themselves are code-declared inside
|
|
# Bifrost (via featureflags.Register); this map only sets their initial
|
|
# values. Anything set here is rendered as a "locked" flag in the UI —
|
|
# operators must edit values.yaml (and redeploy) to change it, which
|
|
# matches the GitOps invariant that Helm-managed values are authoritative.
|
|
#
|
|
# Each key is a flag name; each value carries `enabled`. The `enabled`
|
|
# field accepts either a literal boolean OR an "env.NAME" string so the
|
|
# actual on/off decision can come from a container env var without
|
|
# re-templating the chart.
|
|
#
|
|
# Example:
|
|
# featureFlags:
|
|
# experimental.streaming-mux:
|
|
# enabled: true
|
|
# audit.verbose:
|
|
# enabled: "env.BIFROST_AUDIT_VERBOSE"
|
|
featureFlags: {}
|
|
|
|
# Client configuration
|
|
client:
|
|
dropExcessRequests: false
|
|
initialPoolSize: 300
|
|
allowedOrigins:
|
|
- "*"
|
|
enableLogging: true
|
|
disableContentLogging: false
|
|
disableDbPingsInHealth: false
|
|
dumpErrorsInConsoleLogs: false
|
|
logRetentionDays: 365
|
|
# Deprecated: use enforceAuthOnInference instead.
|
|
enforceGovernanceHeader: false
|
|
# Require auth (VK, API key, or user token) on inference endpoints.
|
|
# Open by default in the raw binary; this chart enables enforcement for production.
|
|
enforceAuthOnInference: true
|
|
maxRequestBodySizeMb: 100
|
|
compat:
|
|
convertTextToChat: false
|
|
convertChatToResponses: false
|
|
shouldDropParams: false
|
|
shouldConvertParams: false
|
|
prometheusLabels: []
|
|
# Header filtering configuration for x-bf-eh-* headers forwarded to LLM providers
|
|
headerFilterConfig:
|
|
allowlist: []
|
|
denylist: []
|
|
# asyncJobResultTTL: 3600 # Default TTL for async job results in seconds
|
|
# requiredHeaders: [] # Headers that must be present on every request
|
|
# loggingHeaders: [] # Headers to capture in log metadata
|
|
# allowedHeaders: [] # Additional allowed headers for CORS and WebSocket
|
|
# Deprecated MCP global settings (use bifrost.mcp.toolManagerConfig and bifrost.mcp.toolSyncInterval instead):
|
|
# mcpAgentDepth: 10
|
|
# mcpToolExecutionTimeout: 30
|
|
# mcpCodeModeBindingLevel: "server"
|
|
# mcpToolSyncInterval: 10
|
|
# mcpDisableAutoToolInject: false
|
|
# mcpEnableTempTokenAuth: false
|
|
# hideDeletedVirtualKeysInFilters: false # Omit deleted virtual keys from logs/MCP filter data
|
|
# whitelistedRoutes: [] # Routes that bypass auth middleware
|
|
# routingChainMaxDepth: 10 # Maximum depth for routing rule chain evaluation
|
|
# allowDirectKeys: false # Allow callers to bypass the key pool via x-bf-direct-key + Authorization header
|
|
# mcpExternalClientUrl: "" # Public base URL used as redirect_uri when Bifrost is an OAuth client to MCP servers
|
|
# How /mcp authenticates inbound MCP clients: headers (default), both, or oauth
|
|
# mcpServerAuthMode: "headers"
|
|
# OAuth2 authorization server settings for /mcp (only used when mcpServerAuthMode is "both" or "oauth")
|
|
# oauth2ServerConfig:
|
|
# issuerUrl: "" # Stable public issuer URL; required for multi-host deployments. Supports env.VAR_NAME
|
|
# authCodeTtl: 300 # Authorization code lifetime in seconds (default 300, max 900)
|
|
# accessTokenTtl: 600 # Issued JWT lifetime in seconds (default 600)
|
|
# disableVkIdentity: false # Only valid when mcpServerAuthMode is "oauth"
|
|
|
|
# Server configuration
|
|
server:
|
|
readBufferSize: 65536 # Read buffer size in bytes for reading HTTP headers (default: 64 KiB)
|
|
|
|
# Framework configuration
|
|
framework:
|
|
pricing:
|
|
# Custom pricing URL for model cost data
|
|
pricingUrl: "https://getbifrost.ai/datasheet"
|
|
# Custom model parameters URL
|
|
modelParametersUrl: "https://getbifrost.ai/datasheet/model-parameters"
|
|
# Sync interval in seconds (default: 86400 = 24 hours, minimum: 3600)
|
|
pricingSyncInterval: 86400
|
|
# Custom MCP server catalog URL (optional, leave empty to use the default Bifrost catalog)
|
|
# mcpLibraryUrl: ""
|
|
# MCP library sync interval in seconds (default: 86400 = 24 hours, minimum: 3600)
|
|
# mcpLibrarySyncInterval: 86400
|
|
|
|
# Provider configurations (add your provider keys here)
|
|
# You can specify API keys directly or use env.VAR_NAME syntax to reference environment variables
|
|
# When using existingSecret in providerSecrets, the keys will be injected as env vars and
|
|
# you should use env.VAR_NAME syntax in the value field
|
|
# Note: The entire providers block is passed through to the config as-is.
|
|
# See https://getbifrost.ai/schema for the full provider schema.
|
|
providers: {}
|
|
# openai:
|
|
# keys:
|
|
# - name: "primary-key" # Key name (required, must be unique)
|
|
# value: "sk-..." # Direct value
|
|
# weight: 1
|
|
# models: ["gpt-4o", "gpt-4o-mini"] # Restrict key to specific models
|
|
# use_for_batch_api: false # Whether this key can be used for batch API
|
|
# - name: "secondary-key"
|
|
# value: "env.OPENAI_KEY" # Reference to environment variable
|
|
# weight: 1
|
|
# # Network configuration (optional, per-provider)
|
|
# network_config:
|
|
# base_url: "" # Custom base URL (required for Ollama)
|
|
# extra_headers: {} # Additional headers to send with requests
|
|
# default_request_timeout_in_seconds: 300 # Request timeout
|
|
# max_retries: 3 # Maximum number of retries
|
|
# retry_backoff_initial_ms: 500 # Initial retry backoff in ms
|
|
# retry_backoff_max_ms: 5000 # Max retry backoff in ms
|
|
# stream_idle_timeout_in_seconds: 60 # Max wait for next stream chunk (default: 60)
|
|
# max_conns_per_host: 5000 # Max TCP connections per host (default: 5000)
|
|
# enforce_http2: false # Force HTTP/2 on provider connections (e.g. Bedrock)
|
|
# insecure_skip_verify: false # Disable TLS certificate verification (last resort)
|
|
# ca_cert_pem: "" # PEM-encoded CA cert for self-signed/private CA
|
|
# allow_private_network: false # Allow connections to RFC 1918 private IPs (k8s pod network, LAN, VPC)
|
|
# beta_header_overrides: # Override Anthropic beta header support (optional)
|
|
# redact-thinking-: true # Enable/disable specific beta headers by prefix
|
|
# # Concurrency configuration (optional)
|
|
# concurrency_and_buffer_size:
|
|
# concurrency: 100 # Number of concurrent requests
|
|
# buffer_size: 200 # Buffer size for requests
|
|
# # Proxy configuration (optional)
|
|
# proxy_config:
|
|
# type: "none" # Options: none, http, socks5, environment
|
|
# url: ""
|
|
# username: ""
|
|
# password: ""
|
|
# ca_cert_pem: "" # PEM-encoded CA cert for SSL-intercepting proxies
|
|
# send_back_raw_response: false # Include raw response in BifrostResponse
|
|
# store_raw_request_response: false # Capture raw payloads for plugins only; not returned to client
|
|
#
|
|
# anthropic:
|
|
# keys:
|
|
# - name: "anthropic-key"
|
|
# value: "sk-ant-..."
|
|
# weight: 1
|
|
#
|
|
# # Azure OpenAI example (requires azure_key_config)
|
|
# azure:
|
|
# keys:
|
|
# - name: "azure-key"
|
|
# value: "..."
|
|
# weight: 1
|
|
# azure_key_config:
|
|
# endpoint: "https://your-resource.openai.azure.com"
|
|
# api_version: "2024-02-15-preview"
|
|
# deployments:
|
|
# gpt-4o: "my-gpt4o-deployment"
|
|
#
|
|
# # Google Vertex AI example (requires vertex_key_config)
|
|
# vertex:
|
|
# keys:
|
|
# - name: "vertex-key"
|
|
# value: ""
|
|
# weight: 1
|
|
# vertex_key_config:
|
|
# project_id: "my-gcp-project"
|
|
# region: "us-central1"
|
|
# auth_credentials: "env.GOOGLE_CREDENTIALS"
|
|
#
|
|
# # AWS Bedrock example (requires bedrock_key_config)
|
|
# bedrock:
|
|
# keys:
|
|
# - name: "bedrock-key"
|
|
# value: ""
|
|
# weight: 1
|
|
# bedrock_key_config:
|
|
# region: "us-east-1"
|
|
# access_key: "env.AWS_ACCESS_KEY_ID"
|
|
# secret_key: "env.AWS_SECRET_ACCESS_KEY"
|
|
#
|
|
# # AWS Bedrock Mantle example (requires bedrock_mantle_key_config)
|
|
# bedrock_mantle:
|
|
# keys:
|
|
# - name: "bedrock-mantle-key"
|
|
# value: ""
|
|
# weight: 1
|
|
# bedrock_mantle_key_config:
|
|
# region: "us-east-1" # Required
|
|
# access_key: "env.AWS_ACCESS_KEY_ID"
|
|
# secret_key: "env.AWS_SECRET_ACCESS_KEY"
|
|
# # session_token: "env.AWS_SESSION_TOKEN"
|
|
# # role_arn: "" # For AssumeRole
|
|
# # external_id: ""
|
|
# # session_name: ""
|
|
|
|
# Provider secrets - use existing Kubernetes secrets for provider API keys
|
|
# These will be injected as environment variables that can be referenced in providers config
|
|
providerSecrets: {}
|
|
# openai:
|
|
# existingSecret: "my-openai-secret"
|
|
# key: "api-key"
|
|
# envVar: "OPENAI_API_KEY" # Environment variable name to inject
|
|
# anthropic:
|
|
# existingSecret: "my-anthropic-secret"
|
|
# key: "api-key"
|
|
# envVar: "ANTHROPIC_API_KEY"
|
|
|
|
# MCP (Model Context Protocol) configuration
|
|
mcp:
|
|
enabled: false
|
|
clientConfigs: []
|
|
# - name: "example-mcp"
|
|
# connectionType: "stdio"
|
|
# stdioConfig:
|
|
# command: "/path/to/mcp/server"
|
|
# args: []
|
|
# envs: []
|
|
# # Optional: source connection_string from a Kubernetes secret.
|
|
# # When set, chart injects BIFROST_MCP_<NAME>_CONNECTION_STRING
|
|
# # into the pod and rewrites connection_string in config.json
|
|
# # to `env.BIFROST_MCP_<NAME>_CONNECTION_STRING`.
|
|
# secretRef:
|
|
# name: "" # k8s secret name
|
|
# connectionStringKey: "connection-string" # key within the secret
|
|
#
|
|
# - name: "example-https-mcp"
|
|
# connectionType: "http"
|
|
# connectionString: "https://my-internal-mcp.corp/mcp"
|
|
# # Per-server tool execution timeout override. Go duration string ("30s", "2m")
|
|
# # or a bare integer treated as seconds. Overrides toolManagerConfig.toolExecutionTimeout
|
|
# # for this server only. Omit or set to 0 to use the global default.
|
|
# toolExecutionTimeout: "30s"
|
|
# # TLS configuration for HTTP and SSE connection types.
|
|
# # Use when the MCP server presents a self-signed or private CA certificate.
|
|
# tlsConfig:
|
|
# insecureSkipVerify: false # Disable TLS verification (dev/test only — takes priority over caCertPem)
|
|
# caCertPem: "env.MY_MCP_CA_CERT" # PEM string or env.VAR_NAME reference
|
|
#
|
|
# - name: "example-oauth-mcp"
|
|
# connectionType: "http"
|
|
# connectionString: "https://my-mcp.corp/mcp"
|
|
# # authType "oauth": shared OAuth token; provide oauthConfigId referencing an existing oauth_config.
|
|
# # authType "per_user_oauth": each user authenticates individually via OAuth flow;
|
|
# # oauth_config is registered via the API (POST /api/mcp/clients), not configured here.
|
|
# authType: "oauth"
|
|
# oauthConfigId: "my-oauth-config-id" # ID of the OAuth config created in Bifrost
|
|
# toolSyncInterval: "10m" # Global tool sync interval (Go duration string, e.g. "10m", "1h", "0s")
|
|
# Tool manager configuration
|
|
toolManagerConfig:
|
|
toolExecutionTimeout: "30s"
|
|
maxAgentDepth: 10
|
|
# codeModeBindingLevel: "server" # Code mode binding level (server or tool)
|
|
# disableAutoToolInject: false # Disable automatic MCP tool injection
|
|
|
|
# Plugins configuration
|
|
# Plugin version must be >= 1 (schema minimum). Use values > 1 to force DB-backed plugin config replacement on upgrade.
|
|
plugins:
|
|
telemetry:
|
|
enabled: false
|
|
version: 1
|
|
config:
|
|
custom_labels: []
|
|
# push_gateway:
|
|
# enabled: false
|
|
# push_gateway_url: ""
|
|
# job_name: "bifrost"
|
|
# instance_id: ""
|
|
# push_interval: 15
|
|
# basic_auth:
|
|
# username: ""
|
|
# password: ""
|
|
|
|
logging:
|
|
enabled: false
|
|
version: 1
|
|
config:
|
|
disable_content_logging: false
|
|
logging_headers: []
|
|
|
|
governance:
|
|
enabled: false
|
|
version: 1
|
|
config:
|
|
is_vk_mandatory: false
|
|
required_headers: []
|
|
is_enterprise: false
|
|
|
|
maxim:
|
|
enabled: false
|
|
version: 1
|
|
config:
|
|
api_key: ""
|
|
log_repo_id: ""
|
|
# Use existing Kubernetes secret for API key (takes precedence over config.api_key)
|
|
secretRef:
|
|
name: ""
|
|
key: "api-key"
|
|
|
|
semanticCache:
|
|
enabled: false
|
|
version: 1
|
|
config:
|
|
# Semantic caching mode (dimension > 1): requires provider, keys, and embedding_model
|
|
# Direct caching mode (dimension: 1): hash-based exact matching, no embedding provider needed
|
|
provider: "openai"
|
|
keys: []
|
|
embedding_model: "text-embedding-3-small"
|
|
dimension: 1536
|
|
threshold: 0.8
|
|
ttl: "5m"
|
|
conversation_history_threshold: 3
|
|
cache_by_model: true
|
|
cache_by_provider: true
|
|
exclude_system_prompt: false
|
|
vector_store_namespace: ""
|
|
|
|
otel:
|
|
enabled: false
|
|
version: 1
|
|
config:
|
|
# plugin_span_filter: # Optional: filter which plugin hook spans are exported
|
|
# mode: "include" # "include" or "exclude"
|
|
# plugins: ["maxim", "otel"]
|
|
#
|
|
# Multi-profile shape (use profiles OR the flat single-profile fields below, not both):
|
|
# profiles:
|
|
# - service_name: "bifrost"
|
|
# collector_url: "" # e.g., http://otel-collector:4318 (HTTP) or otel-collector:4317 (gRPC)
|
|
# trace_type: "genai_extension" # genai_extension | vercel | open_inference
|
|
# protocol: "grpc" # http | grpc
|
|
# metrics_enabled: false
|
|
# metrics_endpoint: "" # e.g., http://otel-collector:4318/v1/metrics (HTTP) or otel-collector:4317 (gRPC)
|
|
# metrics_push_interval: 15 # Push interval in seconds (1-300)
|
|
# headers: {}
|
|
# tls_ca_cert: "" # Path to TLS CA certificate file
|
|
# insecure: true # Skip TLS verification (ignored if tls_ca_cert is set)
|
|
# disable_content_logging: false
|
|
# group_traces_by_session: false # Group requests sharing x-bf-session-id into one trace (traceparent takes precedence)
|
|
# disable_root_span_content: false # Drop input/output from the root span only (keeps it on the llm.call span)
|
|
#
|
|
# Single-profile shape:
|
|
service_name: "bifrost"
|
|
collector_url: "" # e.g., http://otel-collector:4318 (HTTP) or otel-collector:4317 (gRPC)
|
|
trace_type: "genai_extension" # genai_extension | vercel | open_inference
|
|
protocol: "grpc" # http | grpc
|
|
# Push-based metrics export via OTLP (recommended for multi-node clusters)
|
|
metrics_enabled: false
|
|
metrics_endpoint: "" # e.g., http://otel-collector:4318/v1/metrics (HTTP) or otel-collector:4317 (gRPC)
|
|
metrics_push_interval: 15 # Push interval in seconds (1-300)
|
|
# Custom headers for the collector (supports env.VAR_NAME prefix)
|
|
headers: {}
|
|
# TLS configuration
|
|
tls_ca_cert: "" # Path to TLS CA certificate file
|
|
insecure: false # Skip TLS verification (ignored if tls_ca_cert is set)
|
|
# Drop message content (input/output messages, embeddings, tool defs/args/results) from exported spans
|
|
disable_content_logging: false
|
|
# Group requests sharing the same x-bf-session-id header into one trace (an inbound W3C traceparent takes precedence)
|
|
group_traces_by_session: false
|
|
# Drop input/output content from the root span only (the llm.call generation span keeps it)
|
|
disable_root_span_content: false
|
|
datadog:
|
|
enabled: false
|
|
version: 1
|
|
config:
|
|
service_name: "bifrost"
|
|
# Datadog Agent address. Supports env.VAR_NAME references — e.g. set
|
|
# agent_addr: "env.DD_AGENT_ADDR" and inject DD_AGENT_ADDR via the
|
|
# top-level `env:` (e.g. from status.hostIP for a node-local agent DaemonSet).
|
|
agent_addr: "localhost:8126"
|
|
# dogstatsd_addr: "localhost:8125" # DogStatsD address (supports env.VAR_NAME)
|
|
# Alternatively, set host and port separately (common in Kubernetes, where the
|
|
# host comes from the downward API status.hostIP and the port is fixed — the two
|
|
# can't be collapsed into one env var). When a *_host is set it takes precedence
|
|
# over the matching *_addr; the *_port defaults to 8126 (agent) / 8125 (DogStatsD).
|
|
# agent_host: "env.DD_AGENT_HOST"
|
|
# agent_port: "8126"
|
|
# dogstatsd_host: "env.DD_AGENT_HOST"
|
|
# dogstatsd_port: "8125"
|
|
env: ""
|
|
version: ""
|
|
custom_tags: {}
|
|
enable_traces: true
|
|
# ml_app: "" # ML app name for LLM Observability (defaults to service_name)
|
|
# enable_metrics: true
|
|
# enable_llm_obs: true
|
|
# group_traces_by_session: false # Group requests sharing x-bf-session-id into one APM trace (agent mode only)
|
|
# disable_content_logging: false
|
|
# request_headers: [] # Header name patterns (exact or wildcard like "x-custom-*")
|
|
# Agentless mode (direct to Datadog API, no local agent):
|
|
# agentless: true
|
|
# api_key: "env.DD_API_KEY" # Required for agentless mode (supports env.VAR_NAME)
|
|
# site: "datadoghq.com" # Datadog site/region (e.g. datadoghq.eu)
|
|
# plugin_span_filter: # Optional: filter which plugin hook spans are exported
|
|
# mode: "exclude" # "include" or "exclude"
|
|
# plugins: ["logging"]
|
|
|
|
bigquery:
|
|
enabled: false
|
|
version: 1
|
|
config:
|
|
project_id: "" # GCP project ID (required when enabled)
|
|
dataset_id: "bifrost_traces"
|
|
table_id: "traces"
|
|
location: "US"
|
|
# service_account_key: "" # Service account key JSON, or "env.VAR". Omit to use ADC.
|
|
create_table_if_not_exists: true
|
|
flush_interval_seconds: 5
|
|
buffer_size: 500
|
|
custom_labels: {}
|
|
disable_content_logging: false
|
|
# request_headers: [] # Header name patterns (exact or wildcard like "x-custom-*")
|
|
# plugin_span_filter: # Optional: filter which plugin hook spans are exported
|
|
# mode: "exclude" # "include" or "exclude"
|
|
# plugins: ["logging"]
|
|
|
|
kafka:
|
|
enabled: false
|
|
version: 1
|
|
config:
|
|
brokers: [] # Kafka broker addresses (required when enabled)
|
|
topic: "" # Topic to publish traces to (required when enabled)
|
|
sasl_enabled: false
|
|
# sasl:
|
|
# mechanism: "PLAIN" # PLAIN | SCRAM-SHA-256 | SCRAM-SHA-512
|
|
# username: "env.KAFKA_USERNAME"
|
|
# password: "env.KAFKA_PASSWORD"
|
|
tls_enabled: false
|
|
# ca_cert: "env.KAFKA_CA_CERT" # PEM CA certificate to verify the broker. Omit to use the system CA pool.
|
|
compression: "none" # none | gzip | snappy | lz4 | zstd
|
|
batch_size: 100
|
|
flush_interval_ms: 1000
|
|
auto_create_topic: false
|
|
disable_content_logging: false
|
|
# request_headers: [] # Header name patterns (exact or wildcard like "x-custom-*")
|
|
# plugin_span_filter: # Optional: filter which plugin hook spans are exported
|
|
# mode: "exclude" # "include" or "exclude"
|
|
# plugins: ["logging"]
|
|
|
|
pubsub:
|
|
enabled: false
|
|
version: 1
|
|
config:
|
|
project_id: "" # GCP project ID (required when enabled)
|
|
topic_id: "" # Pub/Sub topic ID (required when enabled)
|
|
# service_account_key: "" # Service account key JSON, or "env.VAR". Omit to use ADC.
|
|
auto_create_topic: false
|
|
disable_content_logging: false
|
|
# request_headers: [] # Header name patterns (exact or wildcard like "x-custom-*")
|
|
# plugin_span_filter: # Optional: filter which plugin hook spans are exported
|
|
# mode: "exclude" # "include" or "exclude"
|
|
# plugins: ["logging"]
|
|
|
|
# Custom/dynamic plugins
|
|
custom: []
|
|
# - name: "my-custom-plugin"
|
|
# enabled: true
|
|
# path: "/plugins/my-plugin.so"
|
|
# version: 1 # must be >= 1; increase to force DB-backed plugin config replacement
|
|
# config:
|
|
# key: value
|
|
|
|
# Governance configuration for budgets, rate limits, customers, teams, virtual keys, and routing rules
|
|
governance:
|
|
budgets: []
|
|
# - id: "budget-1"
|
|
# max_limit: 100
|
|
# reset_duration: "1M" # Supports: 30s, 5m, 1h, 1d, 1w, 1M, 1Y
|
|
rateLimits: []
|
|
# - id: "rate-limit-1"
|
|
# token_max_limit: 100000
|
|
# token_reset_duration: "1d"
|
|
# request_max_limit: 1000
|
|
# request_reset_duration: "1h"
|
|
customers: []
|
|
# - id: "customer-1"
|
|
# name: "Customer Name"
|
|
# rate_limit_id: "rate-limit-1"
|
|
# # Option A: inline multi-budget (each must have a unique reset_duration)
|
|
# budgets:
|
|
# - id: "budget-monthly"
|
|
# max_limit: 500
|
|
# reset_duration: "1M"
|
|
# - id: "budget-yearly"
|
|
# max_limit: 5000
|
|
# reset_duration: "1Y"
|
|
# # Option B: single budget reference (pre-declared in governance.budgets)
|
|
# budget_id: "budget-1"
|
|
teams: []
|
|
# - id: "team-1"
|
|
# name: "Team Name"
|
|
# customer_id: "customer-1"
|
|
# budget_id: "budget-1"
|
|
# rate_limit_id: "rate-limit-1"
|
|
# profile: {} # Team profile data
|
|
# config: {} # Team configuration data
|
|
# claims: {} # Team claims data
|
|
roles: []
|
|
# - name: "dataAnalyst"
|
|
# description: "Read-only access for data analysts"
|
|
# dac: "team-data" # own-data | team-data | all-data (default: all-data)
|
|
# access_profile: "analyst-profile" # Optional: name of an access_profile to attach
|
|
# permissions:
|
|
# - resource: "Logs"
|
|
# operation: "View"
|
|
# - resource: "Metrics"
|
|
# operation: "View"
|
|
# - resource: "VirtualKeys"
|
|
# operation: "View"
|
|
virtualKeys: []
|
|
# - id: "vk-1"
|
|
# name: "Virtual Key 1"
|
|
# description: "Virtual key description"
|
|
# value: "sk-bf-..." # Optional - auto-generated if omitted
|
|
# is_active: true
|
|
# expires_at: "2026-12-31T23:59:59Z" # Optional RFC3339 expiry; requests rejected once passed. Omit for no expiry
|
|
# team_id: "team-1" # Mutually exclusive with customer_id
|
|
# customer_id: "" # Mutually exclusive with team_id
|
|
# rate_limit_id: "rate-limit-1"
|
|
# # Provider-specific configurations (empty means all providers allowed)
|
|
# provider_configs:
|
|
# - provider: "openai"
|
|
# weight: 1.0
|
|
# allowed_models: ["gpt-4o"]
|
|
# blacklisted_models: [] # Models blocked even if matched by allowed_models; ["*"] blocks all
|
|
# rate_limit_id: ""
|
|
# keys:
|
|
# - key_id: "uuid-of-key"
|
|
# name: "my-key"
|
|
# value: "sk-..."
|
|
# # MCP configurations for this virtual key
|
|
# mcp_configs:
|
|
# - mcp_client_id: 1
|
|
# tools_to_execute: ["tool1", "tool2"]
|
|
modelConfigs: []
|
|
# - id: "model-config-1"
|
|
# model_name: "gpt-4o" # model name, or "*" for all models
|
|
# provider: "openai" # optional; omit to apply to all providers
|
|
# scope: "global" # "global" (default) or "virtual_key"
|
|
# scope_id: "" # required when scope is "virtual_key" — the virtual key id
|
|
# budget_id: "budget-1"
|
|
# rate_limit_id: "rate-limit-1"
|
|
providers: []
|
|
# - name: "openai"
|
|
# budget_id: "budget-1"
|
|
# rate_limit_id: "rate-limit-1"
|
|
# send_back_raw_request: false
|
|
# send_back_raw_response: false
|
|
routingRules: []
|
|
# - id: "route-1"
|
|
# name: "Route to Azure"
|
|
# description: "Route GPT requests to Azure"
|
|
# enabled: true
|
|
# cel_expression: "model.startsWith('gpt-')"
|
|
# targets:
|
|
# - provider: "azure"
|
|
# model: "" # Empty means use original model
|
|
# provider_key_name: "" # Optional provider key name (resolved to internal key_id at load time)
|
|
# weight: 1.0
|
|
# fallbacks: ["openai"]
|
|
# scope: "global" # Options: global, team, customer, virtual_key
|
|
# scope_id: "" # Required for non-global scopes
|
|
# priority: 0 # Lower = evaluated first
|
|
pricingOverrides: []
|
|
# - id: "override-1"
|
|
# name: "Provider key pricing override"
|
|
# scope_kind: "provider_key" # global|provider|provider_key|virtual_key|virtual_key_provider|virtual_key_provider_key
|
|
# provider_key_name: "" # Optional provider key name alias (resolved to internal provider key ID at load time)
|
|
# match_type: "exact" # exact|wildcard
|
|
# pattern: "gpt-4o-mini"
|
|
# request_types: ["chat_completion"]
|
|
# pricing_patch: "{\"input_cost_per_token\":0.000001,\"output_cost_per_token\":0.000002}"
|
|
complexityAnalyzerConfig:
|
|
null
|
|
# tier_boundaries:
|
|
# simple_medium: 0.15
|
|
# medium_complex: 0.35
|
|
# complex_reasoning: 0.60
|
|
# keywords:
|
|
# code_keywords: ["function", "class", "api", "debug", "deploy"]
|
|
# reasoning_keywords: ["step by step", "explain why", "tradeoffs", "root cause analysis"]
|
|
# technical_keywords: ["architecture", "kubernetes", "latency", "authentication"]
|
|
# simple_keywords: ["hello", "hi", "thanks", "what is", "define"]
|
|
authConfig:
|
|
adminUsername: ""
|
|
adminPassword: ""
|
|
isEnabled: false
|
|
# Use existing Kubernetes secret for admin credentials
|
|
existingSecret: ""
|
|
usernameKey: "username"
|
|
passwordKey: "password"
|
|
|
|
# Cluster mode configuration for distributed deployments
|
|
cluster:
|
|
enabled: false
|
|
# region: "" # Region identifier for cluster
|
|
peers: []
|
|
# - "bifrost-0.bifrost-headless:7946"
|
|
# - "bifrost-1.bifrost-headless:7946"
|
|
gossip:
|
|
port: 7946
|
|
config:
|
|
timeoutSeconds: 10
|
|
successThreshold: 3
|
|
failureThreshold: 3
|
|
# gRPC transport for cluster counter-sync (replaces gossip broadcast for governance counters)
|
|
grpc:
|
|
port: 10102
|
|
dialTimeoutSeconds: 5
|
|
discovery:
|
|
enabled: false
|
|
# Discovery type: kubernetes, dns, udp, consul, etcd, mdns
|
|
type: ""
|
|
# Service name used by consul/etcd/udp discovery and as mDNS default
|
|
# This must be explicitly set for consul/etcd/udp discovery.
|
|
serviceName: ""
|
|
allowedAddressSpace: []
|
|
# Kubernetes discovery
|
|
k8sNamespace: ""
|
|
k8sLabelSelector: ""
|
|
# DNS discovery
|
|
dnsNames: []
|
|
# UDP broadcast discovery
|
|
udpBroadcastPort: 0
|
|
# Consul discovery
|
|
consulAddress: ""
|
|
# Etcd discovery
|
|
etcdEndpoints: []
|
|
# mDNS discovery
|
|
mdnsService: ""
|
|
|
|
# SCIM/SSO configuration for enterprise SSO
|
|
scim:
|
|
enabled: false
|
|
# Provider: okta, entra, keycloak, zitadel, google
|
|
provider: ""
|
|
config: {}
|
|
# Okta configuration:
|
|
# issuerUrl: "https://your-domain.okta.com/oauth2/default"
|
|
# authServerType: "org" # "org" or "custom"; auto-detected from issuer URL when omitted
|
|
# clientId: ""
|
|
# clientSecret: ""
|
|
# apiToken: ""
|
|
# audience: ""
|
|
# userIdField: "sub"
|
|
# teamIdsField: "groups"
|
|
# rolesField: "roles"
|
|
# # Attribute -> role/team/business-unit mappings (requires Custom Authorization Server;
|
|
# # the free Org Auth Server does not support claim expressions).
|
|
# attributeRoleMappings:
|
|
# - attribute: "groups"
|
|
# value: "bifrost-admins"
|
|
# role: "admin"
|
|
# attributeTeamMappings:
|
|
# - attribute: "groups"
|
|
# value: "*" # pass-through: every group becomes a team
|
|
# team: "" # ignored when value is "*"
|
|
# # SCIM provisioning: match by SCIM user attribute
|
|
# - attribute: "department"
|
|
# value: "engineering"
|
|
# team: "eng-team"
|
|
# attributeType: "user" # "user" = SCIM User push, "group" = SCIM Group push
|
|
# attributeValue: "engineering"
|
|
# # SCIM provisioning: match by SCIM group (displayName)
|
|
# - attribute: "groups"
|
|
# value: "Engineering"
|
|
# team: "eng-team"
|
|
# attributeType: "group"
|
|
# attributeValue: "displayName" # always "displayName" for group type
|
|
# attributeBusinessUnitMappings:
|
|
# - attribute: "department"
|
|
# value: "platform"
|
|
# business_unit: "Platform"
|
|
#
|
|
# Entra (Azure AD) configuration:
|
|
# tenantId: ""
|
|
# clientId: ""
|
|
# clientSecret: ""
|
|
# cloud: "commercial" # or "gcc-high" or "dod"
|
|
# audience: ""
|
|
# appIdUri: ""
|
|
# userIdField: "oid"
|
|
# teamIdsField: "groups"
|
|
# rolesField: "roles"
|
|
# attributeRoleMappings:
|
|
# - attribute: "roles"
|
|
# value: "BifrostAdmin"
|
|
# role: "admin"
|
|
# attributeTeamMappings:
|
|
# - attribute: "groups"
|
|
# value: "<group-object-id>"
|
|
# team: "platform-team"
|
|
# attributeBusinessUnitMappings: []
|
|
#
|
|
# Keycloak configuration:
|
|
# serverUrl: "https://keycloak.company.com" # base URL, must NOT include /realms/{realm}
|
|
# realm: "bifrost-prod"
|
|
# clientId: "bifrost"
|
|
# clientSecret: "env.KEYCLOAK_CLIENT_SECRET" # supports env. prefix
|
|
# audience: ""
|
|
# userIdField: "sub"
|
|
# teamIdsField: "groups"
|
|
# rolesField: "roles"
|
|
# attributeRoleMappings:
|
|
# - attribute: "realm_access.roles"
|
|
# value: "bifrost-admin"
|
|
# role: "admin"
|
|
# attributeTeamMappings: []
|
|
# attributeBusinessUnitMappings: []
|
|
#
|
|
# Zitadel configuration:
|
|
# domain: "my-instance.zitadel.cloud" # no scheme
|
|
# clientId: ""
|
|
# clientSecret: "" # optional, for confidential clients
|
|
# projectId: "" # optional, for project-scoped role claims
|
|
# audience: ""
|
|
# serviceAccountClientId: "" # required for user provisioning
|
|
# serviceAccountClientSecret: ""
|
|
# teamIdsField: "groups"
|
|
# attributeRoleMappings: []
|
|
# attributeTeamMappings: []
|
|
# attributeBusinessUnitMappings: []
|
|
#
|
|
# Google Workspace configuration:
|
|
# domain: "company.com"
|
|
# clientId: ""
|
|
# clientSecret: ""
|
|
# credentialMode: "inherit" # "inherit" (ADC), "env", or "file"
|
|
# serviceAccountEnvVar: "GOOGLE_SA_JSON" # required when credentialMode is "env"
|
|
# serviceAccountFile: "/etc/bifrost/sa.json" # required when credentialMode is "file"
|
|
# adminEmail: "admin@company.com" # required for Directory API (domain-wide delegation)
|
|
# impersonateServiceAccount: "" # optional, for Workload Identity
|
|
# audience: ""
|
|
# teamIdsField: "groups"
|
|
# attributeRoleMappings: []
|
|
# attributeTeamMappings: []
|
|
# attributeBusinessUnitMappings: []
|
|
|
|
# Load balancer configuration for intelligent request routing
|
|
loadBalancer:
|
|
enabled: false
|
|
# directionSelectionEnabled: true # Enable adaptive provider selection. Defaults to true; omit to leave on.
|
|
# routeSelectionEnabled: true # Enable adaptive per-key (route) selection. Defaults to true; omit to leave on.
|
|
# rerouteFailedDirections: false # Re-route to a healthy provider when a pinned direction is unhealthy. Defaults to false.
|
|
# pruneFailedFallbacks: false # Drop unhealthy directions from a request's configured fallbacks. Defaults to false.
|
|
trackerConfig: {}
|
|
bootstrap: {}
|
|
|
|
# Guardrails configuration for content moderation and policy enforcement
|
|
guardrails:
|
|
rules: []
|
|
# - id: 1
|
|
# name: "Block PII"
|
|
# description: "Block requests containing PII"
|
|
# enabled: true
|
|
# cel_expression: "!contains(request.body, 'SSN')"
|
|
# apply_to: "input"
|
|
# sampling_rate: 100
|
|
# timeout: 60 # Timeout in seconds for rule execution (default: 60)
|
|
# max_turns_to_send: 0
|
|
# evaluation_mode: "bundled" # "bundled" (default) | "per_turn" (each turn scanned in isolation; avoids cross-turn false positives, more provider calls)
|
|
providers: []
|
|
# - id: 1
|
|
# provider_name: "bedrock"
|
|
# policy_name: "content-filter"
|
|
# enabled: true
|
|
# timeout: 30 # Timeout in seconds for provider execution (default: 30)
|
|
# config: {}
|
|
|
|
# Declarative Skills Repository. Rendered verbatim as top-level `skills_registry`
|
|
# in config.json and reconciled at startup when enabled.
|
|
# skillsRegistry:
|
|
# enabled: true
|
|
# skills:
|
|
# - name: "my-skill"
|
|
# description: "What this skill does"
|
|
# version: "1.0.0"
|
|
# skill_md_body: "# My Skill\n\nInstructions..."
|
|
# # license: "MIT"
|
|
# # compatibility: ">=1.0.0"
|
|
# # allowed_tools: "Read,Write"
|
|
# # metadata: {}
|
|
# # extra_frontmatter: {}
|
|
# # files:
|
|
# # - path: "reference.md"
|
|
# # source_type: "text" # text | url | dataurl
|
|
# # content: "..." # required when source_type=text
|
|
# # # url: "https://..." # required when source_type=url
|
|
# # # dataurl: "data:..." # required when source_type=dataurl
|
|
|
|
# Access profiles (enterprise): seed RBAC access profile templates from Helm.
|
|
# This is rendered directly as top-level `access_profiles` in config.json.
|
|
accessProfiles: []
|
|
# - name: "platform-default"
|
|
# description: "Default platform profile"
|
|
# is_active: true
|
|
# tags: ["platform", "default"]
|
|
# budgets:
|
|
# - id: "ap-budget-1"
|
|
# max_limit: 100
|
|
# reset_duration: "1M"
|
|
# rate_limit:
|
|
# id: "ap-rate-limit-1"
|
|
# token_max_limit: 200000
|
|
# token_reset_duration: "1h"
|
|
# provider_configs:
|
|
# - provider_name: "openai"
|
|
# all_models_allowed: false
|
|
# allowed_models: ["gpt-4o", "gpt-4o-mini"]
|
|
# mcp_tool_groups:
|
|
# - tool_group_id: 1
|
|
# mcp_servers:
|
|
# - mcp_server_id: "github"
|
|
# mcp_tool_overrides:
|
|
# - mcp_client_id: "github"
|
|
# tool_name: "create_pull_request"
|
|
# action: "include"
|
|
|
|
# Audit logs configuration for CADF-compliant activity logging
|
|
auditLogs:
|
|
disabled: false
|
|
hmacKey: ""
|
|
|
|
# Large payload optimization - streams large payloads without full materialization
|
|
# largePayloadOptimization:
|
|
# enabled: false
|
|
# requestThresholdBytes: 10485760 # 10MB
|
|
# responseThresholdBytes: 10485760 # 10MB
|
|
# prefetchSizeBytes: 65536 # 64KB
|
|
# maxPayloadBytes: 524288000 # 500MB
|
|
# truncatedLogBytes: 1048576 # 1MB
|
|
|
|
# WebSocket gateway configuration (Responses API, Realtime API)
|
|
# websocket:
|
|
# maxConnectionsPerUser: 100
|
|
# transcriptBufferSize: 100
|
|
# pool:
|
|
# maxIdlePerKey: 50
|
|
# maxTotalConnections: 1000
|
|
# idleTimeoutSeconds: 600
|
|
# maxConnectionLifetimeSeconds: 7200
|
|
|
|
# Circuit breaker configuration: automatic failover when a provider endpoint degrades.
|
|
# Each policy monitors a primary provider+model and redirects traffic to a fallback
|
|
# when the circuit opens based on response header signals.
|
|
# circuitBreakerConfig:
|
|
# policies:
|
|
# - name: "azure-gpt4-ptu-failover"
|
|
# enabled: true
|
|
# primary_provider: "azure"
|
|
# primary_model: "gpt-4-ptu"
|
|
# primary_key_ids: [] # leave empty for a single shared circuit
|
|
# fallback_provider: "openai"
|
|
# fallback_model: "gpt-4o"
|
|
# condition:
|
|
# operator: "OR" # OR (default) | AND
|
|
# signals:
|
|
# - source: "response_header"
|
|
# header_name: "x-ms-throttle-reason"
|
|
# header_value: "ModelCapacityExceeded"
|
|
# default_cooldown: "30s" # Go duration; used when no header-based cooldown
|
|
# cooldown_header: "retry-after-ms" # header whose value (ms) overrides default_cooldown
|
|
|
|
# Storage configuration
|
|
storage:
|
|
# Default storage mode: sqlite or postgres
|
|
# Used as fallback when per-store type is not specified
|
|
mode: sqlite # Options: sqlite, postgres
|
|
|
|
# Persistent volume for SQLite databases (when using sqlite for any store)
|
|
persistence:
|
|
enabled: true
|
|
# storageClass: "-" # Use default storage class
|
|
accessMode: ReadWriteOnce
|
|
size: 10Gi
|
|
# existingClaim: "" # Use an existing PVC
|
|
|
|
# Configuration store settings
|
|
configStore:
|
|
enabled: true
|
|
# Backend type for config store. Empty string uses storage.mode as default
|
|
type: "" # Options: sqlite, postgres, or "" (uses storage.mode)
|
|
# PostgreSQL connection pool tuning (only applies when type is postgres)
|
|
# maxIdleConns: 5
|
|
# maxOpenConns: 50
|
|
|
|
# Vault store for external secret management (enterprise).
|
|
# Resolves "vault.<path>" references in config fields at load time.
|
|
# vaultStore:
|
|
# enabled: true
|
|
# type: aws-secrets-manager # Options: aws-secrets-manager, gcp-secret-manager, hashicorp-vault
|
|
# prefix: bifrost # Path prefix applied to every secret (default: bifrost)
|
|
# accessMode: read_only # read_only or read_and_write
|
|
#
|
|
# # AWS Secrets Manager
|
|
# aws:
|
|
# region: us-east-1
|
|
# accessKeyId: "" # Leave empty to use default AWS credential chain
|
|
# secretAccessKey: ""
|
|
# sessionToken: "" # AWS STS session token (optional)
|
|
# roleArn: "" # IAM role ARN to assume via STS
|
|
# kmsKeyId: "" # Customer-managed KMS key for encryption
|
|
#
|
|
# # GCP Secret Manager
|
|
# gcp:
|
|
# projectId: ""
|
|
# credentialsJson: "" # Service account JSON; omit for default credentials
|
|
#
|
|
# # HashiCorp Vault (KV v2)
|
|
# hashicorp:
|
|
# address: https://vault.example.com
|
|
# token: "" # Static token; omit to use AppRole auth
|
|
# namespace: "" # Vault namespace (HCP Vault / Enterprise)
|
|
# mountPath: secret # KV v2 mount path
|
|
# roleId: "" # AppRole role_id
|
|
# secretId: "" # AppRole secret_id
|
|
|
|
# Logs store settings
|
|
logsStore:
|
|
enabled: true
|
|
# Backend type for logs store. Empty string uses storage.mode as default
|
|
type: "" # Options: sqlite, postgres, clickhouse, or "" (uses storage.mode)
|
|
# PostgreSQL connection pool tuning (only applies when type is postgres)
|
|
# maxIdleConns: 5
|
|
# maxOpenConns: 50
|
|
# matviewRefreshInterval: "30s" # How often to refresh materialized views. Go duration string (e.g. '30s', '5m', '1h'). Minimum 5s.
|
|
# ClickHouse connection settings (only applies when type is clickhouse)
|
|
# clickhouse:
|
|
# host: "clickhouse.default.svc.cluster.local" # Required
|
|
# port: "9000" # Defaults by protocol: native 9000 (9440 TLS), http 8123 (8443 TLS)
|
|
# database: "default"
|
|
# username: "default"
|
|
# password: "env.CLICKHOUSE_PASSWORD"
|
|
# protocol: "native" # Options: native, http (default: native)
|
|
# secure: false # Enable TLS
|
|
# dialTimeout: 10000 # Connection dial timeout in milliseconds
|
|
# cluster: "" # Optional cluster name; runs DDL ON CLUSTER with replicated engines
|
|
# Async writer queue and batch tuning. Omitted fields use Bifrost defaults.
|
|
# writer:
|
|
# maxBatchSize: 1000
|
|
# batchInterval: "5s"
|
|
# maxBatchBytes: 314572800
|
|
# writeQueueCapacity: 10000
|
|
# deferredUsageConcurrency: 5
|
|
# Keep selected payload fields in DB instead of offloading to object storage.
|
|
# Uses log payload DB column names (e.g., input_history, output_message, raw_request, raw_response).
|
|
objectStorageExcludeFields: []
|
|
|
|
# Object storage for offloading large log payloads (optional)
|
|
# When enabled, request/response payloads are stored in S3/GCS
|
|
# while the DB keeps only lightweight index data for fast analytics.
|
|
objectStorage:
|
|
enabled: false
|
|
# type: s3 # Options: s3, gcs
|
|
# bucket: "" # Bucket name
|
|
# prefix: bifrost # Key prefix for stored objects
|
|
# compress: false # Enable gzip compression for stored objects
|
|
|
|
# S3 configuration (when type is s3)
|
|
# region: us-east-1
|
|
# endpoint: "" # Custom endpoint for MinIO/R2
|
|
# accessKeyId: "" # Leave empty to use default AWS credential chain
|
|
# secretAccessKey: "" # (instance role, env vars, shared credentials, etc.)
|
|
# sessionToken: "" # AWS STS session token (optional)
|
|
# roleArn: "" # AWS IAM role ARN to assume via STS (works with static creds or instance role)
|
|
# forcePathStyle: false # Set true for MinIO
|
|
|
|
# GCS configuration (when type is gcs)
|
|
# projectId: ""
|
|
# credentialsJson: "" # Service account JSON, omit for default credentials
|
|
|
|
# PostgreSQL configuration (when any store uses postgres)
|
|
postgresql:
|
|
# Deploy PostgreSQL as part of this chart
|
|
enabled: false
|
|
|
|
# Use external PostgreSQL instance
|
|
external:
|
|
enabled: false
|
|
host: ""
|
|
port: 5432
|
|
user: bifrost
|
|
password: ""
|
|
# Command executed by Bifrost to produce the PostgreSQL password on stdout.
|
|
# Use for dynamic credentials such as AWS RDS IAM auth tokens.
|
|
# passwordCommand:
|
|
# command: aws
|
|
# args:
|
|
# - rds
|
|
# - generate-db-auth-token
|
|
# - --hostname
|
|
# - your-rds-endpoint.us-east-1.rds.amazonaws.com
|
|
# - --port
|
|
# - "5432"
|
|
# - --region
|
|
# - us-east-1
|
|
# - --username
|
|
# - bifrost
|
|
# timeout: 10s
|
|
# connMaxLifetime: 10m
|
|
database: bifrost
|
|
sslMode: disable
|
|
# Use existing Kubernetes secret for password (takes precedence over password field)
|
|
existingSecret: ""
|
|
passwordKey: "password"
|
|
|
|
# PostgreSQL image configuration
|
|
image:
|
|
repository: postgres
|
|
tag: "16-alpine"
|
|
pullPolicy: IfNotPresent
|
|
|
|
# PostgreSQL subchart configuration (when postgresql.enabled is true)
|
|
auth:
|
|
username: bifrost
|
|
password: bifrost_password
|
|
database: bifrost
|
|
# Use existing Kubernetes secret for password (takes precedence over password field).
|
|
# The postgres pod and bifrost will both read from this secret.
|
|
existingSecret: ""
|
|
passwordKey: "password"
|
|
|
|
primary:
|
|
persistence:
|
|
enabled: true
|
|
size: 8Gi
|
|
# storageClass: "-" # "-" disables dynamic provisioning; empty uses the cluster default.
|
|
|
|
resources:
|
|
limits:
|
|
cpu: 1000m
|
|
memory: 1Gi
|
|
requests:
|
|
cpu: 250m
|
|
memory: 256Mi
|
|
|
|
podSecurityContext:
|
|
fsGroup: 999
|
|
|
|
containerSecurityContext: {}
|
|
|
|
# PostgreSQL scheduling is independent from the Bifrost application pods.
|
|
# Set these explicitly for the target Meesho cluster's node-pool topology.
|
|
nodeSelector: {}
|
|
tolerations: []
|
|
affinity: {}
|
|
|
|
metrics:
|
|
enabled: false
|
|
|
|
# Vector store configuration
|
|
vectorStore:
|
|
# Enable vector store for semantic caching
|
|
enabled: false
|
|
type: none # Options: none, weaviate, redis, qdrant
|
|
|
|
# Weaviate configuration
|
|
weaviate:
|
|
# Deploy Weaviate as part of this chart
|
|
enabled: false
|
|
|
|
# Use external Weaviate instance
|
|
external:
|
|
enabled: false
|
|
scheme: http
|
|
host: ""
|
|
apiKey: ""
|
|
grpcHost: ""
|
|
grpcSecured: false
|
|
# timeout: "5s" # Timeout for operations (e.g., "5s", "30s")
|
|
# className: "" # Class name for vector store
|
|
# Use existing Kubernetes secret for API key (takes precedence over apiKey field)
|
|
existingSecret: ""
|
|
apiKeyKey: "api-key"
|
|
|
|
# Weaviate subchart configuration (when weaviate.enabled is true)
|
|
replicas: 1
|
|
|
|
image:
|
|
repository: semitechnologies/weaviate
|
|
tag: "1.24.1"
|
|
|
|
persistence:
|
|
enabled: true
|
|
size: 10Gi
|
|
|
|
resources:
|
|
limits:
|
|
cpu: 1000m
|
|
memory: 2Gi
|
|
requests:
|
|
cpu: 500m
|
|
memory: 1Gi
|
|
|
|
env:
|
|
QUERY_DEFAULTS_LIMIT: "25"
|
|
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: "true"
|
|
PERSISTENCE_DATA_PATH: "/var/lib/weaviate"
|
|
DEFAULT_VECTORIZER_MODULE: "none"
|
|
ENABLE_MODULES: ""
|
|
CLUSTER_HOSTNAME: "node1"
|
|
|
|
# Redis configuration
|
|
redis:
|
|
# Deploy Redis as part of this chart
|
|
enabled: false
|
|
|
|
# Use external Redis instance
|
|
external:
|
|
enabled: false
|
|
host: ""
|
|
port: 6379
|
|
username: ""
|
|
password: ""
|
|
database: 0
|
|
useTls: false # Enable TLS for Redis connection
|
|
insecureSkipVerify: false # Skip TLS certificate verification
|
|
caCertPem: "" # PEM-encoded CA certificate to trust for Redis TLS
|
|
clusterMode: false # Use Redis Cluster mode (required for AWS MemoryDB)
|
|
# Connection pool tuning (optional)
|
|
# poolSize: 10 # Maximum number of socket connections
|
|
# maxActiveConns: 0 # Maximum number of active connections
|
|
# minIdleConns: 0 # Minimum number of idle connections
|
|
# maxIdleConns: 0 # Maximum number of idle connections
|
|
# connMaxLifetime: "" # Connection max lifetime (e.g., "30m")
|
|
# connMaxIdleTime: "" # Connection max idle time (e.g., "5m")
|
|
# dialTimeout: "" # Socket connection timeout (e.g., "5s")
|
|
# readTimeout: "" # Socket read timeout (e.g., "3s")
|
|
# writeTimeout: "" # Socket write timeout (e.g., "3s")
|
|
# contextTimeout: "" # Redis operation timeout (e.g., "10s")
|
|
# Use existing Kubernetes secret for password (takes precedence over password field)
|
|
existingSecret: ""
|
|
passwordKey: "password"
|
|
|
|
# Redis image configuration
|
|
image:
|
|
repository: redis/redis-stack-server
|
|
tag: "7.2.0-v20"
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Redis subchart configuration (when redis.enabled is true)
|
|
auth:
|
|
enabled: true
|
|
password: "redis_password"
|
|
|
|
master:
|
|
persistence:
|
|
enabled: true
|
|
size: 8Gi
|
|
|
|
resources:
|
|
limits:
|
|
cpu: 500m
|
|
memory: 512Mi
|
|
requests:
|
|
cpu: 250m
|
|
memory: 256Mi
|
|
|
|
metrics:
|
|
enabled: false
|
|
|
|
# Qdrant configuration
|
|
qdrant:
|
|
# Deploy Qdrant as part of this chart
|
|
enabled: false
|
|
|
|
# Use external Qdrant instance
|
|
external:
|
|
enabled: false
|
|
host: ""
|
|
port: 6334
|
|
apiKey: ""
|
|
useTls: false
|
|
# Use existing Kubernetes secret for API key (takes precedence over apiKey field)
|
|
existingSecret: ""
|
|
apiKeyKey: "api-key"
|
|
|
|
# Qdrant image configuration
|
|
image:
|
|
repository: qdrant/qdrant
|
|
tag: "v1.16.0"
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Qdrant subchart configuration (when qdrant.enabled is true)
|
|
persistence:
|
|
enabled: true
|
|
size: 10Gi
|
|
|
|
resources:
|
|
limits:
|
|
cpu: 1000m
|
|
memory: 2Gi
|
|
requests:
|
|
cpu: 500m
|
|
memory: 1Gi
|
|
|
|
# Pinecone configuration (external only, no self-hosted option)
|
|
pinecone:
|
|
external:
|
|
enabled: false
|
|
apiKey: ""
|
|
indexHost: "" # Index host URL from Pinecone console (e.g., your-index.svc.environment.pinecone.io)
|
|
# Use existing Kubernetes secret for API key (takes precedence over apiKey field)
|
|
existingSecret: ""
|
|
apiKeyKey: "api-key"
|
|
|
|
# Environment variables
|
|
env: []
|
|
# - name: CUSTOM_ENV_VAR
|
|
# value: "value"
|
|
|
|
# Additional environment variables appended after env
|
|
extraEnv: {}
|
|
# ANOTHER_ENV_VAR: "value"
|
|
|
|
# Environment variables from secrets/configmaps
|
|
envFrom: []
|
|
# - secretRef:
|
|
# name: my-secret
|
|
# - configMapRef:
|
|
# name: my-configmap
|
|
|
|
# Init containers to run before the main application container.
|
|
# Provide a list of init containers using standard Kubernetes container spec.
|
|
initContainers: []
|
|
|
|
# --- Meesho Infrastructure Extensions ---
|
|
|
|
# PodDisruptionBudget for the Bifrost application pods.
|
|
podDisruptionBudget:
|
|
enabled: false
|
|
maxUnavailable: "10%"
|
|
# minAvailable: ""
|
|
|
|
# Pull a Kubernetes Secret from Vault through external-secrets.io. For the
|
|
# bundled PostgreSQL deployment, reference the result with
|
|
# postgresql.auth.existingSecret and postgresql.auth.passwordKey.
|
|
externalSecret:
|
|
enabled: false
|
|
secretName: ""
|
|
path: ""
|
|
version: ""
|
|
refreshInterval: "0"
|
|
secretStoreRef: "vault-backend"
|
|
|
|
# KEDA ScaledObject for the Bifrost Deployment. Keep autoscaling.enabled=false
|
|
# when this is enabled.
|
|
keda:
|
|
enabled: false
|
|
pollingInterval: 30
|
|
minReplicaCount: 2
|
|
maxReplicaCount: 200
|
|
scaledown:
|
|
stabilizationWindowSeconds: 1800
|
|
selectpolicy: Min
|
|
policies:
|
|
- type: Pods
|
|
value: 2
|
|
periodseconds: 15
|
|
scaleup:
|
|
stabilizationWindowSeconds: 120
|
|
selectpolicy: Max
|
|
policies:
|
|
- type: Pods
|
|
value: 2
|
|
periodseconds: 15
|
|
- type: Percent
|
|
value: 10
|
|
periodseconds: 15
|
|
triggers:
|
|
- type: cpu
|
|
metricType: Utilization
|
|
metadata:
|
|
value: "40"
|