-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.env.example
More file actions
450 lines (327 loc) · 24.7 KB
/
.env.example
File metadata and controls
450 lines (327 loc) · 24.7 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
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
# CVErt Ops — Environment Variables
# Copy this file to .env and fill in your values.
# .env is gitignored and never committed.
#
# Notation:
# (required) — server refuses to start without this
# (default) — shown value is the built-in default; set only to override
# (optional) — feature is disabled if unset
# ─────────────────────────────────────────────────────────────────────────────
# Docker Compose — dev stack only (docker/compose.yml variable substitution)
# ─────────────────────────────────────────────────────────────────────────────
# (required for compose) Postgres superuser password
POSTGRES_PASSWORD=change_me_dev_only
# (default) Postgres database name and user
POSTGRES_DB=cvert_ops
POSTGRES_USER=cvert_ops
# (default) Host port mappings
POSTGRES_PORT=5432
APP_PORT=8080
MAILPIT_SMTP_PORT=1025
MAILPIT_UI_PORT=8025
# (default) Caddy reverse proxy host — controls TLS behaviour (docker --profile app only).
# localhost → HTTP only on :80. No TLS, no ACME. Correct for local dev.
# A real domain (e.g. cvert.example.com) → Caddy auto-provisions TLS via Let's Encrypt.
# When using a real domain also set: EXTERNAL_URL=https://... and COOKIE_SECURE=true
CADDY_HOST=localhost
CADDY_HTTP_PORT=80
CADDY_HTTPS_PORT=443
# ─────────────────────────────────────────────────────────────────────────────
# MCP servers (Claude Code development tooling — not used by the app)
# ─────────────────────────────────────────────────────────────────────────────
# (optional) GitHub Personal Access Token for the GitHub MCP server.
# Enables Claude Code to read/create issues and PRs in the repo.
# Create at: https://github.com/settings/tokens (classic or fine-grained)
# Scopes needed: repo (for private repos) or public_repo (for public repos)
# GITHUB_PERSONAL_ACCESS_TOKEN=
# ─────────────────────────────────────────────────────────────────────────────
# Database
# ─────────────────────────────────────────────────────────────────────────────
# (required) PostgreSQL connection string.
# In Docker Compose the app service builds this from the POSTGRES_* vars above;
# set this directly when running the app outside of compose.
DATABASE_URL=postgresql://cvert_ops:change_me_dev_only@localhost:5432/cvert_ops?sslmode=disable
# (optional) Connection string used by `cvert-ops migrate` (superuser/DDL role).
# Falls back to DATABASE_URL if unset. Set this if your app DB role lacks DDL privs.
# For local dev with split roles:
# DATABASE_URL=postgres://cvert_ops_app:changeme@localhost:5432/cvert_ops?sslmode=disable
# DATABASE_URL_MIGRATE=postgres://postgres:postgres@localhost:5432/cvert_ops?sslmode=disable
# DATABASE_URL_MIGRATE=
# (default) Maximum number of open DB connections in the pool.
# Scaling formula: DB_MAX_CONNS × number_of_app_instances < postgres_max_connections − 10
DB_MAX_CONNS=25
# (default) Close connections idle for longer than this duration (prevents NAT gateway drops).
# Format: Go duration string, e.g. 5m, 30s
DB_MAX_CONN_IDLE_TIME=5m
# (default) Per-query statement timeout in milliseconds. Workers that need
# longer (bulk import, retention cleanup) override this with SET LOCAL.
DB_STATEMENT_TIMEOUT_MS=14000
# (default) Extended statement timeout for bulk operations (e.g. bulk import, retention cleanup).
# Used by workers via SET LOCAL; does not affect normal API queries.
DB_LONG_STATEMENT_TIMEOUT_MS=120000
# (default) Use simple_protocol for PgBouncer transaction-pooling compatibility.
# Safe for direct Postgres connections too. Options: simple_protocol | extended_protocol
DB_QUERY_EXEC_MODE=simple_protocol
# ─────────────────────────────────────────────────────────────────────────────
# Server
# ─────────────────────────────────────────────────────────────────────────────
# (default) Address the HTTP server binds to
LISTEN_ADDR=:8080
# (default) Prometheus metrics port (separate from API server)
METRICS_PORT=9090
# (default) Environment name; affects log format and other dev-vs-prod defaults
# Options: development | production
APP_ENV=development
# (required for OAuth) Publicly-accessible base URL of this instance.
# Used to construct OAuth redirect URIs — never derived from the Host header.
# Example: https://cvert.example.com
EXTERNAL_URL=http://localhost:8080
# (default) Where the browser frontend runs.
# "/" = same-origin (production, Go serves the SPA).
# "http://localhost:5173" = Vite dev server (development).
# Used for post-OAuth redirect and CORS origin.
FRONTEND_URL=/
# (default) Graceful shutdown deadline in seconds
SHUTDOWN_TIMEOUT_SECONDS=60
# (default) Who can register a new account.
# Production default is invite-only; set to open for local dev convenience.
# Options: open | invite-only
REGISTRATION_MODE=open
# ─────────────────────────────────────────────────────────────────────────────
# Auth — JWT
# ─────────────────────────────────────────────────────────────────────────────
# (required) Symmetric signing secret for JWT access and refresh tokens.
# Minimum 32 cryptographically random bytes. Server exits at startup if missing
# or too short — auto-generation is intentionally NOT supported (would silently
# log out all users on every restart).
# Generate: openssl rand -base64 32
JWT_SECRET=
# (optional) Previous JWT secret — set during key rotation so existing tokens
# remain valid until they expire. Remove after the longest token TTL has elapsed.
# JWT_SECRET_PREVIOUS=
# (default) JWT signing algorithm
JWT_ALGORITHM=HS256
# ─────────────────────────────────────────────────────────────────────────────
# Auth — Cookies
# ─────────────────────────────────────────────────────────────────────────────
# (default) Set the Secure flag on auth cookies.
# MUST be false for http://localhost (browser silently drops Secure cookies over HTTP).
# MUST be true in production (set to true when TLS is in use).
COOKIE_SECURE=false
# ─────────────────────────────────────────────────────────────────────────────
# Auth — Password hashing (Argon2id)
# ─────────────────────────────────────────────────────────────────────────────
# (default) Max simultaneous argon2id hash operations.
# Each operation allocates ~19.5 MB. Excess requests receive 503 immediately
# (non-blocking) to prevent OOM under concurrent login attacks.
ARGON2_MAX_CONCURRENT=5
# ─────────────────────────────────────────────────────────────────────────────
# Auth — Password Reset
# ─────────────────────────────────────────────────────────────────────────────
# (default) How long a password reset token is valid
PASSWORD_RESET_TOKEN_TTL=1h
# (default) Max password reset emails per user per hour
PASSWORD_RESET_MAX_PER_HOUR=3
# ─────────────────────────────────────────────────────────────────────────────
# Auth — Email Verification
# ─────────────────────────────────────────────────────────────────────────────
# (default) How long an email verification token is valid
EMAIL_VERIFICATION_TOKEN_TTL=24h
# (default) Max verification emails per user per hour
EMAIL_VERIFICATION_MAX_PER_HOUR=3
# ─────────────────────────────────────────────────────────────────────────────
# Auth — Account Lockout
# ─────────────────────────────────────────────────────────────────────────────
# (default) Failed login attempts before the account is temporarily locked
LOCKOUT_THRESHOLD=5
# (default) How long a locked account remains locked
LOCKOUT_DURATION=15m
# ─────────────────────────────────────────────────────────────────────────────
# Auth — MFA (Multi-Factor Authentication)
# ─────────────────────────────────────────────────────────────────────────────
# (default) Enforce MFA enrollment for site admins on login
MFA_REQUIRED_SITE_ADMINS=false
# (default) Enforce MFA enrollment for org owners on login
MFA_REQUIRED_ORG_OWNERS=false
# (default) How long an email OTP code is valid
MFA_EMAIL_OTP_TTL=10m
# (default) Max email OTP sends per user per hour
MFA_EMAIL_OTP_MAX_PER_HOUR=5
# (default) Failed MFA challenge attempts before the pending auth is rejected
MFA_CHALLENGE_MAX_ATTEMPTS=3
# (default) How long a pending MFA enrollment token is valid
MFA_PENDING_TOKEN_TTL=5m
# ─────────────────────────────────────────────────────────────────────────────
# CORS
# ─────────────────────────────────────────────────────────────────────────────
# (optional) Comma-separated list of allowed origins.
# Empty in production disables CORS. In development mode the server
# automatically allows localhost dev servers (e.g. http://localhost:5173).
# Example: https://app.example.com,https://admin.example.com
# CORS_ALLOWED_ORIGINS=
# ─────────────────────────────────────────────────────────────────────────────
# OAuth — GitHub
# ─────────────────────────────────────────────────────────────────────────────
# Create at: https://github.com/settings/developers → OAuth Apps
# Callback URL: ${EXTERNAL_URL}/api/v1/auth/oauth/github/callback
# (optional) GitHub OAuth credentials — GitHub login disabled if unset
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
# ─────────────────────────────────────────────────────────────────────────────
# OAuth — Google
# ─────────────────────────────────────────────────────────────────────────────
# Create at: https://console.cloud.google.com → APIs & Services → Credentials
# Callback URL: ${EXTERNAL_URL}/api/v1/auth/oauth/google/callback
# (optional) Google OAuth credentials — Google login disabled if unset
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
# ─────────────────────────────────────────────────────────────────────────────
# SSO — Encryption
# ─────────────────────────────────────────────────────────────────────────────
# (optional) 32-byte hex key for encrypting SSO state tokens.
# Required if any SSO provider is configured.
# Generate: openssl rand -hex 32
# SSO_ENCRYPTION_KEY=
# (optional) Previous encryption key — set during rotation so in-flight
# SSO flows remain valid. Remove after a few minutes.
# SSO_ENCRYPTION_KEY_PREVIOUS=
# ─────────────────────────────────────────────────────────────────────────────
# Email (SMTP)
# ─────────────────────────────────────────────────────────────────────────────
# In dev, point at Mailpit (started by docker compose up -d).
# Mailpit web UI: http://localhost:8025
#
# SMTP_TLS controls STARTTLS (RFC 3207), NOT implicit TLS (port 465).
# true = STARTTLS required — fails if the server doesn't advertise STARTTLS
# false = STARTTLS opportunistic — upgrades if available, falls back to plaintext
#
# For Amazon SES: use port 587 with SMTP_TLS=true.
# For Amazon SES endpoints: see https://docs.aws.amazon.com/general/latest/gr/ses.html#ses_smtp_endpoints
# For other providers: port 587 + SMTP_TLS=true is the standard configuration.
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_FROM=cvert-ops@localhost
# SMTP_USERNAME=
# SMTP_PASSWORD=
# SMTP_TLS=false
# ─────────────────────────────────────────────────────────────────────────────
# AI — Google Gemini
# ─────────────────────────────────────────────────────────────────────────────
# Create at: https://aistudio.google.com/apikey
# (optional) Gemini API key — AI features (NL search, CVE summaries) disabled if unset
GEMINI_API_KEY=
# (default) Gemini model to use for structured query generation
GEMINI_MODEL=gemini-2.0-flash
# (default) Timeout for Gemini API calls
GEMINI_TIMEOUT=30s
# ─────────────────────────────────────────────────────────────────────────────
# AI — Quotas
# ─────────────────────────────────────────────────────────────────────────────
# (default) Enable per-org AI usage quotas
AI_QUOTA_ENABLED=true
# (default) Monthly NL search quota per tier
AI_NL_SEARCH_LIMIT_FREE=10
AI_NL_SEARCH_LIMIT_PRO=100
AI_NL_SEARCH_LIMIT_ENTERPRISE=1000
# (default) Monthly CVE summarization quota per tier
AI_SUMMARIZE_LIMIT_FREE=5
AI_SUMMARIZE_LIMIT_PRO=50
AI_SUMMARIZE_LIMIT_ENTERPRISE=500
# (default) Cache TTLs for AI results
AI_CACHE_NL_SEARCH_TTL=1h
AI_CACHE_SUMMARIZE_TTL=24h
# (default) How long to retain AI usage logs (days)
AI_LOG_RETENTION_DAYS=90
# ─────────────────────────────────────────────────────────────────────────────
# SIEM — Syslog forwarding
# ─────────────────────────────────────────────────────────────────────────────
# (optional) Syslog endpoint for forwarding security events. Disabled if unset.
# Format: udp://host:port or tcp://host:port
# Example: udp://splunk.internal:514
# SIEM_SYSLOG_ADDR=
# (default) Syslog message format. Options: json | cef
SIEM_SYSLOG_FORMAT=json
# ─────────────────────────────────────────────────────────────────────────────
# Secrets file
# ─────────────────────────────────────────────────────────────────────────────
# (optional) Path to a secrets file. The server reloads secrets from this file
# on SIGHUP, enabling zero-downtime key rotation without a restart.
# CVERTOPS_SECRETS_FILE=
# ─────────────────────────────────────────────────────────────────────────────
# Feed adapters
# ─────────────────────────────────────────────────────────────────────────────
# (optional) NVD API key — unauthenticated rate limit is 5 req/30s (slow);
# authenticated is 50 req/30s. Get one at: https://nvd.nist.gov/developers/request-an-api-key
NVD_API_KEY=
# (optional) Directory containing vendor feed configuration files.
# Each .yaml file in this directory defines a vendor-specific feed adapter.
# CVERTOPS_FEEDS_DIR=
# ─────────────────────────────────────────────────────────────────────────────
# Notifications — delivery
# ─────────────────────────────────────────────────────────────────────────────
# (default) Max concurrent outbound deliveries per org (noisy-neighbour protection)
NOTIFY_MAX_CONCURRENT_PER_ORG=5
# (default) Debounce window in seconds: CVEs matching the same rule+channel within
# this window are batched into a single notification rather than N separate sends.
NOTIFY_DEBOUNCE_SECONDS=120
# (default) How long to accept the old signing secret after rotation (dual-secret window)
WEBHOOK_SECRET_GRACE_HOURS=24
# (default) Number of delivery jobs claimed per worker poll cycle
NOTIFY_CLAIM_BATCH_SIZE=50
# (default) Max retry attempts for failed deliveries (exponential backoff)
NOTIFY_MAX_ATTEMPTS=4
# (default) Base delay in seconds for exponential backoff between retries
NOTIFY_BACKOFF_BASE_SECONDS=30
# ─────────────────────────────────────────────────────────────────────────────
# Rate limiting
# ─────────────────────────────────────────────────────────────────────────────
# (default) Comma-separated CIDR ranges of trusted reverse proxies.
# When set, the rate limiter reads the real client IP from X-Forwarded-For
# (rightmost non-trusted entry) instead of r.RemoteAddr.
# Leave empty for direct connections (no reverse proxy).
# Example: 10.0.0.0/8,172.16.0.0/12
TRUSTED_PROXIES=
# (default) TTL for in-memory rate limiter entries; must be > token refill window.
# Format: Go duration string
RATE_LIMIT_EVICT_TTL=15m
# ─────────────────────────────────────────────────────────────────────────────
# Feed scheduler
# ─────────────────────────────────────────────────────────────────────────────
# (default) Enable the feed scheduler to periodically enqueue ingestion jobs
FEED_SCHEDULER_ENABLED=true
# ─────────────────────────────────────────────────────────────────────────────
# Data retention cleanup
# ─────────────────────────────────────────────────────────────────────────────
# (default) Enable the daily retention cleanup job
RETENTION_CLEANUP_ENABLED=true
# (default) Number of rows deleted per batch in the cleanup job
RETENTION_CLEANUP_BATCH_SIZE=10000
# (default) Max execution time for a single cleanup run (seconds)
RETENTION_MAX_RUNTIME_SECONDS=300
# (default) Per-table retention windows (days, except job queue which is hours).
# These control how long historical data is kept before the cleanup job deletes it.
RETENTION_RAW_PAYLOAD_DAYS=90
RETENTION_FEED_FETCH_LOG_DAYS=90
RETENTION_ALERT_EVENTS_DAYS=365
RETENTION_NOTIFICATION_DELIVERIES_DAYS=90
RETENTION_AUDIT_LOG_DAYS=365
RETENTION_SECURITY_EVENTS_DAYS=90
RETENTION_JOB_QUEUE_HOURS=24
# ─────────────────────────────────────────────────────────────────────────────
# Logging
# ─────────────────────────────────────────────────────────────────────────────
# (default) Log verbosity. Options: debug | info | warn | error
LOG_LEVEL=info
# (default) Log output format. Options: text (human-readable) | json (structured)
LOG_FORMAT=json
# ─────────────────────────────────────────────────────────────────────────────
# Go runtime tuning (advanced)
# ─────────────────────────────────────────────────────────────────────────────
# Memory limit for the Go runtime GC target.
# In containers, automemlimit sets this automatically from cgroup limits.
# Only set manually if you need to override automemlimit's value.
# Example: 400MiB
# GOMEMLIMIT=
# GC target percentage. Default is 100 (GC when heap doubles).
# Lower values (e.g. 50) trigger GC more often at the cost of CPU.
# GOGC=100