-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy path.env.example
More file actions
269 lines (224 loc) · 12.6 KB
/
Copy path.env.example
File metadata and controls
269 lines (224 loc) · 12.6 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
# ══════════════════════════════════════════════════════════════════════════════
# SAFi Environment Configuration
#
# You do not have to edit this file by hand. Run:
#
# python3 scripts/setup.py
#
# It asks four questions, generates every secret below, and writes .env — this
# same file with the values filled in, comments and all. Use --defaults for a
# non-interactive install.
#
# To configure it yourself instead, copy this file to .env and set:
# 1. DB_PASSWORD and MYSQL_ROOT_PASSWORD to anything secure
# 2. At least one AI provider API key (GROQ is free to start)
# 3. SAFI_LOCAL_ADMIN_EMAIL and _PASSWORD for persistent login
# 4. Then run: docker compose up
# ══════════════════════════════════════════════════════════════════════════════
# ── Application ───────────────────────────────────────────────────────────────
# TWO switches use the word "production" and they are independent. Both matter:
#
# FLASK_ENV = STRICTNESS. 'production' refuses to start without
# FLASK_SECRET_KEY, DB_PASSWORD, Google OAuth creds and
# SAFI_ENCRYPTION_KEY. Anything else skips those checks
# — including the encryption one, so a dev instance can
# silently store prompts and ledgers in PLAINTEXT.
# SAFI_DEPLOYMENT_MODE = AUDIENCE. production | trial | showcase, controlling
# demo login and the showcase UI. Set further below.
#
# Typical pairs: laptop = development/trial · customer = production/production
# public demo = production/showcase
FLASK_ENV=development
# Generate with: python -c "import secrets; print(secrets.token_hex(32))"
FLASK_SECRET_KEY=change-me-to-a-secure-random-key
# ── Encryption at Rest ────────────────────────────────────────────────────────
# Master key for application-level encryption of OAuth tokens and user content
# (Fernet). REQUIRED in production. Generate with:
# python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
# Rotation: comma-separated list — FIRST key encrypts new writes, ALL keys
# decrypt. Prepend a new key, then re-run scripts/backfill_encryption.py.
# WARNING: back this key up outside the server. Losing it makes all encrypted
# data permanently unreadable.
SAFI_ENCRYPTION_KEY=
# The public URL where SAFi is reachable (used for OAuth callbacks).
# For local Docker: http://localhost:5000
WEB_BASE_URL=http://localhost:5000
# Comma-separated list of origins allowed to make API requests.
# For local Docker: http://localhost:5000
# If you're running the mobile/ Capacitor app against this instance, also
# include the spoofed local origin(s) from mobile/capacitor.config.ts
# (server.hostname) — e.g. https://selfalignmentframework.com — or native
# cross-origin fetches (guest login, etc.) will fail CORS silently.
# Setting this var at all replaces the built-in default list entirely
# (safi_app/config.py), so omitting the mobile origin here drops it even
# though the code fallback includes it.
ALLOWED_ORIGINS=http://localhost:5000
# Allow session cookies over HTTP (set to False for local http:// installs)
SESSION_COOKIE_SECURE=False
# Exposed port (optional — change if 5000 is already in use)
APP_PORT=5000
# ── Database ──────────────────────────────────────────────────────────────────
# In Docker Compose, DB_HOST is automatically set to 'db' by the compose file.
# Only set this manually for external/existing database servers.
DB_HOST=db
DB_USER=safi
DB_NAME=safi
# Choose a strong password — used by both the app and the MySQL container.
DB_PASSWORD=change-me-db-password
MYSQL_ROOT_PASSWORD=change-me-root-password
# ── AI Provider API Keys ──────────────────────────────────────────────────────
# At least one key is required. The others are optional.
#
# Free tiers available:
# Groq: https://console.groq.com (fast, generous free tier)
# Google: https://aistudio.google.com (Gemini free tier)
# DeepSeek: https://platform.deepseek.com (very cheap)
#
# Paid:
# OpenAI: https://platform.openai.com
# Anthropic: https://console.anthropic.com
# Mistral: https://console.mistral.ai
GROQ_API_KEY=
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
GEMINI_API_KEY=
MISTRAL_API_KEY=
DEEPSEEK_API_KEY=
CEREBRAS_API_KEY=
ZHIPU_API_KEY=
# ── Google OAuth (required for user login) ────────────────────────────────────
# Create credentials at: https://console.cloud.google.com/apis/credentials
# Authorized redirect URI must include: {WEB_BASE_URL}/api/callback/google
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
# Native (Capacitor) app Google Sign-In client id(s), comma-separated. The
# mobile app uses its own OAuth client, so its ID tokens carry a different
# audience than GOOGLE_CLIENT_ID; list those ids here so mobile login works.
GOOGLE_MOBILE_CLIENT_IDS=
# Optional: for Maps/Places features
GOOGLE_MAPS_API_KEY=
# ── Microsoft OAuth (optional) ────────────────────────────────────────────────
# Create an app at: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps
MICROSOFT_CLIENT_ID=
MICROSOFT_CLIENT_SECRET=
# ── GitHub OAuth (optional) ───────────────────────────────────────────────────
# Create an app at: https://github.com/settings/developers
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
# ── SAFi Runtime Settings (optional — defaults shown) ────────────────────────
# AI models for each faculty — LEAVE UNSET TO AUTO-DETECT. SAFi picks sensible
# defaults from the first provider key you configured above, so a fresh install
# needs no model configuration at all. Once you're familiar with the system,
# uncomment any of these to pin a specific model (the value must belong to a
# provider whose API key is set). Example values shown:
#SAFI_INTELLECT_MODEL=claude-haiku-4-5-20251001
#SAFI_CONSCIENCE_MODEL=openai/gpt-oss-120b
#SAFI_SUMMARIZER_MODEL=openai/gpt-oss-20b
#SAFI_BACKEND_MODEL=openai/gpt-oss-20b
# Default agent loaded on first login. The Fiduciary shows what SAFi is for in
# one interaction — a regulated-domain agent declining to give personalised
# financial advice — and needs no knowledge base.
# Org that turns from the public/embedded bot (/api/public/process_prompt) are
# attributed to. Leave unset and those turns record org_id = NULL, which matches
# nothing in SQL — the record exists but is invisible to every Audit Hub view and
# to both exports. Set it if you want the public bot auditable.
SAFI_PUBLIC_ORG_ID=
SAFI_PROFILE=fiduciary
# Which built-in demo agents to enable. The default three all run with zero
# extra setup:
# fiduciary (regulated-domain governance — no RAG)
# tutor (Socratic Tutor — no RAG)
# safi (SAFi Steward — explains the system; its small index auto-builds)
# Set to "all" for the full suite, or any comma-separated list of these keys:
# fiduciary, tutor, safi, health_navigator, bible_scholar, contoso_admin
# health_navigator also needs no RAG. Only bible_scholar and contoso_admin
# require an index to be built first — see rag/build_index_v2.py.
#SAFI_BUILTIN_AGENTS=fiduciary,tutor,safi
# Models for background work: the note-taker (per-agent work memory) and the
# public/embedded chatbot (isolated from users' model selections). Also
# auto-detected when unset; uncomment to override.
#SAFI_NOTETAKER_MODEL=gemini-3.5-flash-lite
#SAFI_PUBLIC_INTELLECT_MODEL=gemini-3.5-flash-lite
#SAFI_PUBLIC_CONSCIENCE_MODEL=openai/gpt-oss-120b
# Daily prompt limit per user (0 = unlimited)
SAFI_DAILY_PROMPT_LIMIT=0
# What this instance is. One declaration instead of several demo switches:
#
# production demo login off, showcase framing off. Use this for any real
# deployment. This is also the default if you set nothing.
# trial demo login on, showcase framing off. Evaluate locally without
# configuring OAuth. Shipped below because that is what the
# Quick Start needs — change it to production before anyone
# other than you uses the instance.
# showcase demo login on, showcase framing on (names the running model
# and explains that SAFi is the governance layer, not the
# intelligence). Only a public demo instance should be this:
# inside your own deployment the staff using the agent are not
# the audience, and disclaiming the intelligence just erodes
# trust in the tool.
#
# An unrecognised value falls back to production and logs a warning at startup.
SAFI_DEPLOYMENT_MODE=trial
# Individual overrides. Only needed to depart from the mode above; each one
# wins over the mode when set, which is also why an older .env that sets these
# directly keeps working unchanged.
# SAFI_ENABLE_DEMO=true
# SAFI_PUBLIC_DEMO_UI=true
# Default Intellect model for fresh demo accounts (guests can still switch).
# Leave blank to inherit the global default.
SAFI_DEMO_INTELLECT_MODEL=gemma-4-31b
# Persistent local admin account (no OAuth required).
# When both vars are set, a permanent admin account is auto-created/updated on startup.
# Ideal for self-hosted instances and local development.
# Leave blank to disable local login entirely.
SAFI_LOCAL_ADMIN_EMAIL=admin@localhost
SAFI_LOCAL_ADMIN_PASSWORD=change-me-local-password
# Max sequential tool-call turns per request before forcing a final answer (default: 5)
SAFI_MAX_AGENT_TURNS=5
# Plaintext JSONL debug logs on disk (default: false). The governance system
# of record is the encrypted governance_records table — leave this off unless
# you are debugging the pipeline locally.
SAFI_DEBUG_JSONL_LOGS=false
SAFI_LOG_DIR=logs
SAFI_LOG_TEMPLATE={profile}-%Y-%m-%d.jsonl
# Days to keep dated log files before the purge script deletes them
# (blank/0 = keep forever; deletion respects legal holds).
SAFI_LOG_RETENTION_DAYS=
# Text-to-speech. "edge-tts" is free and needs no key;
# "voxtral-mini-tts-2603" (Mistral) requires MISTRAL_API_KEY;
# "gpt-4o-mini-tts" requires OPENAI_API_KEY; "gemini-*" requires GEMINI_API_KEY.
SAFI_TTS_MODEL=edge-tts
SAFI_TTS_VOICE=en-US-AvaMultilingualNeural
# Mistral TTS preset voice slug (GET https://api.mistral.ai/v1/audio/voices
# lists them, e.g. en_paul_neutral, gb_jane_neutral, gb_oliver_neutral)
SAFI_MISTRAL_TTS_VOICE=en_paul_neutral
# Cached synthesized audio expires after this many days (0 = never cache)
SAFI_TTS_CACHE_TTL_DAYS=7
# HMAC secret for signing monitoring-alert webhooks (X-SAFi-Signature).
# Required only if an org configures an alert webhook URL.
SAFI_WEBHOOK_SECRET=
# Alignment threshold the enforcement gate applies (0.0–1.0) and MySQL pool size
SAFI_SPIRIT_THRESHOLD=0.5
SAFI_DB_POOL_SIZE=10
# Agent work-memory extraction tuning (defaults shown)
SAFI_AGENT_MEMORY_TEMPERATURE=0.0
SAFI_AGENT_MEMORY_MAX_ITEMS=80
# Spirit memory EMA smoothing factor (0.0–1.0, higher = longer memory)
SAFI_SPIRIT_BETA=0.9
# Maximum document upload size and character extraction limit
SAFI_MAX_UPLOAD_MB=10
SAFI_MAX_DOC_CHARS=50000
# External MCP servers config file path
MCP_SERVERS_JSON=./safi_app/core/mcp_servers/mcp_servers.json
# ── Channel bots (optional — teams_bot.py / telegram_bot.py) ─────────────────
# The bots authenticate to /api/bot/process_prompt with a POLICY API KEY
# minted in the SAFi policy UI (stored in the api_keys table).
SAFI_BOT_POLICY_API_KEY=
# Persona the bot speaks as (an agent key from your instance)
SAFI_BOT_PERSONA=
# Telegram only: the token @BotFather gives you
TELEGRAM_BOT_TOKEN=
# Teams only: Azure bot registration
# MicrosoftAppId= / MicrosoftAppPassword= / MicrosoftAppTenantId=
# Legacy shared secret (unused by current bots; kept for config validation)
SAFI_BOT_API_SECRET=change-me