Repository navigation
Expand file tree
/
Copy pathenv.template
More file actions
354 lines (313 loc) · 18.2 KB
/
Copy pathenv.template
File metadata and controls
354 lines (313 loc) · 18.2 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
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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# ============================================================================
# BrainKB Unified Deployment - Environment Variables Template
# ============================================================================
# Copy this file to .env and update with your actual values
# cp env.template .env
# ============================================================================
# ----------------------------------------------------------------------------
# PostgreSQL Database Configuration
# ----------------------------------------------------------------------------
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your_secure_password_change_this
POSTGRES_DB=brainkb
POSTGRES_PORT=5432
# ----------------------------------------------------------------------------
# Database Configuration (for APItokenmanager Django service)
# ----------------------------------------------------------------------------
DB_NAME=brainkb
# make sure it matches with postgres db username and password
DB_USER=postgres
DB_PASSWORD=your_secure_password_change_this
# do not change unless you update the docker
DB_HOST=postgres
DB_PORT=5432
# ----------------------------------------------------------------------------
# Django Configuration (APItokenmanager)
# ----------------------------------------------------------------------------
DJANGO_SUPERUSER_USERNAME=admin
DJANGO_SUPERUSER_EMAIL=admin@brainkb.org
DJANGO_SUPERUSER_PASSWORD=your_secure_password_change_this
BRAINYPEDIA_APITOKEN_MANAGER_SECRET_KEY=your-django-secret-key-change-this-in-production
# ----------------------------------------------------------------------------
# JWT Configuration (for query_service and ml_service)
# ----------------------------------------------------------------------------
# do not change
JWT_POSTGRES_DATABASE_HOST_URL=postgres
JWT_POSTGRES_DATABASE_PORT=5432
# make sure it matches with postgres db username and password
JWT_POSTGRES_DATABASE_USER=postgres
JWT_POSTGRES_DATABASE_PASSWORD=your_secure_password_change_this
# ----------------------------------------------------------------------------
# Do not change the following
# ----------------------------------------------------------------------------
JWT_POSTGRES_DATABASE_NAME=brainkb
JWT_POSTGRES_TABLE_USER=Web_jwtuser
JWT_POSTGRES_TABLE_SCOPE=Web_scope
JWT_POSTGRES_TABLE_USER_SCOPE_REL=Web_jwtuser_scopes
JWT_ALGORITHM=HS256
# ----------------------------------------------------------------------------
# Service-Specific JWT Secret Keys (for security isolation)
# ----------------------------------------------------------------------------
# Each service has its own JWT secret key to prevent tokens from one service
# from being used to authenticate with another service
QUERY_SERVICE_JWT_SECRET_KEY=your-query-service-jwt-secret-key-change-this-in-production
ML_SERVICE_JWT_SECRET_KEY=your-ml-service-jwt-secret-key-change-this-in-production
# ----------------------------------------------------------------------------
# User Management Service - JWT
# ----------------------------------------------------------------------------
USERMANAGEMENT_SERVICE_JWT_SECRET_KEY=your-usermanagement-service-jwt-secret-key-change-this-in-production
# ----------------------------------------------------------------------------
# User Management Service - OAuth (unified flow for GitHub, ORCID, Globus)
# ----------------------------------------------------------------------------
# Backend public base URL (used to build OAuth redirect_uri)
# e.g. http://localhost:8004 for local, https://api.brainkb.org for prod
USERMANAGEMENT_PUBLIC_BASE_URL=http://localhost:8004
# Frontend URL we redirect back to after OAuth callback (append ?token=...)
# e.g. http://localhost:3000/auth/callback
USERMANAGEMENT_FRONTEND_CALLBACK_URL=http://localhost:3000/auth/callback
# URLs a CLI/MCP sign-in may return to with ?code= instead of showing the code
# (the MCP server's OAuth callback, used by connector apps such as Perplexity or
# claude.ai). Exact matches, comma-separated. Empty = main + sandbox MCP.
# USERMANAGEMENT_CLI_RETURN_URLS=https://mcp.brainkb.org/oauth/callback,https://mcp.sandbox.brainkb.org/oauth/callback
# Extra browser origins allowed to call the APIs, comma-separated. ADDED to each
# service's built-in list (brainkb.org, www/beta/sandbox, localhost:3000), so leave
# it unset unless you serve the UI from another domain. Read by all four services —
# ml_service, query_service, usermanagement_service, chat_service.
#
# Must be a scheme + host (+ port if non-default), exactly as the browser sends the
# Origin header: "https://ui.example.org", not "ui.example.org" and no trailing
# slash. A schemeless entry silently never matches.
#
# Note: a fetch failing with "No Access-Control-Allow-Origin" is not always a CORS
# problem — the load balancer's own 502 page carries no CORS headers, so a service
# that is down looks identical to one that is misconfigured. Check the service
# responds at all before editing this.
# CORS_ALLOWED_ORIGINS=https://ui.example.org,https://another.example.org
# Fernet key for encrypting OAuth access/refresh tokens at rest.
# Generate once: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
USERMANAGEMENT_OAUTH_TOKEN_ENC_KEY=Z85D3iJe4XCfJ5f8DExKXW3DfznyE4HzJ7XmmaOYtUQ=
# Comma-separated emails bootstrapped as SuperAdmin on first startup — supports
# MULTIPLE (each email in the list is seeded as SuperAdmin+Admin, and every one is
# honored by require_admin even before its profile exists). Each must be a
# Globus-verifiable account: it goes live when that person logs in via Globus.
# SuperAdmins also receive the regular Admin role for permissions, but the
# SuperAdmin marker protects them from being banned, deleted, or having that
# role stripped via the admin UI/API. Regular Admins (assigned through the
# admin UI) remain fully manageable.
# You can also add more SuperAdmins at runtime: an existing SuperAdmin assigns the
# SuperAdmin role to another user (SuperAdmin-only action).
# Example (multiple, comma-separated — no spaces needed):
# USERMANAGEMENT_BOOTSTRAP_SUPERADMIN_EMAILS=admin@example.org,lead@example.org,pi@lab.example.edu
USERMANAGEMENT_BOOTSTRAP_SUPERADMIN_EMAILS=admin@example.org,second-admin@example.org
# ----------------------------------------------------------------------------
# Single-issuer SSO (auth Phase 2 — RS256 + JWKS). See query_service/AUTH_UNIFICATION.md
# ----------------------------------------------------------------------------
# usermanagement is the sole token issuer. A login (/api/auth/login) mints a
# short-lived refresh token; clients exchange it (/api/auth/exchange) for narrow
# per-service access tokens (aud=<service>). Services verify via the published
# JWKS (/.well-known/jwks.json) and require their own audience, so a token minted
# for one service cannot be replayed against another. Legacy HS256 tokens above
# still work during migration.
#
# RS256 private key: AUTO-GENERATED — do NOT set it here. The unified container's
# start.sh creates a persistent key at /app/secrets/um_jwt_private.pem (mounted
# from ./secrets) on first boot, so the JWKS `kid` is stable across the 4 gunicorn
# workers and redeploys. Because it is auto-generated, it is intentionally NOT a
# variable in this template or in .env.
# To OVERRIDE with your own key (optional), add one of these lines yourself:
# USERMANAGEMENT_JWT_PRIVATE_KEY_PEM=<PEM inline, \n-escaped>
# USERMANAGEMENT_JWT_PRIVATE_KEY_FILE=<path to a mounted PEM file>
# Generate one with: openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out sso_key.pem
# Token issuer (`iss`). query_service's QUERY_SERVICE_SSO_ISSUER must match this.
USERMANAGEMENT_JWT_ISSUER=brainkb-usermanagement
# Token lifetimes (minutes). These control how long a login lasts before the user
# must re-authenticate — logins are NOT forever.
# - ACCESS: short-lived per-service token (exchanged on demand). Keep small.
# - REFRESH: the session lifetime from one login. When it expires, the user is
# asked to log in again. 720 = 12h; lower it (e.g. 240 = 4h, 60 = 1h) to force
# more frequent re-login, raise it for longer sessions.
# The MCP/skill caps its cached session to the refresh token's expiry (and to its
# own MCP_SESSION_TTL_MIN) — see brainkb_mcp/.env.example.
USERMANAGEMENT_ACCESS_TOKEN_TTL_MIN=15
USERMANAGEMENT_REFRESH_TOKEN_TTL_MIN=720
# TTL (minutes) of the web-session ACCESS JWT the UI receives at OAuth login
# (?token=). The UI silently refreshes it using the web refresh token below, so
# this can stay short-ish. 720 = 12h.
USERMANAGEMENT_WEB_SESSION_TTL_MIN=720
# TTL (minutes) of the web REFRESH token (?refresh=) the UI stores to renew its
# access token without re-login (exchanged at /api/auth/exchange). Governs the
# overall web session length before the user must sign in again. 10080 = 7 days.
USERMANAGEMENT_WEB_REFRESH_TTL_MIN=10080
# Services a refresh token may be exchanged for (valid `aud` values).
USERMANAGEMENT_TOKEN_AUDIENCES=usermanagement,query_service,ml_service,chat_service
# OAuth CLI/skill paste-code length (raw chars, before dash grouping). The code
# is short-lived (~10 min) + single-use, but kept high-entropy: 20 chars over a
# 30-symbol alphabet ≈ 98 bits. Clamped to 24 to fit the storage column.
USERMANAGEMENT_CLI_CODE_LEN=20
# Personal Access Tokens (PATs) — browser-free CLI/MCP auth. A user mints a PAT
# once (while logged in), sets it as BRAINKB_TOKEN in their MCP/skill config, and
# authenticates with it thereafter (no login/browser) until it expires or is
# revoked. PATs are opaque + hashed at rest + revocable instantly; on use they
# are exchanged for the same short-lived per-service token the login flow issues.
# DEFAULT_DAYS also acts as the SLIDING/idle window (see PAT_SLIDING): an
# actively-used token keeps rolling forward and never re-prompts; leave it unused
# this many days and it expires.
USERMANAGEMENT_PAT_DEFAULT_DAYS=3 # default lifetime + idle window when `days` omitted
USERMANAGEMENT_PAT_MAX_DAYS=365 # absolute ceiling — a PAT can't roll past created_at + this
USERMANAGEMENT_PAT_MAX_PER_USER=20 # max active PATs one user may hold
# Sliding expiry: each use pushes expiry to now + DEFAULT_DAYS (capped at
# created_at + MAX_DAYS). true = "stay logged in while you keep using it, expire
# when idle"; false = fixed lifetime from creation.
USERMANAGEMENT_PAT_SLIDING=true
# query_service verifies RS256 access tokens against the issuer's JWKS.
# In the unified container usermanagement is on localhost:8004; in a split
# deployment point this at the usermanagement service URL.
QUERY_SERVICE_SSO_JWKS_URL=http://127.0.0.1:8004/.well-known/jwks.json
# Must match USERMANAGEMENT_JWT_ISSUER above.
QUERY_SERVICE_SSO_ISSUER=brainkb-usermanagement
# This service's audience — tokens must carry aud == this value.
QUERY_SERVICE_SSO_AUDIENCE=query_service
# GitHub OAuth App
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
# ORCID OAuth
ORCID_CLIENT_ID=
ORCID_CLIENT_SECRET=
# Use https://sandbox.orcid.org for dev, https://orcid.org for prod
ORCID_BASE_URL=https://orcid.org
# Globus OAuth (register at https://developers.globus.org).
# IMPORTANT: use an app that supports REDIRECTS (not a Service Account), and add
# the redirect URL ${USERMANAGEMENT_PUBLIC_BASE_URL}/api/auth/globus/callback
# local: http://localhost:8004/api/auth/globus/callback
# deploy: https://<usermanagement-public-host>/api/auth/globus/callback
# Same callback serves web + skill (paste-code) login. See usermanagement_service/README.md
# ("OAuth provider setup"). GitHub/ORCID use the same /api/auth/<provider>/callback pattern.
GLOBUS_CLIENT_ID=
GLOBUS_CLIENT_SECRET=
# ----------------------------------------------------------------------------
# Are not used, kept it for future
# ----------------------------------------------------------------------------
# CHAT_SERVICE_JWT_SECRET_KEY=your-chat-service-jwt-secret-key-change-this-in-production
# INGESTION_SERVICE_JWT_SECRET_KEY=your-ingestion-service-jwt-secret-key-change-this-in-production
# ----------------------------------------------------------------------------
# Service Ports - do not change unless you update docker/compose
# ----------------------------------------------------------------------------
NGINX_PORT=80
API_TOKEN_PORT=8000
QUERY_SERVICE_PORT=8010
ML_SERVICE_PORT=8007
USERMANAGEMENT_SERVICE_PORT=8004
OXIGRAPH_PORT=7878
UI_PORT=3000
PGADMIN_PORT=5051
# ----------------------------------------------------------------------------
# Oxigraph SPARQL Database Configuration
# ----------------------------------------------------------------------------
OXIGRAPH_USER=admin
OXIGRAPH_PASSWORD=your_oxigraph_password_change_this
OXIGRAPH_DATA_PATH=/
OXIGRAPH_TMP_PATH=/
# Oxigraph Data Storage Configuration
# For local development: Leave commented to use Docker named volumes (recommended)
# For production with shared storage: Set to absolute path (e.g., /fsx/brainkb-kg-repo)
# OXIGRAPH_DATA_PATH=/path/to/your/data
# OXIGRAPH_TMP_PATH=/path/to/your/tmp
# ----------------------------------------------------------------------------
# Query Service Configuration
# ----------------------------------------------------------------------------
ENV_STATE=production
# LOGTAIL_API_KEY optional
LOGTAIL_API_KEY=
# this is your oxigraph username and password
GRAPHDATABASE_USERNAME=admin
GRAPHDATABASE_PASSWORD=your_oxigraph_password_change_this
# ----------------------------------------------------------------------------
# Do not change the following, unless you use different graphdb/update docker
# ----------------------------------------------------------------------------
GRAPHDATABASE_HOSTNAME=oxigraph
GRAPHDATABASE_PORT=7878
GRAPHDATABASE_TYPE=OXIGRAPH
GRAPHDATABASE_REPOSITORY=
RAPID_RELEASE_FILE=data-release.yaml
DEFAULT_NAMED_GRAPH=named_graph
WEB_CONCURRENCY=6
# ----------------------------------------------------------------------------
# pgAdmin Configuration (Optional - for PostgreSQL management)
# ----------------------------------------------------------------------------
PGADMIN_DEFAULT_EMAIL=admin@brainkb.org
PGADMIN_DEFAULT_PASSWORD=your_secure_password_change_this
PGADMIN_SERVER_NAME=BrainKB PostgreSQL
# ----------------------------------------------------------------------------
# ML Service - Query Service Integration
# ----------------------------------------------------------------------------
QUERY_SERVICE_BASE_URL=localhost:8010
# ----------------------------------------------------------------------------
# ML Service - MongoDB Configuration we use mongodb atlas
# ----------------------------------------------------------------------------
MONGO_DB_URL=
NER_DATABASE=ner_database
NER_COLLECTION=ner_collection
# ----------------------------------------------------------------------------
# ML Service - StructSense/KG Source Configuration
# ----------------------------------------------------------------------------
ENABLE_KG_SOURCE=False
ONTOLOGY_DATABASE=ontology_database_agent_test1
WEAVIATE_GRPC_HOST=
WEAVIATE_HTTP_HOST=
WEAVIATE_API_KEY=
# ----------------------------------------------------------------------------
# ML Service - PDF Extraction Configuration
# ----------------------------------------------------------------------------
EXTERNAL_PDF_EXTRACTION_SERVICE=True
GROBID_SERVER_URL_OR_EXTERNAL_SERVICE=yoururl_grobid/fylo api
# ----------------------------------------------------------------------------
# ML Service - Ollama Configuration
# ----------------------------------------------------------------------------
# Use http://host.docker.internal:11434 when running ollama via docker
# Use http://localhost:11434 when running ollama on host
OLLAMA_API_ENDPOINT=http://host.docker.internal:11434
OLLAMA_MODEL=nomic-embed-text
OLLAMA_PORT=11434
# ----------------------------------------------------------------------------
# ML Service - SynthScholar (PRISMA literature review)
# ----------------------------------------------------------------------------
# Mounts under /api/synth-scholar/* in ml_service. End-to-end PRISMA-guided
# pipeline (search strategy → article fetch → title/abstract + full-text
# screening → data charting → critical appraisal → narrative synthesis →
# GRADE), driven by the `synthscholar` Python library and orchestrated by
# the local module at ml_service/core/synth_scholar/. SSE progress, plan-
# confirmation gating, exports (markdown / JSON / BibTeX / Turtle / JSON-LD),
# per-user ownership, and shared/cached corpus search are all wired up.
#
# Database: SynthScholar reuses the unified `brainkb` Postgres database
# (the same one JWT auth and usermanagement_service write to). Its tables
# (`reviews`, plus synthscholar's bundled `article_store` / `review_cache` /
# `pipeline_checkpoints`) coexist with the existing `Web_*` tables — names
# are snake_case here vs PascalCase there, so there are no collisions. No
# separate DSN is needed; the JWT_POSTGRES_DATABASE_* values above are
# reused at startup. Optional: install pgvector in the postgres image to
# enable semantic article/review search; without it, only keyword/title
# search works (synthscholar's bundled migration 004 logs and skips).
#
# Auth: every endpoint sits behind ml_service's existing JWT (clients call
# /api/token with NEXT_PUBLIC_JWT_USER / _PASSWORD on the UI side). The
# UI also forwards a per-user OpenRouter key on every create-review call
# (resolved from the user's personal sessionStorage key, or the admin-
# shared key set in /admin/settings/openrouter-key). The OPENROUTER_API_KEY
# below is only the operator fallback used when neither is configured.
# OpenRouter API key — operator fallback only. The UI normally forwards a
# per-user or admin-shared key on every request, so this env value is used
# only when neither is configured. Safe to leave blank in production.
OPENROUTER_API_KEY=
# Optional. NCBI E-utilities API key — recommended in production to raise
# PubMed rate limits from 3 to 10 requests/second.
# https://www.ncbi.nlm.nih.gov/account/settings/
NCBI_API_KEY=
# Optional. Semantic Scholar API key — adds Semantic Scholar to the search
# fan-out. Silently skipped at runtime if absent.
SEMANTIC_SCHOLAR_API_KEY=
# Optional. CORE API key — adds the CORE provider. Silently skipped if absent.
CORE_API_KEY=
# Optional. Contact email passed to OpenAlex / Crossref / Europe PMC for
# polite-pool rate limits. Silently skipped if absent.
SYNTHSCHOLAR_EMAIL=