# 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 "-". # 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__CONNECTION_STRING # # into the pod and rewrites connection_string in config.json # # to `env.BIFROST_MCP__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: "" # 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." 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"