-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path.env.example
More file actions
248 lines (219 loc) · 11.8 KB
/
Copy path.env.example
File metadata and controls
248 lines (219 loc) · 11.8 KB
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
# =============================================================================
# Convos backend env vars.
#
# Vars tagged `# REQUIRED` are hard-required to boot the server locally —
# `pnpm dev` throws on startup if unset (or set to an invalid value).
# Untagged vars are optional or have safe defaults.
# =============================================================================
# Node environment (optional)
# NODE_ENV=development
# API server port (default: 4000)
PORT=4000
# REQUIRED — Database connection string (Prisma reads at module load).
# For host `pnpm dev`: use localhost:5432. For Docker `./dev/run`: use convos_db:5432.
DATABASE_URL=postgres://postgres:convos@localhost:5432/postgres?sslmode=disable
# Firebase service account (optional — push fan-out is no-op if unset)
FIREBASE_SERVICE_ACCOUNT=
# REQUIRED — v2 JWT asymmetric ECDSA P-256 keys.
# Generate with: pnpm tsx dev/scripts/generateEcdsaKeys.ts
JWT_PRIVATE_KEY=
JWT_PUBLIC_KEY=
# REQUIRED — Notifications server URL (used by XMTP notification client).
NOTIFICATION_SERVER_URL=http://localhost:8080
# REQUIRED — Secret for XMTP notification server authentication.
XMTP_NOTIFICATION_SECRET=
# Website URL
WEBSITE_URL=https://popup.convos.org
# APNS - Apple Push Notifications Service
APNS_KEY=
APNS_KEY_ID=
APNS_TEAM_ID=
APNS_BUNDLE_ID=
# Assets CDN Base URL
CDN_BASE_URL=https://assets.domain.tld
# Private bucket for agent-build attachments (images / PDFs / voice). Distinct
# from PUBLIC_ASSETS_BUCKET: the backend reads these bytes itself for generation
# + moderation, so the content never gets a public CDN URL. Unset → the build-
# attachment upload + generation paths return 503. Needs s3:GetObject (the
# backend reads object bytes) and Rekognition DetectModerationLabels in the IAM
# role; set a short lifecycle-expiry rule on the bucket (attachments are only
# needed during the seconds-long generation).
PRIVATE_ASSETS_BUCKET=
# REQUIRED — Agent integration.
# ASSISTANT_API_URL: backs POST /api/v2/agents/join and /.well-known/agents.json proxy.
# Backend refuses to start without it. Must use https:// outside localhost / *.test.local.
# For local dev with no real assistants service: http://localhost:8787
# ASSISTANT_API_KEY — optional; set only if the deployed assistants
# service requires a bearer token in front of POST /api/assistants.
# AGENT_ASSETS_API_KEY — optional; for the agent asset upload surface.
ASSISTANT_API_URL=http://localhost:8787
ASSISTANT_API_KEY=
AGENT_ASSETS_API_KEY=
# Composio (optional — /v2/connections/* returns 503 if unset)
# Auth configs are looked up dynamically from Composio by toolkit slug.
COMPOSIO_API_KEY=
COMPOSIO_CONNECTION_CALLBACK_URL=convos://connections/callback
# Dedicated credential for POST /v2/composio/exec (the agent tool-execution
# proxy). Held only by the trusted assistants worker (sent as X-Composio-Exec-Key)
# and MUST match the worker's COMPOSIO_EXEC_API_KEY. Deliberately DISTINCT from
# AGENT_ASSETS_API_KEY so the worker's generic backend proxy can't authenticate
# an exec call. /v2/composio/exec returns 503 if unset.
COMPOSIO_EXEC_API_KEY=
# REQUIRED — Public Playroom origin for agent template URLs.
# Backend refuses to start without it. Env-specific: https://dev.convos.org / https://convos.org.
BUILDER_SITE_URL=https://dev.convos.org
# Builder/template generation (optional)
BUILDER_OPENROUTER_API_KEY=
BUILDER_MODEL=
BUILDER_EXA_SERVICE_KEY=
# Shared bearer for the assistants-dashboard revalidate webhook
# (POST BUILDER_SITE_URL/api/revalidate). Must match the dashboard's
# BUILDER_REVALIDATE_SECRET. Unset → no-op (dashboard's 60s Data Cache TTL
# is the fallback).
BUILDER_REVALIDATE_SECRET=
POSTHOG_PROJECT_TOKEN=
POSTHOG_HOST=
# Content moderation model override (default: google/gemini-3.1-flash-lite)
CONTENT_MODERATION_MODEL=
# PII redaction model override (default: anthropic/claude-sonnet-5). Persist-time
# scan that fails CLOSED, so recall is prioritized over cost.
PII_REDACTION_MODEL=
# Audio-capable model that transcribes voice attachments before generation
# (default: google/gemini-3.1-flash-lite). The builder model can't take audio.
BUILD_TRANSCRIBE_MODEL=
# Attachment caps (optional). Count per generation (default 9) + aggregate bytes
# (default 60 MB); per-file caps are class-specific and live in code.
BUILD_ATTACHMENTS_MAX_COUNT=
BUILD_ATTACHMENTS_MAX_TOTAL_BYTES=
# Min Rekognition label confidence (%) to block an image attachment (default 60,
# AWS's recommended default). Clamped to 1–100; lower = stricter moderation.
IMAGE_MODERATION_MIN_CONFIDENCE=
# Agent-prompt eval harness (tests/evals — dev only; not used by the server).
# Required to run `pnpm eval:models` / `pnpm eval:prompt`. Needs at least one OpenRouter key:
# EVAL_OPENROUTER_API_KEY alone powers both generation and the judge;
# BUILDER_OPENROUTER_API_KEY (above) also works; set both only to bill the
# judge on a separate key.
BRAINTRUST_API_KEY=
# EVAL_OPENROUTER_API_KEY=
# EVAL_MODELS=anthropic/claude-opus-4.7,google/gemini-3.5-flash
# EVAL_JUDGE_MODEL=openai/gpt-5.5
# EVAL_BASELINE_MODEL=anthropic/claude-opus-4.7
# EVAL_DATASET=tests/evals/datasets/core.jsonl
# EVAL_SAMPLES=1
# Generation pipeline knobs (all optional — sensible defaults applied)
# - GENERATION_TTL_HOURS: TTL after terminal status (default 24)
# - GENERATION_EXECUTOR_TIMEOUT_MS: per-pipeline in-process timeout (default 300000 = 5 min)
# - GENERATION_STUCK_SWEEP_THRESHOLD_MS: stuck-row sweep cutoff for crashed
# processes (default 600000 = 10 min; must be > EXECUTOR_TIMEOUT_MS so the
# in-process timer always wins under normal operation)
GENERATION_TTL_HOURS=
GENERATION_EXECUTOR_TIMEOUT_MS=
GENERATION_STUCK_SWEEP_THRESHOLD_MS=
# S3 Lifecycle Test Configuration
# Bucket for lifecycle testing (24h expiry policy)
LIFECYCLE_TEST_BUCKET=
# Secret token for authenticating lifecycle test endpoint calls
LIFECYCLE_TEST_TOKEN=
# REQUIRED — SIWE / nonce-cookie auth. Backend refuses to start without these.
# Domain pinned in SIWE messages; must match the deployed website host
# (i.e. the host portion of WEBSITE_URL above).
SIWE_DOMAIN=popup.convos.org
# REQUIRED — URI field expected in SIWE messages (must align with SIWE_DOMAIN / WEBSITE_URL).
SIWE_URI=https://popup.convos.org
# Comma-separated allowlist of EVM chain IDs accepted in SIWE messages.
# 1 = Ethereum mainnet. Extend as product needs (e.g. "1,8453" for mainnet + Base).
SIWE_ALLOWED_CHAIN_IDS=1
# REQUIRED — HMAC secret for signing nonce cookies. Must be >= 64 hex chars (32 bytes).
# Generate with: openssl rand -hex 32
# Treat as a secret; rotate via deploy if compromised (invalidates in-flight nonces, 5-min TTL absorbs).
NONCE_HMAC_SECRET=
# --- Payments / Credits ---
# REQUIRED — All five PAYMENTS_* knobs below are hard-required. Backend
# refuses to start without them (src/payments/credits/config.ts).
# REQUIRED — Markup applied on top of OpenRouter cost. 2.0 = 2× pass-through.
PAYMENTS_MARKUP_RATE=2.0
# REQUIRED — Credits per USD. 1000 means 1 credit = $0.001.
PAYMENTS_CREDITS_PER_USD=1000
# REQUIRED — Minimum balance before consume is rejected. Reserves headroom for
# the in-flight turn so a user can't end a turn with negative balance.
PAYMENTS_RESERVED_MAX_TURN_CREDITS=1
# REQUIRED — Floor below which consume throws InsufficientBalanceError. Negative
# allows mild overdraft within a turn; e.g. -1000 ≈ -$1.
PAYMENTS_MIN_BALANCE_CREDITS=-1000
# REQUIRED — Daily refill top-up-to-cap for free-tier accounts (credits).
# Used by POST /v2/credits/daily cron and the /v2/accounts/me/credits display.
PAYMENTS_FREE_TIER_DAILY_CAP_CREDITS=1000
# REQUIRED — Monthly credit allotment for the Plus subscription tier. Source of
# truth for `monthlyGrant` and the per-period `sub_grant` ledger write; annual
# subs grant 12× this once per renewal. Must be a positive integer. The value
# below is a sane local default — ops sets the real number per environment.
PAYMENTS_GRANT_PLUS_MONTHLY=2500
# OPTIONAL — Bearer key for POST /v2/credits/daily cron (X-Cron-Api-Key header).
# When unset, cron route returns 401. Server boots without it.
PAYMENTS_CRON_API_KEY=
# --- Credits Admin tool (/v2/credits-admin) ---
# Dedicated bearer token (>= 32 chars) gating every credits-admin API route.
# Held tighter than DEV_API_TOKEN and deliberately DISTINCT from it so the
# dev/invite token can never mint credits. When unset, every credits-admin API
# call returns 500 (fail closed) — strictly safer than an open tool.
CREDITS_ADMIN_API_TOKEN=
# Cloudflare Access identity verification for audit attribution (optional until
# the CF Access perimeter is deployed in front of the origin). Without these the
# audit actor degrades to a sentinel (token-admin@no-cf); the token above is
# still the authorization gate. CF_ACCESS_TEAM_DOMAIN e.g. your-team.cloudflareaccess.com;
# CF_ACCESS_AUD is the Access application AUD tag.
CF_ACCESS_TEAM_DOMAIN=
CF_ACCESS_AUD=
# Set to exactly "true" to hard-require a verified CF identity on every credits-
# admin mutation (flip on only AFTER the perimeter is live). Any other value =
# off. Default off.
CREDITS_ADMIN_REQUIRE_CF_IDENTITY=
# --- Apple In-App Purchases ---
# Routing for both JWS verification (incoming receipts) and the App Store
# Server API client. Values: "production" | "sandbox" | "local-testing".
# When unset, derived from IS_PRODUCTION. "local-testing" is required for
# tests using StoreKit Configuration files; backend rejects it in prod.
APPLE_ENV=sandbox
# Bundle ID expected in Apple's JWS payloads. Must EXACTLY match the bundle
# id the iOS app builds with — mismatched bundles fail JWS verification.
# Use the per-environment bundle: org.convos.ios (Prod),
# org.convos.ios-preview (Dev), org.convos.ios-local (Local).
APPLE_BUNDLE_ID=org.convos.ios-preview
# Apple's numeric App ID (optional). Used by the JWS verifier to anchor
# x5c chain validation against this app specifically. Find it in App Store
# Connect → your app → App Information → "Apple ID" (10-digit integer).
# Leave unset in dev/sandbox; recommended in production.
APPLE_APP_APPLE_ID=
# App Store Server API key — required for `/subscription/verify` to look up
# canonical subscription state from Apple. Generate one in App Store Connect
# → Users and Access → Integrations → App Store Server API → Generate API Key
# (access: at minimum "In-App Purchase"). Download the .p8 file once;
# Apple does not show it again.
#
# Key ID: the 10-char identifier shown in the keys table.
APPLE_API_KEY_ID=
# Issuer ID: the UUID shown at the top of the keys page (one per team).
APPLE_API_ISSUER_ID=
# The full contents of the downloaded .p8 file, including the
# -----BEGIN/END PRIVATE KEY----- lines. Newlines must survive shell
# parsing; wrap in single quotes or use a real multi-line .env loader.
APPLE_API_SIGNING_KEY=
# --- Google Play Billing ---
# Android package name from Play Console. Must EXACTLY match the package the
# Android app builds with. Used by the Play Developer API client to scope
# purchase lookups and acknowledgements.
GOOGLE_PLAY_PACKAGE_NAME=
# Service-account key JSON for the Play Developer API. Generate one in GCP
# IAM → Service Accounts, grant it "View financial data" + "Manage orders"
# in Play Console → Users and permissions, then paste the entire downloaded
# JSON keyfile here as a single-line string. Required for /subscription/verify
# to fetch the authoritative SubscriptionPurchaseV2 and to acknowledge
# pending purchases.
GOOGLE_PLAY_SERVICE_ACCOUNT_JSON=
# OIDC audience expected on Pub/Sub-push RTDN requests. Set to the public URL
# of POST /v2/webhooks/google-play/rtdn — the Pub/Sub topic subscription must
# be configured to sign tokens for this exact audience.
GOOGLE_PLAY_RTDN_PUBSUB_AUDIENCE=https://api.convos.app/v2/webhooks/google-play/rtdn
# Email of the service account configured on the Pub/Sub topic's push
# subscription. The RTDN handler rejects tokens signed by any other account.
GOOGLE_PLAY_RTDN_SERVICE_ACCOUNT_EMAIL=