-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy path.env.example
More file actions
120 lines (102 loc) · 5.36 KB
/
Copy path.env.example
File metadata and controls
120 lines (102 loc) · 5.36 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
# Backend
# Matches docker-compose.yml defaults — run `docker compose up -d` and this works out of the box
DATABASE_URL=postgresql://anonvote:anonvote_secret@localhost:5432/anonvote
DIRECT_URL=postgresql://anonvote:anonvote_secret@localhost:5432/anonvote
JWT_SECRET=your_jwt_secret_here_min_32_chars
STELLAR_SECRET_KEY=your_stellar_secret_key_here
# Same key is used for both Stellar manageData operations and future Soroban contract calls
STELLAR_NETWORK=testnet
# Optional app-level encryption key for retry payloads and other non-ballot secrets.
DATA_ENCRYPTION_KEY=your_32_byte_hex_encryption_key_here
FRONTEND_ORIGIN=http://localhost:5173
PORT=3001
NODE_ENV=development
# Request logging (structured JSON, PII-redacted)
# LOG_LEVEL: debug | info | warn | error
LOG_LEVEL=info
# Comma-separated paths excluded from request logging
LOG_SKIP_PATHS=/health,/healthz,/api/health
# Email notifications (optional — get a free API key at https://resend.com)
RESEND_API_KEY=re_your_api_key_here
EMAIL_FROM=AnonVote <noreply@yourdomain.com>
# Soroban smart contract — blockchain audit trail (issue #77)
# Without this the app still works but all on-chain audit calls are skipped silently
# and a warning is logged at startup.
# To deploy: see docs/SOROBAN_INTEGRATION.md and contracts/README.md
SOROBAN_CONTRACT_ID=
# Override the default Soroban RPC endpoint (optional — defaults to Stellar testnet/mainnet)
SOROBAN_SERVER_URL=
# ── Transaction batching (issue #77) ─────────────────────────────────────────
# Votes are anchored in ONE atomic Soroban transaction per batch. A flush is
# triggered when the queue reaches VOTE_BATCH_SIZE votes or after
# VOTE_BATCH_TIMEOUT_MS has elapsed since the first queued vote.
VOTE_BATCH_SIZE=100
VOTE_BATCH_TIMEOUT_MS=30000
# ── Retry semantics & circuit breaker (issue #77) ────────────────────────────
# Total attempts per contract call (1 initial + retries) with exponential
# backoff of SOROBAN_RETRY_BASE_DELAY_MS * 2^attempt (default: 1s, 2s, 4s).
# Only retry-safe errors are retried; permanent contract rejections fail fast
# into the dead letter queue (soroban_dead_letters).
SOROBAN_MAX_ATTEMPTS=3
SOROBAN_RETRY_BASE_DELAY_MS=1000
# Circuit breaker for contract submissions — pauses batching when >threshold
# of recent calls fail; recovers via half-open probe after DURATION ms.
SOROBAN_CIRCUIT_BREAKER_THRESHOLD=0.5
SOROBAN_CIRCUIT_BREAKER_DURATION_MS=15000
SOROBAN_CIRCUIT_BREAKER_SAMPLE_SIZE=20
# Contract state reconciliation cadence (contract counters vs database)
CONTRACT_STATE_SYNC_INTERVAL_MS=60000
# ─────────────────────────────────────────────────────────────────────────────
# DDoS Protection & Rate Limiting Configuration
# ─────────────────────────────────────────────────────────────────────────────
# Vote-specific rate limits (enforced per IP, per ballot, per token)
# These are implemented in src/services/voteRateLimiter.ts
# Limits are enforced at the database level and persist across server restarts
#
# Per-IP limit: Prevents a single IP from flooding the system
# Default: 10 votes per minute
VOTE_RATE_LIMIT_PER_IP=10
VOTE_RATE_LIMIT_IP_WINDOW_MS=60000
# Per-ballot limit: Smooths traffic to prevent ballot-specific bursts
# Default: 100 votes per minute (scales with voter count)
VOTE_RATE_LIMIT_PER_BALLOT=100
VOTE_RATE_LIMIT_BALLOT_WINDOW_MS=60000
# Per-token limit: Prevents rapid resubmission of the same token
# Default: 3 attempts per hour (allows retry for legitimate network issues)
VOTE_RATE_LIMIT_PER_TOKEN=3
VOTE_RATE_LIMIT_TOKEN_WINDOW_MS=3600000
# Circuit Breaker Configuration
# Protects against cascading failures when database or services are degraded
# When error rate exceeds threshold, circuit opens and rejects new requests with 503
#
# Error rate threshold to open circuit (0.0 to 1.0, where 1.0 = 100% error rate)
# Default: 0.5 (50% error rate triggers circuit open)
CIRCUIT_BREAKER_THRESHOLD=0.5
# Duration in milliseconds to keep circuit open before attempting recovery
# Default: 10000ms (10 seconds)
CIRCUIT_BREAKER_DURATION=10000
# Number of recent requests to track for error rate calculation
# Default: 20 requests
CIRCUIT_BREAKER_SAMPLE_SIZE=20
# Request Validation Configuration
# Fail-fast validation to reject malformed requests before they reach the database
#
# Maximum length of encrypted vote payload in characters
# Default: 4096 (4KB of encrypted data)
MAX_ENCRYPTED_VOTE_LENGTH=4096
# Maximum total payload size in bytes (includes all JSON fields)
# Default: 10240 (10KB)
MAX_VOTE_PAYLOAD_SIZE=10240
# Rate limiting for tests (set to "true" to enable rate limits in test environment)
# Default: not set (rate limits disabled in tests)
# ENABLE_RATE_LIMITS=true
# Distributed vote protection (issue #75)
REDIS_URL=redis://localhost:6379
VOTE_RATE_LIMIT_PER_SECOND=5
VOTE_RATE_LIMIT_PER_HOUR=100
VOTE_CIRCUIT_TIMEOUT_MS=1000
VOTE_CIRCUIT_BREAKER_THRESHOLD=0.05
VOTE_CIRCUIT_BREAKER_DURATION_MS=30000
VOTE_CIRCUIT_BREAKER_SAMPLE_SIZE=20
VOTE_QUEUE_MAX_DEPTH=1000
VOTE_QUEUE_MAX_CONCURRENCY=100