## --------------------------------------------------------------------------- ## CI Agent environment configuration ## Copy to .env and adjust. Nothing here is a real secret. ## --------------------------------------------------------------------------- # --- App ----------------------------------------------------------------- APP_ENV=development APP_NAME=CI Agent # Comma-separated list of allowed CORS origins. Add your LAN address here # (e.g. http://localhost:3000,http://192.168.1.190:3000) to reach the app # from another device on your network - find your LAN IP with `ipconfig` # (Windows) or `ifconfig`/`ip a` (Mac/Linux). FRONTEND_URL=http://localhost:3000 BACKEND_URL=http://localhost:8000 # What the *browser* uses to reach the API - baked into the frontend build, # so for LAN access this must be the host's LAN IP, not localhost (e.g. # http://192.168.1.190:8000). Leave unset for localhost-only access. NEXT_PUBLIC_API_URL=http://localhost:8000 # --- Reverse proxy (only relevant once deployed behind Cloudflare/Nginx) ----- # Empty = trust the direct connection for client-IP resolution (correct for # this Docker/local setup - no proxy exists). Set to CF-Connecting-IP once # behind Cloudflare's proxy, or the IP throttle/ban system and is_localhost # will treat every visitor as sharing the proxy's own address. TRUSTED_PROXY_IP_HEADER= # --- Local-dev convenience -------------------------------------------------- # Comma-separated extra IPs that is_localhost treats as loopback-equivalent. # Needed under Docker Desktop, where even host-originated traffic arrives at # the containers via the bridge gateway rather than real loopback - find # yours from a recent ip_throttle_state/user_security_events row, or leave # blank to keep the strict default (only real 127.0.0.1/::1 count as local). # Never set this in a real deployment. ADDITIONAL_TRUSTED_LOCAL_IPS= # --- Auth ------------------------------------------------------------------ # local = single fixed dev user, no login screen required # jwt = real email/password accounts AUTH_MODE=local JWT_SECRET=dev-only-change-me-32-characters-minimum JWT_ACCESS_TOKEN_MINUTES=15 JWT_REFRESH_TOKEN_DAYS=7 # --- Database ---------------------------------------------------------------- # Postgres (Docker Compose default): DATABASE_URL=postgresql+psycopg://ciagent:ciagent@postgres:5432/ciagent # SQLite fallback for running the API without Docker: # DATABASE_URL=sqlite+aiosqlite:///./ciagent_dev.db # --- Redis / Celery -------------------------------------------------------- REDIS_URL=redis://redis:6379/0 CELERY_TASK_ALWAYS_EAGER=false # --- LLM --------------------------------------------------------------------- # mock | anthropic | ollama | gemini LLM_PROVIDER=mock ANTHROPIC_API_KEY= ANTHROPIC_MODEL=claude-sonnet-5 OLLAMA_BASE_URL=http://host.docker.internal:11434 OLLAMA_MODEL=llama3.1 # Free-tier option: create a key at https://aistudio.google.com/apikey GEMINI_API_KEY= GEMINI_MODEL=gemini-2.0-flash LLM_MAX_TOKENS_PER_REQUEST=4000 LLM_MAX_RETRIES=2 # --- Search / company discovery -------------------------------------------- # mock | brave SEARCH_PROVIDER=mock BRAVE_SEARCH_API_KEY= SERPAPI_API_KEY= BING_SEARCH_API_KEY= # --- Patents ----------------------------------------------------------------- # Free key via account registration at data.uspto.gov/apis/getting-started # (now requires ID.me identity verification). PatentSourceCollector falls # back to its honest disabled/fixture behavior when this is empty. USPTO_API_KEY= # --- Company enrichment (NinjaPear / nubela.co) ------------------------------- # Paid, per-credit API - get a key from nubela.co/dashboard after # registering. Only ever called once per company, at creation time (never # on a recurring schedule) - see app/services/enrichment_service.py. # Leave empty to skip this feature entirely; nothing else in the app # depends on it. NINJAPEAR_API_KEY= NINJAPEAR_MAX_LEADERSHIP_LOOKUPS=5 # --- Email (SMTP) ------------------------------------------------------------ # Fallback transport when RESEND_API_KEY (below) isn't set - alert emails # and, if Resend is unconfigured, security emails go through this. Point it # at any real SMTP relay (e.g. your own mail server, or Resend's own SMTP # endpoint at smtp.resend.com). Nothing in this stack runs a local catch-all # mail sink - a real relay (or a real Resend account) is required to # actually test email delivery locally. SMTP_HOST= SMTP_PORT=587 SMTP_USERNAME= SMTP_PASSWORD= SMTP_FROM_EMAIL=alerts@ci-agent.local SMTP_USE_TLS=true # --- Resend (transactional security email: verify/reset/lockout) ------------ # Unset by default - falls back to the SMTP block above. Get a key from # resend.com after verifying your sending domain. RESEND_API_KEY= RESEND_SECURITY_FROM_EMAIL=security@ciagent.org # --- Cloudflare Turnstile (CAPTCHA on register/login/password-reset) -------- # Unset by default - skipped when the caller is on loopback, or when this # isn't configured at all (neither here nor via the Settings page's admin # "Server secrets" box, which takes priority over these when set - see # app/services/system_secret_service.py). The site key is safe to expose # publicly; /system/status serves it live to the frontend, so there's no # separate NEXT_PUBLIC_* build-time variable for it. TURNSTILE_SITE_KEY= TURNSTILE_SECRET= # --- SMS (optional) ----------------------------------------------------------- NOTIFICATION_SMS_ENABLED=false # twilio | telnyx SMS_PROVIDER=twilio TWILIO_ACCOUNT_SID= TWILIO_AUTH_TOKEN= TWILIO_FROM_NUMBER= # Telnyx: portal.telnyx.com -> API Keys for TELNYX_API_KEY; the number must # be assigned to a Messaging Profile (portal.telnyx.com -> Messaging). TELNYX_API_KEY= TELNYX_FROM_NUMBER= SMS_MONTHLY_CAP=50 # --- GitHub collector (optional, raises rate limit) -------------------------- GITHUB_TOKEN= # --- Scheduling defaults ----------------------------------------------------- DEFAULT_TIMEZONE=America/New_York DEFAULT_MONITORING_FREQUENCY=weekly MINIMUM_MONITORING_INTERVAL_MINUTES=60 # --- Scraper behavior --------------------------------------------------------- SCRAPER_USER_AGENT=CIAgentBot/1.0 (+https://ci-agent.local/bot) MAX_PAGES_PER_DOMAIN=25 SCRAPER_REQUEST_TIMEOUT_SECONDS=30 SCRAPER_DOMAIN_DELAY_SECONDS=2 # --- Cost / abuse controls ----------------------------------------------------- MAX_COMPANIES_PER_USER=25 MAX_MANUAL_RUNS_PER_DAY=10 # --- Retention & logging ------------------------------------------------------- DATA_RETENTION_DAYS=365 LOG_LEVEL=INFO