mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 06:21:23 +00:00
* feat(helm): add Pipelock ConfigMap, scanning config, and consolidate compose - Add ConfigMap template rendering DLP, response scanning, MCP input/tool scanning, and forward proxy settings from values - Mount ConfigMap as /etc/pipelock/pipelock.yaml volume in deployment - Add checksum/config annotation for automatic pod restart on config change - Gate HTTPS_PROXY/HTTP_PROXY env injection on forwardProxy.enabled (skip in MCP-only mode) - Use hasKey for all boolean values to prevent Helm default swallowing false - Single source of truth for ports (forwardProxy.port/mcpProxy.port) - Pipelock-specific imagePullSecrets with fallback to app secrets - Merge standalone compose.example.pipelock.yml into compose.example.ai.yml - Add pipelock.example.yaml for Docker Compose users - Add exclude-paths to CI workflow for locale file false positives * Add external assistant support (OpenAI-compatible SSE proxy) Allow self-hosted instances to delegate chat to an external AI agent via an OpenAI-compatible streaming endpoint. Configurable per-family through Settings UI or ASSISTANT_TYPE env override. - Assistant::External::Client: SSE streaming HTTP client (no new gems) - Settings UI with type selector, env lock indicator, config status - Helm chart and Docker Compose env var support - 45 tests covering client, config, routing, controller, integration * Add session key routing, email allowlist, and config plumbing Route to the actual OpenClaw session via x-openclaw-session-key header instead of creating isolated sessions. Gate external assistant access behind an email allowlist (EXTERNAL_ASSISTANT_ALLOWED_EMAILS env var). Plumb session_key and allowedEmails through Helm chart, compose, and env template. * Add HTTPS_PROXY support to External::Client for Pipelock integration Net::HTTP does not auto-read HTTPS_PROXY/HTTP_PROXY env vars (unlike Faraday). Explicitly resolve proxy from environment in build_http so outbound traffic to the external assistant routes through Pipelock's forward proxy when enabled. Respects NO_PROXY for internal hosts. * Add UI fields for external assistant config (Setting-backed with env fallback) Follow the same pattern as OpenAI settings: database-backed Setting fields with env var defaults. Self-hosters can now configure the external assistant URL, token, and agent ID from the browser (Settings > Self-Hosting > AI Assistant) instead of requiring env vars. Fields disable when the corresponding env var is set. * Improve external assistant UI labels and add help text Change placeholder to generic OpenAI-compatible URL pattern. Add help text under each field explaining where the values come from: URL from agent provider, token for authentication, agent ID for multi-agent routing. * Add external assistant docs and fix URL help text Add External AI Assistant section to docs/hosting/ai.md covering setup (UI and env vars), how it works, Pipelock security scanning, access control, and Docker Compose example. Drop "chat completions" jargon from URL help text. * Harden external assistant: retry logic, disconnect UI, error handling, and test coverage - Add retry with backoff for transient network errors (no retry after streaming starts) - Add disconnect button with confirmation modal in self-hosting settings - Narrow rescue scope with fallback logging for unexpected errors - Safe cleanup of partial responses on stream interruption - Gate ai_available? on family assistant_type instead of OR-ing all providers - Truncate conversation history to last 20 messages - Proxy-aware HTTP client with NO_PROXY support - Sanitize protocol to use generic headers (X-Agent-Id, X-Session-Key) - Full test coverage for streaming, retries, proxy routing, config, and disconnect * Exclude external assistant client from Pipelock scan-diff False positive: `@token` instance variable flagged as "Credential in URL". Temporary workaround until Pipelock supports inline suppression. * Address review feedback: NO_PROXY boundary fix, SSE done flag, design tokens - Fix NO_PROXY matching to require domain boundary (exact match or .suffix), case-insensitive. Prevents badexample.com matching example.com. - Add done flag to SSE streaming so read_body stops after [DONE] - Move MAX_CONVERSATION_MESSAGES to class level - Use bg-success/bg-destructive design tokens for status indicators - Add rationale comment for pipelock scan exclusion - Update docs last-updated date * Address second round of review feedback - Allowlist email comparison is now case-insensitive and nil-safe - Cap SSE buffer at 1 MB to prevent memory blowup from malformed streams - Don't expose upstream HTTP response body in user-facing errors (log it instead) - Fix frozen string warning on buffer initialization - Fix "builtin" typo in docs (should be "built-in") * Protect completed responses from cleanup, sanitize error messages - Don't destroy a fully streamed assistant message if post-stream metadata update fails (only cleanup partial responses) - Log raw connection/HTTP errors internally, show generic messages to users to avoid leaking network/proxy details - Update test assertions for new error message wording * Fix SSE content guard and NO_PROXY test correctness Use nil check instead of present? for SSE delta content to preserve whitespace-only chunks (newlines, spaces) that can occur in code output. Fix NO_PROXY test to use HTTP_PROXY matching the http:// client URL so the proxy resolution and NO_PROXY bypass logic are actually exercised. * Forward proxy credentials to Net::HTTP Pass proxy_uri.user and proxy_uri.password to Net::HTTP.new so authenticated proxies (http://user:pass@host:port) work correctly. Without this, credentials parsed from the proxy URL were silently dropped. Nil values are safe as positional args when no creds exist. * Update pipelock integration to v0.3.1 with full scanning config Bump Helm image tag from 0.2.7 to 0.3.1. Add missing security sections to both the Helm ConfigMap and compose example config: mcp_tool_policy, mcp_session_binding, and tool_chain_detection. These protect the /mcp endpoint against tool injection, session hijacking, and multi-step exfiltration chains. Add version and mode fields to config files. Enable include_defaults for DLP and response scanning to merge user patterns with the 35 built-in patterns. Remove redundant --mode CLI flag from the Helm deployment template since mode is now in the config file. * Pipelock Helm hardening + docs for external assistant and pipelock Helm templates: - ServiceMonitor for Prometheus scraping on /metrics (proxy port) - Ingress template for MCP reverse proxy (external AI agent access) - PodDisruptionBudget with minAvailable/maxUnavailable mutual exclusion - topologySpreadConstraints on Deployment - Structured logging config (format, output, include_allowed/blocked) - extraConfig escape hatch for additional pipelock.yaml sections - requireForExternalAssistant guard (fails when assistant enabled without pipelock) - Component label on Service metadata for ServiceMonitor targeting - NOTES.txt pipelock section with health, access, security, metrics info - Bump pipelock image tag 0.3.1 -> 0.3.2 - Fix: rename _asserts.tpl -> asserts.tpl (Helm skipped _ prefixed file) Documentation: - Helm chart README: full Pipelock section - docs/hosting/pipelock.md: dedicated hosting guide (Docker + Kubernetes) - docs/hosting/docker.md: AI features section (external assistant, pipelock) - .env.example: external assistant and MCP env vars Infra: - Chart.lock pinning dependency versions - .gitignore for vendored subchart tarballs * Fix bot comments: quote ingress host, fix sidecar wording, add code block lang * Fail fast when pipelock ingress enabled with empty hosts * Fail fast when pipelock ingress host has empty paths * Messed up the conflict merge --------- Signed-off-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Juan José Mata <jjmata@jjmata.com>
161 lines
5.7 KiB
Plaintext
161 lines
5.7 KiB
Plaintext
# ================================ PLEASE READ ===========================================================
|
|
# This file outlines all the possible environment variables supported by the Sure app for self hosting.
|
|
#
|
|
# If you're a developer setting up your local environment, please use `.env.local.example` instead.
|
|
# ========================================================================================================
|
|
|
|
# Required self-hosting vars
|
|
# --------------------------------------------------------------------------------------------------------
|
|
|
|
# Enables self hosting features (should be set to true unless you know what you're doing)
|
|
SELF_HOSTED=true
|
|
|
|
# Controls onboarding flow (valid: open, closed, invite_only)
|
|
ONBOARDING_STATE=open
|
|
|
|
# Secret key used to encrypt credentials (https://api.rubyonrails.org/v7.1.3.2/classes/Rails/Application.html#method-i-secret_key_base)
|
|
# Has to be a random string, generated eg. by running `openssl rand -hex 64`
|
|
SECRET_KEY_BASE=secret-value
|
|
|
|
# Optional self-hosting vars
|
|
# --------------------------------------------------------------------------------------------------------
|
|
|
|
# Optional: OpenAI-compatible API endpoint config
|
|
OPENAI_ACCESS_TOKEN=
|
|
OPENAI_MODEL=
|
|
OPENAI_URI_BASE=
|
|
|
|
# Optional: External AI Assistant — delegates chat to a remote AI agent
|
|
# instead of calling LLMs directly. The agent calls back to Sure's /mcp endpoint.
|
|
# See docs/hosting/ai.md for full details.
|
|
# ASSISTANT_TYPE=external
|
|
# EXTERNAL_ASSISTANT_URL=https://your-agent-host/v1/chat/completions
|
|
# EXTERNAL_ASSISTANT_TOKEN=your-api-token
|
|
# EXTERNAL_ASSISTANT_AGENT_ID=main
|
|
# EXTERNAL_ASSISTANT_SESSION_KEY=agent:main:main
|
|
# EXTERNAL_ASSISTANT_ALLOWED_EMAILS=user@example.com
|
|
|
|
# Optional: MCP server endpoint — enables /mcp for external AI assistants.
|
|
# Both values are required. MCP_USER_EMAIL must match an existing user's email.
|
|
# MCP_API_TOKEN=your-random-bearer-token
|
|
# MCP_USER_EMAIL=user@example.com
|
|
|
|
# Optional: Langfuse config
|
|
LANGFUSE_HOST=https://cloud.langfuse.com
|
|
LANGFUSE_PUBLIC_KEY=
|
|
LANGFUSE_SECRET_KEY=
|
|
|
|
# Optional: Twelve Data API Key for exchange rates + stock prices
|
|
# (you can also set this in your self-hosted settings page)
|
|
# Get it here: https://twelvedata.com/
|
|
TWELVE_DATA_API_KEY=
|
|
|
|
# Optional: Provider selection for exchange rates and securities data
|
|
# Options: twelve_data (default), yahoo_finance
|
|
# EXCHANGE_RATE_PROVIDER=twelve_data
|
|
# SECURITIES_PROVIDER=twelve_data
|
|
|
|
# Alternative: Use Yahoo Finance as provider (free, no API key required)
|
|
EXCHANGE_RATE_PROVIDER=yahoo_finance
|
|
SECURITIES_PROVIDER=yahoo_finance
|
|
|
|
# Brandfetch to grab logos for banks and merchants
|
|
BRAND_FETCH_CLIENT_ID=
|
|
|
|
# Custom port config
|
|
# For users who have other applications listening at 3000, this allows them to set a value puma will listen to.
|
|
PORT=3000
|
|
|
|
# SMTP Configuration
|
|
# This is only needed if you intend on sending emails from your Sure instance (such as for password resets or email financial reports).
|
|
# Resend.com is a good option that offers a free tier for sending emails.
|
|
SMTP_ADDRESS=
|
|
SMTP_PORT=465
|
|
SMTP_USERNAME=
|
|
SMTP_PASSWORD=
|
|
SMTP_TLS_ENABLED=true
|
|
|
|
# Address that emails are sent from
|
|
EMAIL_SENDER=
|
|
|
|
# Database Configuration
|
|
DB_HOST=localhost # May need to be changed to `DB_HOST=db` if using devcontainer
|
|
DB_PORT=5432
|
|
POSTGRES_PASSWORD=postgres
|
|
POSTGRES_USER=postgres
|
|
|
|
# Redis configuration
|
|
# Standard Redis URL (for direct connection)
|
|
REDIS_URL=redis://localhost:6379/1
|
|
|
|
# Redis Sentinel configuration (for high availability)
|
|
# When REDIS_SENTINEL_HOSTS is set, it takes precedence over REDIS_URL
|
|
# REDIS_SENTINEL_HOSTS=sentinel1:26379,sentinel2:26379,sentinel3:26379
|
|
# REDIS_SENTINEL_MASTER=mymaster
|
|
# REDIS_SENTINEL_USERNAME=default
|
|
# REDIS_PASSWORD=your-redis-password
|
|
|
|
# App Domain
|
|
# This is the domain that your Sure instance will be hosted at. It is used to generate links in emails and other places.
|
|
APP_DOMAIN=
|
|
|
|
# OpenID Connect configuration
|
|
OIDC_CLIENT_ID=
|
|
OIDC_CLIENT_SECRET=
|
|
OIDC_ISSUER=
|
|
OIDC_REDIRECT_URI=
|
|
|
|
# Product/Brand Name
|
|
PRODUCT_NAME=
|
|
BRAND_NAME=
|
|
|
|
# PostHog configuration
|
|
POSTHOG_KEY=
|
|
POSTHOG_HOST=
|
|
|
|
# Disable enforcing SSL connections
|
|
# DISABLE_SSL=true
|
|
|
|
# Active Record Encryption Keys (Optional)
|
|
# These keys are used to encrypt sensitive data like API keys in the database.
|
|
# For managed mode: Set these environment variables to provide encryption keys.
|
|
# For self-hosted mode: If not provided, they will be automatically generated based on your SECRET_KEY_BASE.
|
|
# You can generate your own keys by running: rails db:encryption:init
|
|
# ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=
|
|
# ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=
|
|
# ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=
|
|
|
|
# ======================================================================================================
|
|
# Active Storage Configuration - responsible for storing file uploads
|
|
# ======================================================================================================
|
|
#
|
|
# * Defaults to disk storage but you can also use Amazon S3 or Cloudflare R2
|
|
# * Set the appropriate environment variables to use these services.
|
|
# * Ensure libvips is installed on your system for image processing - https://github.com/libvips/libvips
|
|
#
|
|
# Amazon S3
|
|
# ==========
|
|
# ACTIVE_STORAGE_SERVICE=amazon <- Enables Amazon S3 storage
|
|
# S3_ACCESS_KEY_ID=
|
|
# S3_SECRET_ACCESS_KEY=
|
|
# S3_REGION= # defaults to `us-east-1` if not set
|
|
# S3_BUCKET=
|
|
#
|
|
# Cloudflare R2
|
|
# =============
|
|
# ACTIVE_STORAGE_SERVICE=cloudflare <- Enables Cloudflare R2 storage
|
|
# CLOUDFLARE_ACCOUNT_ID=
|
|
# CLOUDFLARE_ACCESS_KEY_ID=
|
|
# CLOUDFLARE_SECRET_ACCESS_KEY=
|
|
# CLOUDFLARE_BUCKET=
|
|
#
|
|
# Generic S3
|
|
# ==========
|
|
# ACTIVE_STORAGE_SERVICE=generic_s3 <- Enables Generic S3 storage
|
|
# GENERIC_S3_ACCESS_KEY_ID=
|
|
# GENERIC_S3_SECRET_ACCESS_KEY=
|
|
# GENERIC_S3_REGION=
|
|
# GENERIC_S3_BUCKET=
|
|
# GENERIC_S3_ENDPOINT=
|
|
# GENERIC_S3_FORCE_PATH_STYLE= <- defaults to false
|