# ===== Planner metrics version ===== # 3 ranks by instrumented validation HTTP attempts from RequestLedger. PLANNER_METRICS_VERSION=3 # ===== GitHub artifact hunter ===== # Enabled by default as a product preference; instance still no-ops without tokens + DATABASE_URL. GITHUB_HUNTER_ENABLED=true # Comma-separated fine-grained PATs (Contents read-only, public only recommended). GITHUB_TOKENS= GITHUB_API_BASE_URL=https://api.github.com GITHUB_API_VERSION=2022-11-28 # Per-pack commit-message shard budget (R3 multi-term queries need ≥8–10). GITHUB_COMMIT_QUERY_BUDGET=12 GITHUB_CODE_QUERY_BUDGET=8 GITHUB_SEARCH_PAGE_SIZE=100 GITHUB_MAX_PAGES_PER_SHARD=5 # Incremental: hours to look back when no checkpoint watermark exists. GITHUB_LOOKBACK_HOURS=24 # Full scan without BACKFILL_FROM: default 720h (30 days). mode=full always ignores watermark. GITHUB_FULL_LOOKBACK_HOURS=720 # Optional absolute start for full backfill (ISO date/datetime, e.g. 2025-06-01). GITHUB_BACKFILL_FROM= GITHUB_OVERLAP_MINUTES=15 GITHUB_REQUEST_TIMEOUT=20 GITHUB_ARTIFACT_CONCURRENCY=8 GITHUB_MAX_COMMIT_FILES=3000 GITHUB_MAX_BLOB_BYTES=1048576 GITHUB_BLOB_FALLBACK_BUDGET=100 GITHUB_FILE_HISTORY_ENABLED=true GITHUB_FILE_HISTORY_COMMIT_LIMIT=100 # Skip a GitHub lane when all tokens for that resource cool longer than this. GITHUB_RATE_LIMIT_MAX_WAIT_SECONDS=90 # ===== FofoAPI Configuration ===== # Comma-separated list of FOFA keys (rotation / fallback) FOFA_KEYS=your_fofa_key_1,your_fofa_key_2,your_fofa_key_3 # Base URL of the FOFA proxy (fofoapi.com is recommended, faster) FOFA_BASE_URL=https://fofoapi.com # Page size per request (max 100, but header/banner/cert fields reduce it to be safe) FOFA_PAGE_SIZE=100 # Max pages per query (total results capped at 10000 by platform unless paid) FOFA_MAX_PAGES=10 # Request timeout (seconds) FOFA_TIMEOUT=30 # Reserved for compatibility with earlier deployments. FOFA_QUERY_CONCURRENCY=3 # Delay between FOFA pages (seconds). FOFA_PAGE_DELAY=0.3 # Reserve 20% of planned searches for deterministic exploration of lower-yield queries. QUERY_EXPLORATION_RATIO=0.2 # Incremental scan query-expression budgets (full scans execute every query). FOFA_QUERY_BUDGET=24 SHODAN_QUERY_BUDGET=16 # Conservative cap on expected hosts covered by a Shodan country-shard group. SHODAN_SHARD_HOST_BUDGET=1000 # Concurrent in-flight host probes (HTTP). Semaphore limit, not task count. PROBER_CONCURRENCY=50 # How many hosts to schedule as asyncio tasks per wave. Large scans (10k–30k # hosts) are split into batches so peak memory stays bounded on small VPS # (e.g. 2c6g). Lower this if OOM persists; raise on bigger boxes. PROBER_BATCH_SIZE=200 # Concurrency for validation probes (max in-flight HTTP validates) VALIDATE_CONCURRENCY=20 # Credentials loaded/scheduled per wave when validating from PostgreSQL spill. VALIDATE_BATCH_SIZE=500 # Max concurrent provider requests triggered by the UI batch balance action. # A page may select up to 50 records; keep this conservative on small VPS hosts. BALANCE_BATCH_CONCURRENCY=6 # Request timeout for validation probes VALIDATE_TIMEOUT=15 # Small VPS (2 vCPU / 6GB) — concurrency only; keep full probe risk + source=all # PROBER_CONCURRENCY=6 # PROBER_BATCH_SIZE=100 # VALIDATE_CONCURRENCY=6 # VALIDATE_BATCH_SIZE=500 # GITHUB_ARTIFACT_CONCURRENCY=3 # Per-target HTTP budget for product probers (dict + L0–L3 need headroom). MAX_REQUESTS_PER_TARGET=650 # Independent generic-prober budget (refetch / fallback). Isolated from product L1+. GENERIC_MAX_REQUESTS_PER_TARGET=12 MAX_PROBE_REDIRECTS=2 MIN_PROBE_EVIDENCE_SCORE=50 # # ⚠️ ACTIVE-PROBE SAFETY GATES — this example ships a SAFE, L0-ONLY default. # L0 = passive unauthenticated reads only. Enabling anything below turns on # ACTIVE attack behaviour (weak-password spraying, IDOR, SSRF, SQLi, RCE) and # is only lawful against targets you are explicitly authorized to test. # DO NOT flip these on for an internet-wide sweep. Fill AUTHORIZED_PROBE_SCOPE # with the exact origins you own/are authorized for BEFORE raising the risk. # # Master gate for L1+ (weak_password / IDOR / SSRF / SQLi / RCE). # false → only L0 unauth_read (default). true → L1+ allowed per flags below. INTRUSIVE_CHECKS=false # Required origin allowlist for L1+ (comma-separated exact origins, no path/query). # Empty always fails closed to L0, even when INTRUSIVE_CHECKS=true. AUTHORIZED_PROBE_SCOPE= # Password dictionary (one password per line). Empty = packaged Rust resource: # crates/aipocket-prober/data/weak_passwords.txt WEAK_PASSWORD_DICT_PATH= # Usernames tried with each dict password (order = priority; admin first). WEAK_PASSWORD_USERNAMES=admin,root # Cap (username,password) pairs per target. 0 = full dict × usernames (budget-limited). # Each product weak-password Spec ALSO caps itself via its own max_requests. WEAK_PASSWORD_MAX_ATTEMPTS=0 # Vuln-class allowlist. Classes: unauth_read,weak_password,idor,ssrf,sqli,rce (* = all). # Unknown / misspelled class names are REJECTED at startup (fail-closed). PROBE_VULN_CLASSES=* # Max risk level: 0=L0 only, 1=+L1 weak/IDOR, 2=+L2 SSRF/SQLi, 3=+L3 RCE. # Product adapters each register L0–L3 Specs; this + flags decide what actually runs. # Safe default is 0 (L0 passive reads only). Raise ONLY with authorization. PROBE_MAX_RISK=0 # L2/L3 class switches (also need INTRUSIVE_CHECKS=true and PROBE_MAX_RISK ≥ 2/3). # Every product prober ships SSRF + SQLi + RCE Specs; these turn them on. # Default OFF — leave off unless you are authorized to run active exploits. PROBE_SSRF_ENABLED=false PROBE_SQLI_ENABLED=false PROBE_RCE_ENABLED=false # ===== Scheduler ===== # Enable periodic execution (true/false) SCHEDULER_ENABLED=false # Interval between runs (seconds). 3600 = 1 hour SCHEDULER_INTERVAL=3600 # Redis lease TTL for global scan coordination. The owner renews every TTL/3. SCAN_LOCK_TTL=7200 # ===== Tavily (CVE sync) ===== TAVILY_BASE_URL=https://tavily.astrdark.cyou TAVILY_KEY=your_tavily_proxy_key # ===== GPT Analyzer (third-party OpenAI-compatible API) ===== GPT_BASE_URL=https://your-gpt-proxy.com/v1 GPT_KEY=sk-your-gpt-key GPT_MODEL=gpt-4o-mini # Fast mode: higher concurrency for GPT extract batches GPT_FAST=false # reasoning_effort for reasoning models (low|medium|high, or ""/none to omit). # Fast models (e.g. grok-4.5) can afford "high" for better extraction accuracy. GPT_REASONING_EFFORT=high # Re-check concurrency (parallel GPT calls for validation re-check) GPT_RECHECK_CONCURRENCY=10 # Re-check batch size (items per GPT call; reduces total API calls) GPT_RECHECK_BATCH_SIZE=10 # Cooldown seconds between GPT extract and re-check (avoids rate-limit storms) GPT_RECHECK_COOLDOWN=5.0 # ===== Output ===== # Directory for JSON results RESULTS_DIR=results # ===== Web API (Axum service layer, `aipocket serve`) ===== # Single global password for the web UI login. Required to start the server. WEB_PASSWORD=change_me_to_a_strong_password # HMAC secret for signing JWT session tokens. Required. Use a long random string, # e.g. `python -c "import secrets; print(secrets.token_urlsafe(48))"`. WEB_JWT_SECRET=change_me_to_a_long_random_secret # Session token lifetime in seconds (default 86400 = 24h). WEB_TOKEN_TTL=86400 # CORS allowed origins (comma-separated). "*" for local dev; set the real # frontend origin(s) in production, e.g. https://app.example.com WEB_CORS_ORIGINS=* # Rolling in-memory scan log window (lines kept for SSE replay + polling). WEB_LOG_BUFFER_LINES=2000 # ===== Cross-run Dedup (Redis) ===== # When True, hosts/credentials already processed in a previous run are skipped # (successful validations are cached + reused; failures get a short TTL so they # are retried later). If Redis is unreachable, the scan degrades gracefully to # the original no-dedup behavior. Set DEDUP_ENABLED=false to disable entirely. DEDUP_ENABLED=true DEDUP_REDIS_URL=redis://localhost:6379/0 # TTLs in seconds. Defaults: host=7d, cred=3d, deterministic rejection=30d, # transient failure=6h, balance=1d. DEDUP_HOST_TTL=604800 DEDUP_CRED_TTL=259200 DEDUP_REJECTED_TTL=2592000 DEDUP_TRANSIENT_TTL=21600 DEDUP_BALANCE_TTL=86400 # ===== PostgreSQL (persistent source of truth) ===== # libpq connection URL for the scan results / high-value keys / CVE store. # Leave empty to keep using JSONL files only (original behavior). Set it to # enable PG. In docker-compose this points at the bundled `postgres` service. # postgresql://aipocket:aipocket@localhost:5432/aipocket DATABASE_URL= # Connection pool sizing. PG_POOL_MIN=2 PG_POOL_MAX=10 # Transitional dual-write: true => write BOTH PG and JSONL (for backfill + # verification + rollback when migrating an existing deployment). Default false # => PG is the sole source of truth. Set true only during a migration. PG_DUAL_WRITE=false # ===== Shodan Configuration (second data source) ===== # Comma-separated list of Shodan API keys (rotation / fallback) # Get yours from https://account.shodan.io SHODAN_KEYS=your_shodan_key_1,your_shodan_key_2 # Base URL of the Shodan REST API (rarely changed) SHODAN_BASE_URL=https://api.shodan.io # Max pages per query (Shodan returns 100 results/page). 1 page = 1 query credit # when the query contains a filter. Higher = more coverage, more credits. # Budget: 200000 query credits/month, 1 credit = 100 results. # Note: the very largest product queries are country-sharded (see SHARD_PRODUCTS # in shodan_queries.py), so 10 pages here lets each shard pull up to 1000 fresh # hits instead of being truncated at the first 100. SHODAN_MAX_PAGES=10 # Maximum Shodan page-1 credits allocated to country shards per product query. SHODAN_CREDIT_BUDGET=8 # Request timeout (seconds) SHODAN_TIMEOUT=30 # Delay between paginated requests (seconds). Shodan rate-limits ~1 req/sec. SHODAN_PAGE_DELAY=1