# Global configuration global: # Image registry and pull policy imageRegistry: "ghcr.io" # Use registry for all images, not just simstudioai/* images useRegistryForAllImages: false imagePullSecrets: [] # Common labels applied to all resources commonLabels: {} # Storage class for persistent volumes storageClass: "" # Main Sim application configuration app: # Enable/disable the main application enabled: true # Image configuration image: repository: simstudioai/simstudio # tag defaults to Chart.AppVersion. Override with a release tag (e.g. "0.6.73") or pin via image.digest. tag: "" # Optional image digest pin: "sha256:..." — when set, overrides tag. digest: "" pullPolicy: IfNotPresent # Number of replicas replicaCount: 1 # Resource limits and requests resources: limits: memory: "8Gi" cpu: "2000m" requests: memory: "4Gi" cpu: "1000m" # Node selector for pod scheduling (leave empty to allow scheduling on any node) nodeSelector: {} # Topology spread constraints for app pods (HA across zones / nodes). # Each entry must include its own labelSelector. topologySpreadConstraints: [] # Pod security context podSecurityContext: fsGroup: 1001 # Container security context securityContext: runAsNonRoot: true runAsUser: 1001 # Secret management configuration # Use this to reference pre-existing Kubernetes secrets instead of defining values directly # This enables integration with External Secrets Operator, HashiCorp Vault, Azure Key Vault, etc. secrets: existingSecret: # Set to true to use an existing secret instead of creating one from values enabled: false # Name of the existing Kubernetes secret containing app credentials name: "" # Key mappings - specify the key names in your existing secret # Only needed if your secret uses different key names than the defaults keys: BETTER_AUTH_SECRET: "BETTER_AUTH_SECRET" ENCRYPTION_KEY: "ENCRYPTION_KEY" INTERNAL_API_SECRET: "INTERNAL_API_SECRET" CRON_SECRET: "CRON_SECRET" API_ENCRYPTION_KEY: "API_ENCRYPTION_KEY" REDIS_URL: "REDIS_URL" # Environment variables env: # Application URLs — set NEXT_PUBLIC_APP_URL / BETTER_AUTH_URL to your public origin # (e.g. https://sim.example.com). Defaults to http://localhost:3000 via app.envDefaults # for local installs; override here (or via --set) for production. Set values here go # into the chart-managed Secret and take precedence over envDefaults at runtime. NEXT_PUBLIC_APP_URL: "" BETTER_AUTH_URL: "" INTERNAL_API_BASE_URL: "" # Optional server-side internal base URL for /api self-calls (include http:// or https://); falls back to NEXT_PUBLIC_APP_URL when empty # TRUSTED_ORIGINS: comma-separated extra public origins to trust for auth (e.g. apex+www, alias hostnames). # Merged into Better Auth `trustedOrigins` alongside NEXT_PUBLIC_APP_URL. Leave empty when serving from a single origin. TRUSTED_ORIGINS: "" # SOCKET_SERVER_URL: Auto-detected when realtime.enabled=true (uses internal service) # NEXT_PUBLIC_SOCKET_URL: public WebSocket URL for browsers. Leave empty to default to the # page's own origin (assumes the ingress/reverse proxy routes /socket.io to the realtime service). # Set explicitly only when realtime is on a separate host:port from the app (e.g. wss://socket.example.com). NEXT_PUBLIC_SOCKET_URL: "" # Telemetry & Monitoring TELEMETRY_ENDPOINT: "" # OTLP endpoint for traces/logs (e.g., "https://otlp-collector:4318/v1/traces") # Authentication and encryption secrets (REQUIRED for production) # Generate secure 32-character secrets using: openssl rand -hex 32 BETTER_AUTH_SECRET: "" # REQUIRED - set via --set flag or external secret manager ENCRYPTION_KEY: "" # REQUIRED - set via --set flag or external secret manager INTERNAL_API_SECRET: "" # REQUIRED - set via --set flag or external secret manager, used for internal service-to-service authentication # Optional: Scheduled Jobs Authentication # Generate using: openssl rand -hex 32 CRON_SECRET: "" # OPTIONAL - required only if cronjobs.enabled=true, authenticates scheduled job requests # Optional: API Key Encryption (RECOMMENDED for production) # Generate with: openssl rand -hex 32 (produces the required 64-hex-char / 32-byte value). API_ENCRYPTION_KEY: "" # OPTIONAL - encrypts API keys at rest; if unset, keys are stored in plain text REDIS_URL: "" # OPTIONAL - Redis connection string for caching/sessions; can also come from app secret or External Secrets # Email & Communication # Configure one provider — the mailer auto-detects in priority order: # Resend → AWS SES → SMTP → Azure Communication Services. EMAIL_VERIFICATION_ENABLED: "" # Set to "true" to enable email verification for user registration and login (default "false" via envDefaults) RESEND_API_KEY: "" # Resend API key for transactional emails FROM_EMAIL_ADDRESS: "" # Complete from address (e.g., "Sim " or "DoNotReply@domain.com") EMAIL_DOMAIN: "" # Domain for sending emails (fallback when FROM_EMAIL_ADDRESS not set) AWS_SES_REGION: "" # AWS region for SES (e.g., "us-east-1"); credentials resolved via the standard AWS provider chain (env, IRSA, instance profile) AZURE_ACS_CONNECTION_STRING: "" # Azure Communication Services connection string (email provider — used when Resend/SES/SMTP are not configured) SMTP_HOST: "" # SMTP server hostname (alternative to Resend/SES) SMTP_PORT: "" # SMTP server port (465 for TLS, 587 for STARTTLS, 25 for plain) SMTP_USER: "" # SMTP username (optional — omit for unauthenticated relays like MailHog) SMTP_PASS: "" # SMTP password (optional — omit for unauthenticated relays) SMTP_SECURE: "" # Set to "true" to force TLS on connect; defaults to true when SMTP_PORT=465 # OAuth Integration Credentials (leave empty if not using) GOOGLE_CLIENT_ID: "" # Google OAuth client ID GOOGLE_CLIENT_SECRET: "" # Google OAuth client secret GITHUB_CLIENT_ID: "" # GitHub OAuth client ID GITHUB_CLIENT_SECRET: "" # GitHub OAuth client secret DISABLE_GOOGLE_AUTH: "" # Set to "true" to hide Google OAuth login DISABLE_GITHUB_AUTH: "" # Set to "true" to hide GitHub OAuth login # Google Vertex AI Configuration VERTEX_PROJECT: "" # Google Cloud project ID for Vertex AI VERTEX_LOCATION: "" # Google Cloud region for Vertex AI (default "us-central1" via envDefaults) # Azure OpenAI Configuration (leave empty if not using Azure OpenAI) AZURE_OPENAI_ENDPOINT: "" # Azure OpenAI service endpoint (e.g., https://your-resource.openai.azure.com) AZURE_OPENAI_API_KEY: "" # Azure OpenAI API key AZURE_OPENAI_API_VERSION: "" # Azure OpenAI API version (e.g., 2024-07-01-preview) # Azure Anthropic Configuration (leave empty if not using Azure Anthropic via AI Foundry) AZURE_ANTHROPIC_ENDPOINT: "" # Azure AI Foundry endpoint for Anthropic models AZURE_ANTHROPIC_API_KEY: "" # Azure Anthropic API key AZURE_ANTHROPIC_API_VERSION: "" # Azure Anthropic API version (e.g., 2023-06-01) KB_OPENAI_MODEL_NAME: "" # Azure deployment name serving the configured KB embedding model (used only when AZURE_OPENAI_* credentials are set) WAND_OPENAI_MODEL_NAME: "" # Wand generation model deployment name (works with both regular OpenAI and Azure OpenAI) # Azure Mistral OCR Configuration (leave empty if not using Azure-hosted OCR for document processing) OCR_AZURE_ENDPOINT: "" # Azure Mistral OCR service endpoint OCR_AZURE_MODEL_NAME: "" # Azure Mistral OCR model name OCR_AZURE_API_KEY: "" # Azure Mistral OCR API key # AI Provider API Keys (leave empty if not using) OPENAI_API_KEY: "" # Primary OpenAI API key OPENAI_API_KEY_1: "" # Additional OpenAI API key for load balancing OPENAI_API_KEY_2: "" # Additional OpenAI API key for load balancing OPENAI_API_KEY_3: "" # Additional OpenAI API key for load balancing MISTRAL_API_KEY: "" # Mistral AI API key FIREWORKS_API_KEY: "" # Fireworks AI API key (for hosted model access) ANTHROPIC_API_KEY_1: "" # Primary Anthropic Claude API key ANTHROPIC_API_KEY_2: "" # Additional Anthropic API key for load balancing ANTHROPIC_API_KEY_3: "" # Additional Anthropic API key for load balancing OLLAMA_URL: "" # Ollama local LLM server URL PII_URL: "" # Presidio PII service URL; auto-computed when pii.enabled, override here otherwise ELEVENLABS_API_KEY: "" # ElevenLabs API key for text-to-speech in deployed chat # UI Branding & Whitelabeling Configuration NEXT_PUBLIC_BRAND_NAME: "" # Custom brand name (default "Sim" via envDefaults) NEXT_PUBLIC_BRAND_LOGO_URL: "" # Custom logo URL — square icon, shown in collapsed sidebar NEXT_PUBLIC_BRAND_WORDMARK_URL: "" # Custom wordmark URL — wide image, shown in expanded sidebar NEXT_PUBLIC_BRAND_FAVICON_URL: "" # Custom favicon URL (leave empty for default) NEXT_PUBLIC_BRAND_PRIMARY_COLOR: "" # Primary brand color (hex, e.g., "#701a75") NEXT_PUBLIC_BRAND_ACCENT_COLOR: "" # Accent color (hex, e.g., "#9333ea") NEXT_PUBLIC_BRAND_BACKGROUND_COLOR: "" # Background color (hex, e.g., "#ffffff") NEXT_PUBLIC_CUSTOM_CSS_URL: "" # Custom stylesheet URL (leave empty for none) NEXT_PUBLIC_SUPPORT_EMAIL: "" # Support email address (default "help@sim.ai" via envDefaults) NEXT_PUBLIC_DOCUMENTATION_URL: "" # Documentation URL (leave empty for none) NEXT_PUBLIC_TERMS_URL: "" # Terms of service URL (leave empty for none) NEXT_PUBLIC_PRIVACY_URL: "" # Privacy policy URL (leave empty for none) # Registration Control DISABLE_REGISTRATION: "" # Set to "true" to disable new user signups EMAIL_PASSWORD_SIGNUP_ENABLED: "" # Set to "false" to disable email/password login (SSO-only mode, server-side enforcement) NEXT_PUBLIC_EMAIL_PASSWORD_SIGNUP_ENABLED: "" # Set to "false" to hide email/password login form (UI-side) # Bot Protection (Cloudflare Turnstile) TURNSTILE_SECRET_KEY: "" # Cloudflare Turnstile secret key (leave empty to disable captcha) NEXT_PUBLIC_TURNSTILE_SITE_KEY: "" # Cloudflare Turnstile site key (leave empty to disable captcha) # Access Control (leave empty if not restricting login) ALLOWED_LOGIN_EMAILS: "" # Comma-separated list of allowed email addresses for login ALLOWED_LOGIN_DOMAINS: "" # Comma-separated list of allowed email domains for login # Admin API Configuration ADMIN_API_KEY: "" # Admin API key for organization/user management (generate with: openssl rand -hex 32) # Organizations & Permission Groups (defaults to "false" via envDefaults — set "true" here to enable) ACCESS_CONTROL_ENABLED: "" # Enable permission groups feature ("true" to enable) ORGANIZATIONS_ENABLED: "" # Enable organizations feature ("true" to enable) NEXT_PUBLIC_ACCESS_CONTROL_ENABLED: "" # Show permission groups UI ("true" to enable) NEXT_PUBLIC_ORGANIZATIONS_ENABLED: "" # Show organizations UI ("true" to enable) # LLM Provider/Model Restrictions (leave empty if not restricting) BLACKLISTED_PROVIDERS: "" # Comma-separated provider IDs to hide from UI (e.g., "openai,anthropic,google") BLACKLISTED_MODELS: "" # Comma-separated model names/prefixes to hide (e.g., "gpt-4,claude-*") ALLOWED_MCP_DOMAINS: "" # Comma-separated domains for MCP servers (e.g., "internal.company.com,mcp.example.org"). Empty = all allowed. # Integration/Block Restrictions (leave empty if not restricting) ALLOWED_INTEGRATIONS: "" # Comma-separated block types to allow (e.g., "slack,github,agent"). Empty = all allowed. # Invitation Control DISABLE_INVITATIONS: "" # Set to "true" to disable workspace invitations globally NEXT_PUBLIC_DISABLE_INVITATIONS: "" # Set to "true" to hide invitation UI elements # Public API Access Control DISABLE_PUBLIC_API: "" # Set to "true" to disable public API toggle globally NEXT_PUBLIC_DISABLE_PUBLIC_API: "" # Set to "true" to hide public API toggle in UI # SSO Configuration (Enterprise Single Sign-On) # Set to "true" AFTER running the SSO registration script SSO_ENABLED: "" # Enable SSO authentication ("true" to enable) NEXT_PUBLIC_SSO_ENABLED: "" # Show SSO login button in UI ("true" to enable) # SSO_TRUSTED_PROVIDER_IDS: comma-separated SSO provider IDs to trust for automatic account linking when a # user signs in via SSO and an account with the same email already exists. Only needed for IdPs that do NOT # assert email_verified (trustEmailVerified already handles those that do). Resolved at startup — restart after editing. SSO_TRUSTED_PROVIDER_IDS: "" # Enterprise Feature Overrides (self-hosted) INBOX_ENABLED: "" # Enable Sim Mailer on self-hosted ("true" to enable) NEXT_PUBLIC_INBOX_ENABLED: "" # Show Sim Mailer settings page ("true" to enable) WHITELABELING_ENABLED: "" # Enable whitelabeling on self-hosted ("true" to enable) NEXT_PUBLIC_WHITELABELING_ENABLED: "" # Show whitelabeling settings page ("true" to enable) AUDIT_LOGS_ENABLED: "" # Enable audit logs on self-hosted ("true" to enable) NEXT_PUBLIC_AUDIT_LOGS_ENABLED: "" # Show audit logs settings page ("true" to enable) DATA_DRAINS_ENABLED: "" # Enable data drains on self-hosted ("true" to enable) NEXT_PUBLIC_DATA_DRAINS_ENABLED: "" # Show data drains settings page ("true" to enable) # AWS Bedrock Credential Mode # Set to "true" when the deployment uses AWS default credential chain (IAM roles, instance # profiles, ECS task roles, IRSA, etc.) instead of explicit access key/secret per workflow. # When enabled, the AWS Access Key ID and Secret fields are hidden in the Agent block UI. NEXT_PUBLIC_BEDROCK_DEFAULT_CREDENTIALS: "" # Set to "true" to hide Bedrock credential fields # Azure Provider Credential Mode # Set to "true" when AZURE_OPENAI_ENDPOINT/API_KEY (and/or AZURE_ANTHROPIC_*) are configured # server-side. When enabled, the Azure endpoint, API key, and API version fields are hidden # in the Agent block UI — users just pick an Azure model and run. NEXT_PUBLIC_AZURE_CONFIGURED: "" # Set to "true" to hide Azure credential fields # Cohere Reranker (Knowledge block) # Set COHERE_API_KEY (or COHERE_API_KEY_1/2/3 for rotation) and NEXT_PUBLIC_COHERE_CONFIGURED=true # to pre-configure the Cohere reranker server-side. When configured, the Cohere API Key field is # hidden in the Knowledge block UI. NEXT_PUBLIC_COHERE_CONFIGURED: "" # Set to "true" to hide the Cohere API Key field on the Knowledge block # AWS S3 Cloud Storage Configuration (optional - for file storage) # If configured, files will be stored in S3 instead of local storage AWS_REGION: "" # AWS region (e.g., "us-east-1") AWS_ACCESS_KEY_ID: "" # AWS access key ID AWS_SECRET_ACCESS_KEY: "" # AWS secret access key S3_BUCKET_NAME: "" # S3 bucket for workspace files S3_KB_BUCKET_NAME: "" # S3 bucket for knowledge base files S3_EXECUTION_FILES_BUCKET_NAME: "" # S3 bucket for workflow execution files S3_CHAT_BUCKET_NAME: "" # S3 bucket for deployed chat files S3_COPILOT_BUCKET_NAME: "" # S3 bucket for copilot files S3_PROFILE_PICTURES_BUCKET_NAME: "" # S3 bucket for user profile pictures S3_OG_IMAGES_BUCKET_NAME: "" # S3 bucket for OpenGraph preview images S3_WORKSPACE_LOGOS_BUCKET_NAME: "" # S3 bucket for workspace logos S3_ENDPOINT: "" # Custom endpoint for S3-compatible storage (Cloudflare R2, MinIO, Backblaze B2). Leave empty for AWS S3 S3_FORCE_PATH_STYLE: "" # Set to "true" for path-style addressing (MinIO/Ceph RGW). Leave empty for AWS S3 and R2 # Azure Blob Storage Configuration (optional - for file storage) # If configured, files will be stored in Azure Blob instead of local storage # Note: Azure Blob takes precedence over S3 if both are configured AZURE_ACCOUNT_NAME: "" # Azure storage account name AZURE_ACCOUNT_KEY: "" # Azure storage account key AZURE_CONNECTION_STRING: "" # Azure connection string (alternative to account name/key) AZURE_STORAGE_CONTAINER_NAME: "" # Azure container for workspace files AZURE_STORAGE_KB_CONTAINER_NAME: "" # Azure container for knowledge base files AZURE_STORAGE_EXECUTION_FILES_CONTAINER_NAME: "" # Azure container for workflow execution files AZURE_STORAGE_CHAT_CONTAINER_NAME: "" # Azure container for deployed chat files AZURE_STORAGE_COPILOT_CONTAINER_NAME: "" # Azure container for copilot files AZURE_STORAGE_PROFILE_PICTURES_CONTAINER_NAME: "" # Azure container for user profile pictures AZURE_STORAGE_OG_IMAGES_CONTAINER_NAME: "" # Azure container for OpenGraph preview images AZURE_STORAGE_WORKSPACE_LOGOS_CONTAINER_NAME: "" # Azure container for workspace logos # Operational tunables shipped with the chart. These are rendered as inline `env:` on the # app container — NOT written into the chart-managed Secret and NOT required to be mapped # when externalSecrets.enabled=true. Override any key by setting `app.envDefaults.KEY` in # your values file. Move a key into `app.env` above only if it must be treated as secret. envDefaults: # Application URLs (override in app.env or app.envDefaults for production) NEXT_PUBLIC_APP_URL: "http://localhost:3000" BETTER_AUTH_URL: "http://localhost:3000" # Node environment NODE_ENV: "production" NEXT_TELEMETRY_DISABLED: "1" # Email defaults EMAIL_VERIFICATION_ENABLED: "false" # Vertex AI defaults VERTEX_LOCATION: "us-central1" # Branding defaults NEXT_PUBLIC_BRAND_NAME: "Sim" NEXT_PUBLIC_SUPPORT_EMAIL: "help@sim.ai" # Feature flags (default off — set "true" in app.env or app.envDefaults to enable) ACCESS_CONTROL_ENABLED: "false" ORGANIZATIONS_ENABLED: "false" NEXT_PUBLIC_ACCESS_CONTROL_ENABLED: "false" NEXT_PUBLIC_ORGANIZATIONS_ENABLED: "false" # Admission Gate ADMISSION_GATE_MAX_INFLIGHT: "500" # Max concurrent in-flight execution requests per pod # Rate Limiting (per minute) RATE_LIMIT_WINDOW_MS: "60000" # Rate limit window duration (1 minute) RATE_LIMIT_FREE_SYNC: "50" # Sync API executions per minute RATE_LIMIT_FREE_ASYNC: "200" # Async API executions per minute # Execution Timeouts (seconds) — sync timeouts apply to synchronous API calls EXECUTION_TIMEOUT_FREE: "300" # Free tier sync timeout (5 minutes) EXECUTION_TIMEOUT_PRO: "3000" # Pro tier sync timeout (50 minutes) EXECUTION_TIMEOUT_TEAM: "3000" # Team tier sync timeout (50 minutes) EXECUTION_TIMEOUT_ENTERPRISE: "3000" # Enterprise tier sync timeout (50 minutes) # Async timeouts apply to async/background job executions EXECUTION_TIMEOUT_ASYNC_FREE: "5400" # Free tier async timeout (90 minutes) EXECUTION_TIMEOUT_ASYNC_PRO: "5400" # Pro tier async timeout (90 minutes) EXECUTION_TIMEOUT_ASYNC_TEAM: "5400" # Team tier async timeout (90 minutes) EXECUTION_TIMEOUT_ASYNC_ENTERPRISE: "5400" # Enterprise tier async timeout (90 minutes) # Table Feature Limits (per workspace, per plan) FREE_TABLES_LIMIT: "3" # Max user tables per workspace on free tier FREE_TABLE_ROWS_LIMIT: "1000" # Max rows per table on free tier PRO_TABLES_LIMIT: "25" # Max user tables per workspace on pro tier PRO_TABLE_ROWS_LIMIT: "5000" # Max rows per table on pro tier TEAM_TABLES_LIMIT: "100" # Max user tables per workspace on team tier TEAM_TABLE_ROWS_LIMIT: "10000" # Max rows per table on team tier ENTERPRISE_TABLES_LIMIT: "10000" # Max user tables per workspace on enterprise tier ENTERPRISE_TABLE_ROWS_LIMIT: "1000000" # Max rows per table on enterprise tier # Isolated-VM Worker Pool IVM_POOL_SIZE: "4" # Max worker processes in pool IVM_MAX_CONCURRENT: "10000" # Max concurrent executions globally IVM_MAX_PER_WORKER: "2500" # Max concurrent executions per worker IVM_WORKER_IDLE_TIMEOUT_MS: "60000" # Worker idle cleanup timeout (ms) IVM_QUEUE_TIMEOUT_MS: "300000" # Max queue wait before rejection (ms) IVM_MAX_QUEUE_SIZE: "10000" # Max queued executions globally IVM_MAX_ACTIVE_PER_OWNER: "200" # Max concurrent executions per user IVM_MAX_QUEUED_PER_OWNER: "2000" # Max queued executions per user IVM_MAX_OWNER_WEIGHT: "5" # Max scheduling weight per user IVM_DISTRIBUTED_MAX_INFLIGHT_PER_OWNER: "2200" # Max in-flight per user across instances (Redis) IVM_DISTRIBUTED_LEASE_MIN_TTL_MS: "120000" # Min distributed lease TTL (ms) IVM_MAX_FETCH_RESPONSE_BYTES: "8388608" # Max fetch response size (8MB) IVM_MAX_FETCH_RESPONSE_CHARS: "4000000" # Max fetch response chars IVM_MAX_FETCH_URL_LENGTH: "8192" # Max fetch URL length IVM_MAX_FETCH_OPTIONS_JSON_CHARS: "262144" # Max fetch options payload (256KB) IVM_MAX_STDOUT_CHARS: "200000" # Max stdout capture per execution # Service configuration service: type: ClusterIP port: 3000 targetPort: 3000 # Health checks # startupProbe shields a slow Next.js cold start (large bundle, 4Gi memory limits) from # liveness restarts. Once it succeeds, liveness + readiness take over. Total cold-start # budget: failureThreshold * periodSeconds = 60 * 5s = 300s (5 minutes). startupProbe: httpGet: path: / port: 3000 initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 60 # Liveness: lenient — only restart on true deadlock. failureThreshold * periodSeconds = 180s. livenessProbe: httpGet: path: / port: 3000 initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 5 failureThreshold: 6 # Readiness: fast — shift traffic in/out within ~30s of state change. readinessProbe: httpGet: path: / port: 3000 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 3 # Additional volumes for app deployment (e.g., branding assets, custom configs) extraVolumes: [] extraVolumeMounts: [] # Realtime socket server configuration realtime: # Enable/disable the realtime service enabled: true # Image configuration image: repository: simstudioai/realtime # tag defaults to Chart.AppVersion. Override with a release tag or pin via image.digest. tag: "" digest: "" pullPolicy: IfNotPresent # Number of replicas replicaCount: 1 # Resource limits and requests resources: limits: memory: "1Gi" cpu: "500m" requests: memory: "512Mi" cpu: "250m" # Node selector for pod scheduling (leave empty to allow scheduling on any node) nodeSelector: {} # Topology spread constraints for realtime pods (HA across zones / nodes). # Each entry must include its own labelSelector. topologySpreadConstraints: [] # Pod security context podSecurityContext: fsGroup: 1001 # Container security context securityContext: runAsNonRoot: true runAsUser: 1001 # Environment variables — Secret-bound. See `envDefaults` below for chart-shipped defaults. env: # Application URLs — must mirror the public origin used by the main app. # Defaults to http://localhost:3000 via envDefaults; override here for production. NEXT_PUBLIC_APP_URL: "" BETTER_AUTH_URL: "" # Authentication secret (REQUIRED for production) # Must match the BETTER_AUTH_SECRET value from the main app configuration BETTER_AUTH_SECRET: "" # REQUIRED - set via --set flag or external secret manager # Cross-Origin Resource Sharing (CORS) allowed origins for the realtime service. # Set to the same public origin(s) as the main app (comma-separated). The realtime # service rejects WebSocket upgrades from origins not in this list. # Defaults to http://localhost:3000 via envDefaults; override here for production. ALLOWED_ORIGINS: "" # Operational defaults shipped with the chart. Rendered as inline `env:` on the realtime # container (NOT written into the Secret, NOT required in externalSecrets.remoteRefs). # User-set values in `realtime.env` above take precedence. envDefaults: NEXT_PUBLIC_APP_URL: "http://localhost:3000" BETTER_AUTH_URL: "http://localhost:3000" ALLOWED_ORIGINS: "http://localhost:3000" NODE_ENV: "production" # Service configuration service: type: ClusterIP port: 3002 targetPort: 3002 # Health checks # Startup probe absorbs cold-start time. Total budget: 30 * 5s = 150s. startupProbe: httpGet: path: /health port: 3002 initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 30 # Liveness: lenient. failureThreshold * periodSeconds = 180s. livenessProbe: httpGet: path: /health port: 3002 initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 5 failureThreshold: 6 # Readiness: fast. readinessProbe: httpGet: path: /health port: 3002 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 3 # Additional volumes for realtime deployment extraVolumes: [] extraVolumeMounts: [] # Database migrations job configuration migrations: # Enable/disable migrations job enabled: true # Image configuration image: repository: simstudioai/migrations # tag defaults to Chart.AppVersion. Override with a release tag or pin via image.digest. tag: "" digest: "" pullPolicy: IfNotPresent # Resource limits and requests resources: limits: memory: "1Gi" requests: memory: "512Mi" cpu: "100m" # Pod security context podSecurityContext: fsGroup: 1001 # Container security context securityContext: runAsNonRoot: true runAsUser: 1001 # PostgreSQL database configuration postgresql: # Enable/disable internal PostgreSQL deployment enabled: true # Image configuration image: repository: pgvector/pgvector tag: pg17 pullPolicy: IfNotPresent # Authentication configuration auth: username: postgres password: "" # REQUIRED - set via --set flag or external secret manager database: sim # Use an existing secret for PostgreSQL credentials # This enables integration with External Secrets Operator, HashiCorp Vault, etc. existingSecret: enabled: false name: "" # Name of existing Kubernetes secret passwordKey: "POSTGRES_PASSWORD" # Key in the secret containing the password # Node selector for database pod scheduling (leave empty to allow scheduling on any node) nodeSelector: {} # Resource limits and requests resources: limits: memory: "2Gi" requests: memory: "1Gi" cpu: "500m" # Pod security context # PostgreSQL image's `postgres` user is uid/gid 999. podSecurityContext: runAsNonRoot: true runAsUser: 999 runAsGroup: 999 fsGroup: 999 # Container security context # readOnlyRootFilesystem is intentionally false — Postgres writes to /var/lib/postgresql/data # (mounted from PVC) and needs to manage its own data directory. securityContext: runAsNonRoot: true runAsUser: 999 runAsGroup: 999 # Persistence configuration persistence: enabled: true storageClass: "" size: 10Gi accessModes: - ReadWriteOnce # SSL/TLS configuration (enable for production deployments with certificates) # Requires cert-manager to be installed in the cluster tls: enabled: false certificatesSecret: postgres-tls-secret # Certificate configuration (only used if enabled) duration: "87600h" # 10 years (default) renewBefore: "2160h" # Renew 90 days before expiry (default) rotationPolicy: "" # Set to "Always" to rotate private key on renewal (recommended for security) privateKey: algorithm: RSA # RSA or ECDSA size: 4096 # Key size in bits # Issuer reference (REQUIRED if tls.enabled is true) # By default, references the CA issuer created by certManager.caIssuer # Make sure certManager.enabled is true, or provide your own issuer issuerRef: name: sim-ca-issuer # Name of your cert-manager Issuer/ClusterIssuer kind: ClusterIssuer # ClusterIssuer or Issuer group: "" # Optional: cert-manager.io (leave empty for default) # Additional DNS names (optional) additionalDnsNames: [] # Example: # additionalDnsNames: # - postgres.example.com # - db.example.com # PostgreSQL configuration config: maxConnections: 1000 sharedBuffers: "1280MB" maxWalSize: "4GB" minWalSize: "80MB" # Service configuration service: type: ClusterIP port: 5432 targetPort: 5432 # Health checks # startupProbe shields liveness from slow first-boot scenarios (pgvector # extension init, WAL replay after a crash on a large data dir). Gives # postgres up to 150s (30 * 5s) to become ready before liveness takes over. startupProbe: exec: command: ["pg_isready", "-U", "postgres", "-d", "sim"] periodSeconds: 5 failureThreshold: 30 timeoutSeconds: 5 livenessProbe: exec: command: ["pg_isready", "-U", "postgres", "-d", "sim"] initialDelaySeconds: 10 periodSeconds: 5 readinessProbe: exec: command: ["pg_isready", "-U", "postgres", "-d", "sim"] initialDelaySeconds: 5 periodSeconds: 3 # External database configuration (use when connecting to managed database services) externalDatabase: # Enable to use an external database instead of the internal PostgreSQL instance enabled: false # Database connection details host: "external-db.example.com" port: 5432 username: postgres password: "" database: sim # SSL configuration sslMode: require # Use an existing secret for external database credentials # This enables integration with External Secrets Operator, HashiCorp Vault, etc. existingSecret: enabled: false name: "" # Name of existing Kubernetes secret passwordKey: "EXTERNAL_DB_PASSWORD" # Key in the secret containing the password # Ollama local AI models configuration ollama: # Enable/disable Ollama deployment enabled: false # Image configuration image: repository: ollama/ollama # Pinned to a stable release rather than "latest" to keep deployments reproducible. # 0.23.2 is the latest stable Ollama as of May 2026 # (https://github.com/ollama/ollama/releases/tag/v0.23.2). tag: "0.23.2" digest: "" pullPolicy: IfNotPresent # Number of replicas replicaCount: 1 # GPU configuration gpu: enabled: false count: 1 # GPU sharing strategy: "mig" (Multi-Instance GPU) or "time-slicing" # - mig: Hardware-level GPU partitioning (requires supported GPUs like A100) # - time-slicing: Software-level GPU sharing (works with most NVIDIA GPUs) strategy: "time-slicing" # Number of time-slicing replicas (only used when strategy is "time-slicing") timeSlicingReplicas: 5 # Node selector for GPU workloads (adjust labels based on your cluster configuration) nodeSelector: accelerator: nvidia # Tolerations for GPU nodes (adjust based on your cluster's GPU node taints) tolerations: - key: "sku" operator: "Equal" value: "gpu" effect: "NoSchedule" # Resource limits and requests resources: limits: memory: "8Gi" nvidia.com/gpu: "1" requests: memory: "4Gi" cpu: "1000m" # Pod security context # The upstream ollama/ollama image is built to run as root and writes models to # /root/.ollama by default. To meet Pod Security Standards "restricted", we run # as a non-root user (1001) and rely on fsGroup to make the mounted PVC writable. # Override OLLAMA_MODELS env (or remount /root/.ollama) if your image expects root. podSecurityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 # Container security context # readOnlyRootFilesystem is intentionally false — Ollama writes model blobs to its data dir. securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 # Environment variables env: NVIDIA_DRIVER_CAPABILITIES: "all" OLLAMA_LOAD_TIMEOUT: "-1" OLLAMA_KEEP_ALIVE: "-1" OLLAMA_DEBUG: "1" # The default OLLAMA model dir is /root/.ollama, which a non-root user can't write. # Point it at a path under the writable PVC mount instead. HOME: "/tmp" OLLAMA_MODELS: "/data/models" # Persistence configuration persistence: enabled: true storageClass: "" size: 100Gi accessModes: - ReadWriteOnce # Service configuration service: type: ClusterIP port: 11434 targetPort: 11434 # Health checks startupProbe: httpGet: path: / port: 11434 initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 10 livenessProbe: httpGet: path: / port: 11434 initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 5 readinessProbe: httpGet: path: / port: 11434 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 # Additional volumes for ollama deployment extraVolumes: [] extraVolumeMounts: [] # Presidio PII redaction service (analyzer + anonymizer combined, port 5001). # When enabled, the app's PII_URL is auto-wired to this in-cluster service so the # Guardrails PII block and on-demand masking work. To additionally enable automatic # log redaction, set app.env.PII_REDACTION="true" AND app.env.INTERNAL_API_BASE_URL # to the in-cluster app service URL (the redaction path calls the app's own # /api/guardrails/mask-batch, which must be reachable from inside the cluster). pii: # Enable/disable the PII redaction service enabled: false # Image configuration. repository resolves to ghcr.io/simstudioai/pii — the # sim.image helper auto-prepends global.imageRegistry to simstudioai/* repos, # so do NOT fully-qualify it here. image: repository: simstudioai/pii tag: "" # defaults to Chart.AppVersion digest: "" # sha256: pin overrides tag pullPolicy: IfNotPresent # NER engine: "spacy" (default) or "gliner" (opt-in zero-shot transformer NER # for PERSON/LOCATION/NRP/DATE_TIME; regex/checksum recognizers are identical # on both engines). The image ships both engines, so this is a pure env flip # — no image change needed. Note: gliner on CPU is orders of magnitude slower # than spacy; it is intended for GPU nodes. engine: "spacy" # Torch device for the gliner engine: "cpu", "cuda", or "cuda:N". Empty # auto-detects (cuda when a GPU is visible, else cpu). GPU resource requests # (nvidia.com/gpu) are not wired yet — GPU scheduling is an infra follow-up. device: "" # Number of replicas replicaCount: 1 # Resource limits and requests. Five large spaCy models (en/es/it/pl/fi, ~2.2GB) # load into memory at startup, so size generously. resources: limits: memory: "8Gi" cpu: "2000m" requests: memory: "4Gi" cpu: "1000m" # The sim.podSecurityContext / sim.containerSecurityContext helpers already inject # non-root + uid/gid/fsGroup 1001 + restricted defaults (drop ALL caps, no privilege # escalation, RuntimeDefault seccomp), matching docker/pii.Dockerfile's USER 1001. # Leave these empty to inherit those defaults; override only if you must. podSecurityContext: {} securityContext: {} # Environment variables for the service container env: {} # Node scheduling. nodeSelector pins the (memory-heavy, ~4Gi) service to a # node pool; tolerations are inherited from the top-level `tolerations` key # (shared with app/realtime), and topologySpreadConstraints spreads replicas. nodeSelector: {} topologySpreadConstraints: [] # Service configuration service: type: ClusterIP port: 5001 targetPort: 5001 # Health checks. Cold start is slow (~180s) while spaCy models load, so the # startupProbe grace is generous (failureThreshold * periodSeconds ≈ 300s). startupProbe: httpGet: path: /health port: 5001 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 30 livenessProbe: httpGet: path: /health port: 5001 periodSeconds: 30 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /health port: 5001 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 # Additional volumes for the pii deployment extraVolumes: [] extraVolumeMounts: [] # Ingress configuration # When services share the same host, paths are consolidated into a single rule. # Path order: realtime paths, copilot paths, then app paths (most specific first). # Ensure specific paths (e.g., /socket.io, /copilot) come before catch-all paths (/). ingress: enabled: false className: nginx annotations: nginx.ingress.kubernetes.io/force-ssl-redirect: "true" # Production recommendations (uncomment & adjust to your environment): # # Automatic TLS via cert-manager. Issuer name varies per cluster # (e.g. letsencrypt-prod, letsencrypt-staging, internal-ca). # cert-manager.io/cluster-issuer: letsencrypt-prod # # Allow larger uploads (knowledge base / file ingestion). # nginx.ingress.kubernetes.io/proxy-body-size: "50m" # # Long timeouts for streaming SSE / LLM responses. # nginx.ingress.kubernetes.io/proxy-read-timeout: "300" # nginx.ingress.kubernetes.io/proxy-send-timeout: "300" # Main application (use / as catch-all) app: host: sim.local paths: - path: / pathType: Prefix # Realtime service (use /socket.io when sharing host with app) realtime: host: sim-ws.local paths: - path: / pathType: Prefix # Copilot service (optional, use /copilot when sharing host) # copilot: # host: sim.local # paths: # - path: /copilot # pathType: Prefix tls: enabled: false secretName: sim-tls-secret # Internal Ingress configuration # Same path ordering rules apply as above. ingressInternal: enabled: false className: nginx annotations: {} app: host: sim-internal.local paths: - path: / pathType: Prefix realtime: host: sim-internal.local paths: - path: /socket.io pathType: Prefix # copilot: # host: sim-internal.local # paths: # - path: /copilot # pathType: Prefix tls: enabled: false secretName: sim-internal-tls-secret # Service Account configuration serviceAccount: # Specifies whether a service account should be created create: true # Annotations to add to the service account annotations: {} # The name of the service account to use name: "" # Horizontal Pod Autoscaler for app and realtime deployments. # When enabled, the chart omits spec.replicas from the Deployment so the HPA # owns replica count. Requires metrics-server (or a custom metrics adapter # if you use customMetrics) installed in the cluster. autoscaling: enabled: false minReplicas: 1 maxReplicas: 10 targetCPUUtilizationPercentage: 80 targetMemoryUtilizationPercentage: 80 # Custom metrics for scaling (advanced users can add custom metrics here) customMetrics: [] # Scaling behavior configuration (customize scale-up/down policies) # Example configuration: # behavior: # scaleDown: # stabilizationWindowSeconds: 300 # policies: # - type: Percent # value: 50 # periodSeconds: 60 # scaleUp: # stabilizationWindowSeconds: 60 # policies: # - type: Percent # value: 100 # periodSeconds: 15 # - type: Pods # value: 2 # periodSeconds: 60 behavior: {} # Pod disruption budget # Note: PDBs only protect against voluntary disruptions (node drains, autoscaler). # They do NOT affect rolling updates — use deployment.strategy.rollingUpdate for that. # # Tri-state activation: # enabled: true → force PDB on (any replicaCount) # enabled: false → force PDB off (explicit opt-out, even at replicaCount > 1) # enabled: null → auto-enable when replicaCount > 1 (recommended default) podDisruptionBudget: enabled: null # Use either minAvailable or maxUnavailable (not both). # Percentages scale with HPA / replicaCount; absolute numbers do not. # Default `maxUnavailable: "25%"` allows rolling updates while keeping # 75% of pods serving — matches the K8s docs guidance for stateless HA # frontends (https://kubernetes.io/docs/tasks/run-application/configure-pdb/). # - minAvailable: minimum pods that must remain available (e.g., 1, "90%") # - maxUnavailable: maximum pods that can be unavailable (e.g., 1, "25%") minAvailable: null maxUnavailable: "25%" # unhealthyPodEvictionPolicy: allows eviction of unhealthy pods during node drains # Options: IfHealthyBudget (default) | AlwaysAllow (recommended for production) # Set to null to use K8s default (IfHealthyBudget) unhealthyPodEvictionPolicy: null # Prometheus monitoring integration. # Creates a ServiceMonitor CR scraped by the Prometheus Operator. Requires # the kube-prometheus-stack (or prometheus-operator) CRDs to be installed # in the cluster — otherwise the manifest is rejected by the API server. monitoring: # ServiceMonitor for Prometheus serviceMonitor: enabled: false # Additional labels for ServiceMonitor labels: {} # Additional annotations for ServiceMonitor annotations: {} # Metrics path path: /metrics # Scrape interval interval: 30s # Scrape timeout scrapeTimeout: 10s # Target labels to be added to scraped metrics targetLabels: [] # Metric relabeling configurations metricRelabelings: [] # Relabeling configurations relabelings: [] # NetworkPolicy for east-west and egress isolation. # When enabled, the chart creates policies that allow Sim components to talk # to each other and to required external services (DNS, HTTPS) while blocking # everything else. The egress block additionally blacklists cloud metadata # endpoints (169.254.169.254/32, 169.254.170.2/32) by default — extend # egressExceptCidrs with your cluster's API server CIDR for tighter isolation. # Your CNI must support NetworkPolicy (Calico, Cilium, GKE Dataplane V2, etc.). networkPolicy: enabled: false # NetworkPolicyPeers allowed to reach the app/realtime pods on the # ingress-controller path. Defaults to `- {}` (any source), which matches the # common case where the ingress controller is the only thing routing to these # ports. To restrict ingress to a specific controller namespace, replace with: # ingressFrom: # - namespaceSelector: # matchLabels: # kubernetes.io/metadata.name: ingress-nginx ingressFrom: - {} # Custom ingress rules appended to the policy ingress: [] # Custom egress rules appended to the policy. # Kept as a top-level list (not a map) for backward compatibility with the # pre-1.0 chart that shipped `networkPolicy.egress: []`. Existing values # files continue to work without changes. egress: [] # CIDRs excluded from broad HTTPS (443) egress. # Defaults block AWS/GCP/Azure IMDS (169.254.169.254/32) and ECS task metadata # (169.254.170.2/32). Add your cluster's API server CIDR for stronger isolation. egressExceptCidrs: - "169.254.169.254/32" - "169.254.170.2/32" # Shared storage for enterprise workflows requiring data sharing between pods sharedStorage: enabled: false # Storage class for shared volumes (must support ReadWriteMany access) storageClass: "" # Default access modes for shared volumes (ReadWriteMany required for multi-pod access) defaultAccessModes: - ReadWriteMany # Define shared volumes for your workflows (uncomment and customize as needed) # Example volume configurations: # volumes: # - name: output-share # size: 100Gi # accessModes: # - ReadWriteMany # annotations: {} # - name: rawdata-share # size: 500Gi # accessModes: # - ReadWriteMany # - name: model-share # size: 200Gi # accessModes: # - ReadWriteMany # - name: logs-share # size: 50Gi # accessModes: # - ReadWriteMany volumes: [] # Additional volumes for custom configurations (advanced users) extraVolumes: [] extraVolumeMounts: [] # Branding configuration # Use this to inject custom branding assets (logos, CSS, etc.) into the application branding: # Enable/disable branding ConfigMap enabled: false # Mount path in the container where branding files will be available mountPath: "/app/public/branding" # Text files (CSS, JSON, HTML, etc.) - values are plain text # Example: # files: # custom.css: | # .logo { background-color: #ff0000; } # config.json: | # {"theme": "dark"} files: {} # Binary files (PNG, JPG, ICO, etc.) - values must be base64 encoded # Generate base64 with: base64 -i logo.png | tr -d '\n' # Example: # binaryFiles: # logo.png: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk..." # favicon.ico: "AAABAAEAEBAAAAEAIABoBAAAFgAAAA..." binaryFiles: {} # Additional environment variables for custom integrations extraEnvVars: [] # Pod annotations for custom metadata podAnnotations: {} # Pod labels for custom labeling podLabels: {} # Affinity settings for advanced pod scheduling affinity: {} # Tolerations for scheduling on tainted nodes tolerations: [] # CronJob configuration for scheduled tasks cronjobs: # Enable/disable all cron jobs enabled: true # Individual job configurations jobs: scheduleExecution: enabled: true name: schedule-execution schedule: "*/1 * * * *" path: "/api/schedules/execute" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 gmailWebhookPoll: enabled: true name: gmail-webhook-poll schedule: "*/1 * * * *" path: "/api/webhooks/poll/gmail" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 outlookWebhookPoll: enabled: true name: outlook-webhook-poll schedule: "*/1 * * * *" path: "/api/webhooks/poll/outlook" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 rssWebhookPoll: enabled: true name: rss-webhook-poll schedule: "*/1 * * * *" path: "/api/webhooks/poll/rss" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 imapWebhookPoll: enabled: true name: imap-webhook-poll schedule: "*/1 * * * *" path: "/api/webhooks/poll/imap" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 googleSheetsWebhookPoll: enabled: true name: google-sheets-webhook-poll schedule: "*/1 * * * *" path: "/api/webhooks/poll/google-sheets" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 googleDriveWebhookPoll: enabled: true name: google-drive-webhook-poll schedule: "*/1 * * * *" path: "/api/webhooks/poll/google-drive" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 googleCalendarWebhookPoll: enabled: true name: google-calendar-webhook-poll schedule: "*/1 * * * *" path: "/api/webhooks/poll/google-calendar" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 hubspotWebhookPoll: enabled: true name: hubspot-webhook-poll schedule: "*/1 * * * *" path: "/api/webhooks/poll/hubspot" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 renewSubscriptions: enabled: true name: renew-subscriptions schedule: "0 */12 * * *" path: "/api/cron/renew-subscriptions" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 reconcileBillingSeats: enabled: true name: reconcile-billing-seats schedule: "0 * * * *" path: "/api/cron/reconcile-billing-seats" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 # Releases AgentMail inbox + webhook for workspaces whose Sim Mailer plan # lapsed (canceled/downgraded off Max/Enterprise). Tolerates past_due, so a # transient payment failure never tears down a paying customer's inbox. reconcileInboxEntitlement: enabled: true name: reconcile-inbox-entitlement schedule: "0 3 * * *" path: "/api/cron/reconcile-inbox-entitlement" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 workspaceEventsPoll: enabled: true name: workspace-events-poll schedule: "*/15 * * * *" path: "/api/workspace-events/poll" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 timePauseResumePoll: enabled: true name: time-pause-resume-poll schedule: "*/1 * * * *" path: "/api/resume/poll" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 connectorSync: enabled: true name: connector-sync schedule: "*/5 * * * *" path: "/api/knowledge/connectors/sync" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 runDataDrains: enabled: true name: run-data-drains schedule: "0 * * * *" path: "/api/cron/run-data-drains" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 # Processes the transactional outbox (deployment side-effects retry / dead-letter) # and reaps stale workspace-fork background-work rows. Both are safety nets behind # the immediate post-commit processing, so frequent runs keep retries timely. outboxProcess: enabled: true name: outbox-process schedule: "*/1 * * * *" path: "/api/webhooks/outbox/process" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 1 # Global CronJob settings image: repository: curlimages/curl tag: 8.5.0 pullPolicy: IfNotPresent resources: limits: memory: "128Mi" cpu: "100m" requests: memory: "64Mi" cpu: "50m" restartPolicy: OnFailure activeDeadlineSeconds: 300 startingDeadlineSeconds: 60 # Pod security context podSecurityContext: fsGroup: 1001 # Container security context securityContext: runAsNonRoot: true runAsUser: 1001 # Observability and telemetry configuration telemetry: # Enable/disable telemetry collection enabled: false # OpenTelemetry Collector image image: repository: otel/opentelemetry-collector-contrib tag: 0.91.0 pullPolicy: IfNotPresent # Number of collector replicas replicaCount: 1 # Resource limits and requests resources: limits: memory: "512Mi" cpu: "500m" requests: memory: "256Mi" cpu: "100m" # Node selector for telemetry pod scheduling (leave empty to allow scheduling on any node) nodeSelector: {} # Tolerations for telemetry workloads tolerations: [] # Affinity for telemetry workloads affinity: {} # Service configuration service: type: ClusterIP # Jaeger tracing backend jaeger: enabled: false endpoint: "http://jaeger-collector:14250" tls: enabled: false # Prometheus metrics backend prometheus: enabled: false endpoint: "http://prometheus-server/api/v1/write" auth: "" # Generic OTLP backend otlp: enabled: false endpoint: "http://otlp-collector:4317" tls: enabled: false # Pod security context (preserves the collector's original UID/GID/fsGroup) podSecurityContext: runAsUser: 10001 runAsGroup: 10001 fsGroup: 10001 # Container security context (sim.containerSecurityContext restricted defaults apply) securityContext: {} # Copilot service configuration (optional microservice) copilot: # Enable/disable the copilot service enabled: false # Server deployment configuration server: # Image configuration image: repository: simstudioai/copilot # tag defaults to Chart.AppVersion. Override with a release tag or pin via image.digest. tag: "" digest: "" pullPolicy: IfNotPresent # Number of replicas replicaCount: 1 # Resource limits and requests resources: limits: memory: "2Gi" cpu: "1000m" requests: memory: "1Gi" cpu: "500m" # Node selector for pod scheduling # Leave empty to run on same infrastructure as main Sim platform # Or specify labels to isolate on dedicated nodes: { "workload-type": "copilot" } nodeSelector: {} # Pod security context podSecurityContext: fsGroup: 1001 # Container security context securityContext: runAsNonRoot: true runAsUser: 1001 # Environment variables that go through the chart-managed Secret (or ExternalSecret # when externalSecrets.enabled=true). Every non-empty key here must have a matching # externalSecrets.remoteRefs.copilot entry under ESO — reserve this block for values # that are genuinely sensitive or user-provided; static operational config belongs in # envDefaults below instead. env: AGENT_API_DB_ENCRYPTION_KEY: "" INTERNAL_API_SECRET: "" LICENSE_KEY: "" OPENAI_API_KEY_1: "" ANTHROPIC_API_KEY_1: "" SIM_BASE_URL: "" SIM_AGENT_API_KEY: "" REDIS_URL: "" CORS_ALLOWED_ORIGINS: "" OTEL_EXPORTER_OTLP_ENDPOINT: "" # Operational tunables shipped with the chart. Rendered as inline `env:` on the # copilot container — NOT written into the chart-managed Secret and NOT required to # be mapped when externalSecrets.enabled=true. Override any key by setting # copilot.server.envDefaults.KEY in your values file. Move a key into # copilot.server.env above only if it must be treated as secret. envDefaults: PORT: "8080" SERVICE_NAME: "copilot" ENVIRONMENT: "production" LOG_LEVEL: "info" # Optional: additional static environment variables extraEnv: [] # Optional: references to existing ConfigMaps/Secrets extraEnvFrom: [] # Optional: additional volumes/mounts (e.g. to back an emptyDir /tmp when # enabling securityContext.readOnlyRootFilesystem) extraVolumes: [] extraVolumeMounts: [] # Secret generation configuration (set create=false to use an existing secret) secret: create: true name: "" annotations: {} # Service configuration service: type: ClusterIP port: 8080 targetPort: 8080 # Health checks # Startup probe absorbs cold-start time. Total budget: 30 * 5s = 150s. startupProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 30 readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 3 failureThreshold: 3 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 5 failureThreshold: 6 # Pod Disruption Budget for high availability podDisruptionBudget: enabled: false minAvailable: 1 # PostgreSQL database for copilot (separate from main Sim database) postgresql: # Enable/disable internal PostgreSQL for copilot enabled: true # Image configuration image: repository: postgres tag: 17-alpine pullPolicy: IfNotPresent # Authentication configuration auth: username: copilot password: "" # REQUIRED - set via --set flag or external secret manager database: copilot # Node selector for database pod scheduling # Leave empty to run on same infrastructure as main Sim platform # Or specify labels to isolate on dedicated nodes: { "workload-type": "copilot" } nodeSelector: {} # Resource limits and requests resources: limits: memory: "1Gi" cpu: "500m" requests: memory: "512Mi" cpu: "250m" # Pod security context # PostgreSQL image's `postgres` user is uid/gid 999. podSecurityContext: runAsNonRoot: true runAsUser: 999 runAsGroup: 999 fsGroup: 999 # Container security context # readOnlyRootFilesystem is intentionally false — Postgres writes to /var/lib/postgresql/data. securityContext: runAsNonRoot: true runAsUser: 999 runAsGroup: 999 # Persistence configuration persistence: enabled: true storageClass: "" size: 10Gi accessModes: - ReadWriteOnce # Service configuration service: type: ClusterIP port: 5432 targetPort: 5432 # Health checks # startupProbe shields liveness from slow first-boot scenarios (pgvector # extension init, WAL replay after a crash). Gives postgres up to 150s # (30 * 5s) to become ready before liveness takes over. startupProbe: exec: command: ["pg_isready", "-U", "copilot", "-d", "copilot"] periodSeconds: 5 failureThreshold: 30 timeoutSeconds: 5 livenessProbe: exec: command: ["pg_isready", "-U", "copilot", "-d", "copilot"] initialDelaySeconds: 10 periodSeconds: 5 timeoutSeconds: 5 failureThreshold: 10 readinessProbe: exec: command: ["pg_isready", "-U", "copilot", "-d", "copilot"] initialDelaySeconds: 5 periodSeconds: 3 timeoutSeconds: 5 failureThreshold: 10 # External database configuration (use when connecting to a managed database) database: existingSecretName: "" secretKey: DATABASE_URL url: "" # Migration job configuration migrations: # Enable/disable migrations job enabled: true # Image configuration (same as server) image: repository: simstudioai/copilot # tag defaults to Chart.AppVersion. Override with a release tag or pin via image.digest. tag: "" digest: "" pullPolicy: IfNotPresent # Resource limits and requests resources: limits: memory: "512Mi" cpu: "500m" requests: memory: "256Mi" cpu: "100m" # Pod security context podSecurityContext: fsGroup: 1001 # Container security context securityContext: runAsNonRoot: true runAsUser: 1001 # Job configuration backoffLimit: 3 restartPolicy: OnFailure # External Secrets Operator integration # Use this to automatically sync secrets from external secret managers (Azure Key Vault, AWS Secrets Manager, etc.) # Prerequisites: Install External Secrets Operator in your cluster first # See: https://external-secrets.io/latest/introduction/getting-started/ externalSecrets: # Enable External Secrets Operator integration enabled: false # ESO API version. Default "v1beta1" — supported by every ESO release from # v0.7+ (mid-2023) through current. Set to "v1" only when targeting ESO # v0.17+ clusters where the v1 API has graduated. apiVersion: "v1beta1" # How often to sync secrets from the external store refreshInterval: "1h" # Reference to the SecretStore or ClusterSecretStore secretStoreRef: # Name of the SecretStore or ClusterSecretStore resource name: "" # Kind of the store: "SecretStore" (namespaced) or "ClusterSecretStore" (cluster-wide) kind: "ClusterSecretStore" # Remote references - paths/keys in your external secret store # These map to the secrets that will be created in Kubernetes remoteRefs: # App secrets (authentication, encryption keys) app: # Path to BETTER_AUTH_SECRET in external store (e.g., "sim/app/better-auth-secret") BETTER_AUTH_SECRET: "" # Path to ENCRYPTION_KEY in external store ENCRYPTION_KEY: "" # Path to INTERNAL_API_SECRET in external store INTERNAL_API_SECRET: "" # Path to CRON_SECRET in external store (optional) CRON_SECRET: "" # Path to API_ENCRYPTION_KEY in external store (optional) API_ENCRYPTION_KEY: "" # Path to REDIS_URL in external store (optional) REDIS_URL: "" # PostgreSQL password (for internal PostgreSQL) postgresql: # Path to PostgreSQL password in external store (e.g., "sim/postgresql/password") password: "" # External database password (when using managed database services) externalDatabase: # Path to external database password in external store password: "" # Copilot server secrets (used when copilot.enabled=true and copilot.server.secret.create=true). # Every non-empty copilot.server.env key must have a matching entry here, or template # rendering fails with a clear "map it or remove it" error — same rule as remoteRefs.app. copilot: # Path to AGENT_API_DB_ENCRYPTION_KEY in external store AGENT_API_DB_ENCRYPTION_KEY: "" # Path to INTERNAL_API_SECRET in external store (shared with app/realtime) INTERNAL_API_SECRET: "" # Path to LICENSE_KEY in external store LICENSE_KEY: "" # Path to SIM_BASE_URL in external store SIM_BASE_URL: "" # Path to SIM_AGENT_API_KEY in external store SIM_AGENT_API_KEY: "" # Path to REDIS_URL in external store REDIS_URL: "" # Path to OPENAI_API_KEY_1 in external store (one of OPENAI_API_KEY_1/ANTHROPIC_API_KEY_1 required) OPENAI_API_KEY_1: "" # Path to ANTHROPIC_API_KEY_1 in external store (one of OPENAI_API_KEY_1/ANTHROPIC_API_KEY_1 required) ANTHROPIC_API_KEY_1: "" # cert-manager configuration # Prerequisites: Install cert-manager in your cluster first # See: https://cert-manager.io/docs/installation/ # # This implements the recommended CA bootstrap pattern from cert-manager: # 1. Self-signed ClusterIssuer (bootstrap only - creates root CA) # 2. Root CA Certificate (self-signed, becomes the trust anchor) # 3. CA ClusterIssuer (signs application certificates using root CA) # # Reference: https://cert-manager.io/docs/configuration/selfsigned/ certManager: # Enable/disable cert-manager issuer resources enabled: false # Self-signed ClusterIssuer (used ONLY to bootstrap the root CA) # Do not reference this issuer directly for application certificates selfSignedIssuer: name: "sim-selfsigned-bootstrap-issuer" # Root CA Certificate configuration # This certificate is signed by the self-signed issuer and used as the trust anchor rootCA: # Name of the Certificate resource certificateName: "sim-root-ca" # Namespace where the root CA certificate and secret will be created # Must match cert-manager's cluster-resource-namespace (default: cert-manager) namespace: "cert-manager" # Common name for the root CA certificate commonName: "sim-root-ca" # Secret name where the root CA certificate and key will be stored secretName: "sim-root-ca-secret" # Certificate validity duration (default: 10 years) duration: "87600h" # Renew before expiry (default: 90 days) renewBefore: "2160h" # Private key configuration privateKey: algorithm: RSA size: 4096 # Subject configuration subject: organizations: [] # If empty, defaults to the release name # CA ClusterIssuer configuration # This is the issuer that applications should reference for obtaining certificates caIssuer: name: "sim-ca-issuer" # Helm test hook (helm test) connectivity probes. # Renders a Pod with helm.sh/hook=test that checks the app and realtime # Services are reachable from inside the cluster. Run with: helm test tests: enabled: true image: repository: busybox tag: "1.36" pullPolicy: IfNotPresent pullSecrets: [] timeoutSeconds: 5 resources: limits: cpu: 100m memory: 64Mi requests: cpu: 10m memory: 16Mi