File size: 17,877 Bytes
5e21013
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# ════════════════════════════════════════════════════════════════════════════
# 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=