bee / .env.example
Bee Deploy
HF Space backend deploy [de0cba5]
5e21013
# ════════════════════════════════════════════════════════════════════════════
# Bee β€” Workspace .env (canonical secrets)
# ════════════════════════════════════════════════════════════════════════════
#
# This file is the SINGLE SOURCE OF TRUTH for environment variables shared
# between:
#
# β€’ Python backend (`bee/*` β€” daemon, server, training, etc.)
# β€’ Next.js portal (`apps/portal/*` β€” pricing, billing, QNSP UI)
#
# How it's loaded
# ───────────────
# β€’ Python reads /Users/.../Bee/.env directly via dotenv.
# β€’ Portal reads /Users/.../Bee/.env via the symlink
# `apps/portal/.env -> ../../.env`.
# Next.js then layers `apps/portal/.env.local` on top
# for any portal-only overrides (e.g. SMTP, dev flags).
#
# Precedence (highest first, per Next.js convention):
# 1. process.env (Vercel / shell)
# 2. apps/portal/.env.{NODE_ENV}.local
# 3. apps/portal/.env.local ← portal overrides
# 4. apps/portal/.env.{NODE_ENV}
# 5. apps/portal/.env (symlink β†’ THIS file)
#
# Local setup
# ───────────
# 1. cp .env.example .env (this file β†’ live secrets)
# 2. Fill in every required value.
# 3. ln -sf ../../.env apps/portal/.env (one-time symlink)
# 4. cp apps/portal/.env.example apps/portal/.env.local (portal overrides)
# 5. Fill in SMTP_* and any portal-only overrides.
#
# Production (Vercel)
# ───────────────────
# Every key here belongs in Vercel β†’ Project β†’ Environment Variables, with
# identical names. The symlink + .env.local pattern is local-dev only;
# Vercel injects via process.env directly.
#
# Security
# ────────
# β€’ This file is in `.gitignore`. NEVER commit secrets.
# β€’ Every secret should have an "owner" comment indicating which team /
# vault provides it (QNSP Ops, Stripe Dashboard, Supabase Dashboard, etc.)
# β€’ Rotate any secret on suspected compromise. The QNSP partner secret
# and BEE_PARTNER_OUTBOUND_SIGNING_SECRET have a ROLLING-WINDOW caveat
# documented in `docs/integrations/qnsp-partner.md`.
#
# Adding a new key
# ────────────────
# 1. Add the placeholder line here in the right section.
# 2. Add the real value to the live `.env` (this same file but with values).
# 3. Mirror to Vercel β†’ Project β†’ Environment Variables.
# 4. If the portal needs a different value in dev, set it in
# `apps/portal/.env.local` (overrides this file).
# ════════════════════════════════════════════════════════════════════════════
# 1. Workspace identity (public URLs)
# ════════════════════════════════════════════════════════════════════════════
# Public site URL. Used by the portal for OG tags, password-reset links,
# email canonicalisation. NEXT_PUBLIC_ β†’ exposed to the browser.
# Production: https://bee.cuilabs.io
# Local dev: http://localhost:3000
NEXT_PUBLIC_SITE_URL=http://localhost:3000
# Bee Python backend URL. Server-side only β€” the portal proxies all client
# traffic through internal /api routes; the backend URL is never exposed.
# Production: https://cuilabs-bee.hf.space (HuggingFace Space, always-on)
# Local dev: http://localhost:8000 (when running `python -m bee`)
BEE_API_URL=https://cuilabs-bee.hf.space
# ════════════════════════════════════════════════════════════════════════════
# 2. Supabase / Postgres
# ════════════════════════════════════════════════════════════════════════════
# Source: Supabase Dashboard β†’ Project Settings β†’ API + Database
#
# IMPORTANT: the portal does NOT use the Supabase JS client for hot-path
# queries. It uses a pg-shim (`apps/portal/src/lib/db.ts`) with a
# Supabase-JS-compatible API surface, talking directly to the pg pooler.
# This bypasses the egress-quota restriction on PostgREST. Auth is also
# verified locally with SUPABASE_JWT_SECRET β€” never via GoTrue REST.
# Public-facing (browser-readable):
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... # anon role; safe in client
# Server-side keys (never exposed to the browser):
SUPABASE_SERVICE_ROLE_KEY=eyJ... # full DB access; pg-shim uses this
SUPABASE_JWT_SECRET= # HS256 secret for local cookie verify (lib/auth-jwt.ts)
SUPABASE_PUBLISHABLE_KEY= # alias / legacy
SUPABASE_SECRET_KEY= # alias / legacy
# Direct Postgres pooler connection (used by lib/db.ts):
POSTGRES_HOST=
POSTGRES_DATABASE=
POSTGRES_USER=
POSTGRES_PASSWORD=
POSTGRES_URL= # pooled (pgbouncer transaction mode)
POSTGRES_URL_NON_POOLING= # session pooler β€” used for migrations + lib/db.ts
POSTGRES_PRISMA_URL= # alias
# ════════════════════════════════════════════════════════════════════════════
# 3. Stripe (billing)
# ════════════════════════════════════════════════════════════════════════════
# Source: https://dashboard.stripe.com β†’ Developers β†’ API keys + Webhooks
# Test keys: sk_test_ / pk_test_ Live keys: sk_live_ / pk_live_
#
# Webhook setup:
# 1. Add endpoint: https://bee.cuilabs.io/api/webhooks/stripe
# 2. Subscribe to: customer.subscription.{created,updated,deleted},
# invoice.payment_succeeded, checkout.session.completed
# 3. Copy whsec_… into STRIPE_WEBHOOK_SECRET below.
STRIPE_SECRET_KEY= # sk_test_… or sk_live_…
STRIPE_WEBHOOK_SECRET= # whsec_… signs Stripe β†’ Bee deliveries
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY= # pk_test_… or pk_live_…
# ════════════════════════════════════════════════════════════════════════════
# 4. QNSP Partner Integration (Bee ↔ QNSP)
# ════════════════════════════════════════════════════════════════════════════
# Owner: QNSP Ops team (CUI Labs internal). Delivered out-of-band.
# Wire contract: docs/integrations/qnsp-partner.md
# Commercial model: Phase 1–3 β€” see same doc, "Commercial model" section.
#
# These credentials let the Bee portal:
# β€’ Mint Dilithium2-signed JWTs against QNSP's auth-service.
# β€’ POST /provision and /deprovision when a Bee plan with non-null
# qnsp_plan_name changes state (catalog.v2.ts).
# β€’ Verify HMAC signatures on inbound webhooks from QNSP.
# Outbound (Bee calls QNSP):
QNSP_PARTNER_BASE_URL=https://api.qnsp.cuilabs.io # edge gateway; never the cloud frontend
QNSP_PARTNER_CLIENT_ID=bee-partner # service-account name on QNSP side
QNSP_PARTNER_CLIENT_SECRET= # 64-char URL-safe random; mints JWTs
# Inbound (QNSP calls Bee, /api/webhooks/qnsp):
BEE_PARTNER_OUTBOUND_SIGNING_SECRET= # shared HMAC key; QNSP signs deliveries
# Customer-facing QNSP (legacy / portal-side KMS β€” independent of partner integration above):
QNSP_API_KEY= # required to activate cloud KMS
QNSP_TENANT_ID= # your QNSP tenant UUID
QNSP_KMS_KEY_ID= # KMS key UUID for key wrapping
# ════════════════════════════════════════════════════════════════════════════
# 5. Cron / scheduled jobs (Bee-side, self-managed)
# ════════════════════════════════════════════════════════════════════════════
# Bearer token the cron caller (Vercel Cron, GitHub Actions, etc.) presents
# at /api/cron/qnsp-reconcile. Constant-time-compared on the route. Rotate
# freely β€” independent of QNSP-team-managed secrets above.
# Generate: openssl rand -base64 48
CRON_SECRET=
# ════════════════════════════════════════════════════════════════════════════
# 6. Bee runtime (Python backend β€” `python -m bee`)
# ════════════════════════════════════════════════════════════════════════════
BEE_HOST=0.0.0.0
BEE_PORT=8000
BEE_DEVICE=auto # auto detects MPS on Apple Silicon
BEE_CORS_ORIGINS=https://bee.cuilabs.io,http://localhost:3000
# Ignition: ON by default in daemon mode. For legacy `python -m bee.server`,
# set BEE_IGNITE=1 explicitly.
BEE_IGNITE=1
BEE_IGNITE_PRESET=360m # 360m (any) | 1.7b (8GB+) | 7b (16GB+)
# BEE_BASE_MODEL=Qwen/Qwen2.5-3B-Instruct # recommended for M4 Max / 16GB+ RAM
# Model + adapters
BEE_MODEL_PATH=HuggingFaceTB/SmolLM2-360M-Instruct
BEE_LORA_DIR=./lora_checkpoints
# Persistence
BEE_DATASETS_DIR=./datasets
BEE_INTERACTIONS_DIR=./datasets
BEE_RAG_DIR=./rag_index
BEE_EVOLUTION_DIR=./evolution_state
# API auth (Bee's own Python API; separate from Stripe/QNSP)
BEE_API_KEYS=
# ════════════════════════════════════════════════════════════════════════════
# 7. Bee external API keys (LLM teachers β€” distillation + evolution)
# ════════════════════════════════════════════════════════════════════════════
# Setting at least one of these unlocks autonomous training-data generation.
# Without them the daemon falls back to local-only evolution (slower).
BEE_TEACHER_API_URL=https://api.anthropic.com/v1
BEE_TEACHER_API_KEY=
BEE_TEACHER_MODEL=claude-sonnet-4-20250514
BEE_OPENAI_API_KEY=
BEE_GOOGLE_API_KEY=
BEE_DEEPSEEK_API_KEY=
# ════════════════════════════════════════════════════════════════════════════
# 8. ML platforms / quantum
# ════════════════════════════════════════════════════════════════════════════
# HuggingFace Hub (model + dataset uploads)
HF_TOKEN=
# IBM Quantum (real 156-qubit Heron r2 access; ~10 min/month free)
# Without this, Bee uses local quantum simulator only.
IBM_QUANTUM_API_KEY=
# Kaggle (datasets only)
KAGGLE_USERNAME=
KAGGLE_KEY=
KAGGLE_API_TOKEN=
# ════════════════════════════════════════════════════════════════════════════
# 9. Email confirmation + transactional email (Bee-side, self-managed)
# ════════════════════════════════════════════════════════════════════════════
# Used by /api/auth/signup β†’ confirmation email β†’ /auth/confirm flow.
# Sends through the Bee SMTP (SMTP_* below) so the From: address is
# bee-noreply@cuilabs.io rather than Supabase's free-tier sender.
# HMAC secret for email-confirmation tokens. Independent of
# SUPABASE_JWT_SECRET so we can rotate without invalidating sessions.
# Generate: openssl rand -base64 4# Generate: openssl rand -base64 4# Generate: opens 1 / true β†’ require email confirmation on every new signup (default in prod).
# 0 / unset β†’ auto-confirm immediately (legacy / local-dev only).
AUTH_REQUIRE_EMAIL_CONFIRMATION=1
# Default token TTL in seconds (clamped 60s … 7 days). Default 86400 (24 h).
# EMAIL_CONFIRM_TTL_SECONDS=86400
# ── Outbound SMTP (transactional + auth emails) ────────────────────────────
# Namecheap Private Email is the canonical setup; any RFC-5321 SMTP host
# works. SMTP_FROM_ADDRESS must match the SMTP_USER's domain (server
# rewriting is permitted within the authenticated domain).
SMTP_HOST=premium41.web-hosting.com
SMTP_PORT=465
SMTP_SECURE=true # true for port 465 (implicit TLS); false for 587 (STARTTLS)
SMTP_USER=bee-noreply@cuilabs.io
SMTP_PASSWORD=
SMTP_FROM_NAME=Bee
SMTP_FROM_ADDRESS=bee-noreply@cuilabs.io
# ════════════════════════════════════════════════════════════════════════════
# 10. OAuth providers (Google / GitHub / Microsoft)
# ════════════════════════════════════════════════════════════════════════════
# Implemented natively (no Supabase GoTrue dependency). Each provider is
# enabled when its CLIENT_ID + CLIENT_SECRET are both set; otherwise the
# corresponding "Continue with X" button is hidden client-side.
#
# Redirect URIs to register at each provider's developer console:
# Google: {NEXT_PUBLIC_SITE_URL}/auth/oauth/google/callback
# GitHub: {NEXT_PUBLIC_SITE_URL}/auth/oauth/github/callback
# Microsoft: {NEXT_PUBLIC_SITE_URL}/auth/oauth/microsoft/callback
#
# Walkthrough: docs/operations/infrastructure.md β†’ "OAuth providers".
# Google β€” https://console.cloud.google.com/apis/credentials β†’ Create OAuth
# 2.0 Client ID β†’ Web application β†’ add the redirect URI above.
GOOGLE_OAUTH_CLIENT_ID=
GOOGLE_OAUTH_CLIENT_SECRET=
# GitHub β€” https://github.com/settings/developers β†’ New OAuth App.
GITHUB_OAUTH_CLIENT_ID=
GITHUB_OAUTH_CLIENT_SECRET=
# Microsoft β€” https://portal.azure.com β†’ Microsoft Entra ID β†’ App
# registrations β†’ New registration. Supported account types:
# "Accounts in any organizational directory and personal Microsoft accounts"
# for the most permissive setup. Add the redirect URI under Authentication
# β†’ Platform configurations β†’ Web.
MICROSOFT_OAUTH_CLIENT_ID=
MICROSOFT_OAUTH_CLIENT_SECRET=
# Tenant ID. "common" = work/school + personal accounts; "consumers" =
# personal only; "organizations" = work/school only; or a specific GUID
# for single-tenant apps. Default: "common".
MICROSOFT_OAUTH_TENANT=common
# ── Sentry β€” error tracking (free tier, errors-only, no perf/replays) ──
# Org: cuilabs (us.sentry.io). Auth tokens are server/build-time only;
# DSNs are public and safe to ship to clients. Errors-only by config β€”
# tracesSampleRate=0, no replays, no profiling. Stays inside the 5K/mo
# free-tier event budget for the friends-and-family beta.
SENTRY_ORG=cuilabs
SENTRY_AUTH_TOKEN=sntrys_<replace>
SENTRY_USER_PAT=sntryu_<replace>
SENTRY_DSN_MOBILE=https://<replace>@us.sentry.io/<bee-mobile-id>
SENTRY_DSN_WEB=https://<replace>@us.sentry.io/<bee-web-id>
SENTRY_DSN_BACKEND=https://<replace>@us.sentry.io/<bee-backend-id>
NEXT_PUBLIC_SENTRY_DSN=https://<replace>@us.sentry.io/<bee-web-id>
# ── Mobile APK distribution (Stage 1 friends/family/PH/LinkedIn) ──────
# APK_UPLOAD_SECRET β€” Bearer token operator passes when uploading the
# Bee Android release APK to /api/admin/upload-apk. Generate fresh
# (e.g. `openssl rand -hex 32`) and mirror to Vercel Production envs.
APK_UPLOAD_SECRET=
# BLOB_READ_WRITE_TOKEN β€” Vercel Blob token. Auto-injected by Vercel for
# deployed routes; needed locally for `vercel blob put` CLI in
# scripts/upload_apk.sh and apps/mobile/scripts/release-android.sh.
BLOB_READ_WRITE_TOKEN=