| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| # Bee β Workspace .env (canonical secrets) |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
| # |
| |
| # between: |
| # |
| |
| # β’ Next.js portal (`apps/portal/*` β pricing, billing, QNSP UI) |
| # |
| |
| # βββββββββββββββ |
| # β’ 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). |
| # |
| |
| # 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) |
| # |
| |
| # βββββββββββ |
| # 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. |
| # |
| |
| # βββββββββββββββββββ |
| # 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. |
| # |
| |
| # ββββββββ |
| # β’ 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`. |
| # |
| |
| # ββββββββββββββββ |
| # 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 |
| # |
| |
| # 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_ |
| # |
| |
| # 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. |
| # |
| |
| # β’ 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. |
| # |
| |
| # 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 |
| # |
| |
| |
| # 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= |
|
|