Configuration
All environment variables with defaults and descriptions.
Core
| Variable | Default | Description |
ECHELON_PORT | 1947 | HTTP listen port |
ECHELON_DB_PATH | ./echelon.db | Path to SQLite database file |
ECHELON_SECRET | (empty) | Bearer token for API auth. If unset, PoW tokens won't survive restarts |
ECHELON_RETENTION_DAYS | 90 | Days to keep raw visitor_views and semantic_events |
Authentication
| Variable | Default | Description |
ECHELON_USERNAME | (empty) | Username for password-based login |
ECHELON_PASSWORD_HASH | (empty) | PBKDF2 hash (pbkdf2$600000$<salt>$<hash>) |
Generate a password hash:
deno eval "import{hashPassword}from'./lib/auth.ts';console.log(await hashPassword('yourpassword'))"
Bot Defense
| Variable | Default | Description |
ECHELON_SUSPECT_COUNTRIES | CN | Comma-separated ISO-2 codes that add penalty points |
ECHELON_SUSPECT_POINTS | 30 | Points added per suspect country match |
ECHELON_SITE_SUSPECT_COUNTRIES | (empty) | Per-site suspect countries: site:CC,CC;site:CC |
ECHELON_BOT_DISCARD_THRESHOLD | 0 | Scores ≥ this are discarded before storage. 0 = store all |
ECHELON_BOT_UA_PATTERNS | (long list) | Comma-separated UA substrings to drop entirely |
ECHELON_CHALLENGE_WINDOW_MINUTES | 10 | Minutes of past PoW challenges accepted as valid |
Rate Limiting
| Variable | Default | Description |
ECHELON_RATE_LIMIT_MAX | 100 | Max requests per IP per window |
ECHELON_RATE_LIMIT_WINDOW_MS | 60000 | Rate limit window in milliseconds |
Buffered Writes
| Variable | Default | Description |
ECHELON_VIEW_FLUSH_MS | 15000 | Flush interval for pageview buffer (ms) |
ECHELON_EVENT_FLUSH_MS | 10000 | Flush interval for event buffer (ms) |
Network & Proxy
| Variable | Default | Description |
ECHELON_TRUST_PROXY | false | Trust X-Forwarded-For / X-Real-IP for client IP |
ECHELON_BEHIND_CLOUDFLARE | false | Trust Cloudflare headers (cf-*) for geo and bot data |
ECHELON_TRUST_GEO_HEADERS | false | Trust cloudfront-viewer-country / x-country-code |
ECHELON_ALLOWED_ORIGINS | (empty) | Comma-separated domains allowed to load the tracker. Empty = all |
Admin UI
| Variable | Default | Description |
ECHELON_LIVE_STATS_MINUTES | 10 | Time window (minutes) for live stats in the admin nav bar |
ECHELON_DISPLAY_TIMEZONE | UTC | IANA timezone for admin UI timestamps (e.g. Europe/Oslo). Data is stored in UTC. |
MCP Server
| Variable | Default | Description |
ECHELON_URL | (required) | Base URL of the Echelon Analytics instance the MCP server queries (e.g. https://ea.islets.app) |
ECHELON_SECRET | (empty) | Bearer token for authenticated instances. Not needed for public mode instances. |
Anonymization & Public Mode
| Variable | Default | Description |
ECHELON_ANONYMIZE_SITES | (empty) | Comma-separated site IDs to anonymize before storage. Records for these sites get HMAC-hashed visitor IDs, fictional countries, redacted referrers, and codename UTMs. See Telemetry |
ECHELON_PUBLIC_MODE | false | Disable admin auth requirement. The dashboard is openly accessible without login — ideal for public analytics dashboards |
Miscellaneous
| Variable | Default | Description |
ECHELON_COOKIE_CONSENT | false | Show consent banner before setting visitor cookie |
ECHELON_IGNORED_SITES | (empty) | Comma-separated site IDs to silently ignore. "smoke-test" always ignored |
ECHELON_TELEMETRY | (unset) | Override telemetry: true = force on, false = force off, unset = respect admin choice. See Telemetry |
🌍 "Did you know you can set per-site suspect countries with ECHELON_SITE_SUSPECT_COUNTRIES? Format: site1:CN,RU;site2:KP for granular bot defense." -🦭
Example .env
# Core
ECHELON_PORT=1947
ECHELON_DB_PATH=./data/echelon.db
ECHELON_SECRET=change-me-to-a-secure-random-string
ECHELON_RETENTION_DAYS=90
# Auth
ECHELON_USERNAME=admin
ECHELON_PASSWORD_HASH=pbkdf2$600000$...
# Network
ECHELON_TRUST_PROXY=true
ECHELON_BEHIND_CLOUDFLARE=true
# Bot defense
ECHELON_SUSPECT_COUNTRIES=CN
ECHELON_SUSPECT_POINTS=30
ECHELON_RATE_LIMIT_MAX=100
# Admin UI
ECHELON_LIVE_STATS_MINUTES=10
ECHELON_DISPLAY_TIMEZONE=Europe/Oslo
# Telemetry (optional — unset = prompt admin on first access)
# ECHELON_TELEMETRY=false