2026-07-07 17:50:51 -04:00
|
|
|
# OSINT Dashboard — environment configuration
|
|
|
|
|
# Copy to `.env` and adjust. All values have safe defaults for local compose.
|
|
|
|
|
|
|
|
|
|
# ── PostgreSQL / TimescaleDB ───────────────────────────────────────────────
|
|
|
|
|
DB_USER=osint
|
|
|
|
|
DB_PASSWORD=osint
|
|
|
|
|
DB_HOST=db
|
|
|
|
|
DB_PORT=5432
|
|
|
|
|
DB_NAME=osint_data
|
|
|
|
|
|
|
|
|
|
# ── NATS JetStream (optional — only needed when profile `ingest` is used) ──
|
|
|
|
|
NATS_URL=nats://nats:4222
|
|
|
|
|
|
|
|
|
|
# ── MinIO (optional — document storage; endpoint used if wired later) ──────
|
|
|
|
|
MINIO_ENDPOINT=minio:9000
|
|
|
|
|
MINIO_ACCESS_KEY=
|
|
|
|
|
MINIO_SECRET_KEY=
|
|
|
|
|
# "true" for TLS endpoints (e.g. S3-compatible prod); "false" for local HTTP.
|
|
|
|
|
MINIO_SECURE=false
|
Add NASA FIRMS active-fire ingest + /api/fires; API keys management page
Coherent merge of two coordinated features on the shared working tree:
FIRMS fire heatmap (backend, t_6e404c14):
- app/fire_sources.py: fetch FIRMS VIIRS area CSV (free MAP_KEY) -> NATS events.fire
- fires hypertable (TimescaleDB, 1-day chunks) with natural-key PK
(latitude, longitude, acq_time, satellite); idempotent ON CONFLICT DO NOTHING
- alembic/versions/002_fires.py; GET /api/fires?bbox=&since= (JSON only)
- POST /api/ingest/fires; ~15 min poll loop (FIRMS_INTERVAL=900) in ingester
- env-driven config (FIRMS_MAP_KEY/DATASET/BBOX/INTERVAL); docs/firms.md covers
the zero-cost GIBS VIIRS_SNPP_Thermal_Anomalies_375m_All tile alternative
- 18 tests (parser, mapping, idempotency, API contract) verified vs real
TimescaleDB+PostGIS (localhost/osint-dashboard-pg image)
API keys page (frontend, t_4433cff2):
- app/keystore.py: api_keys table (self-creating), FIRMS/GEMINI/TELEGRAM
registry with format validation, ****last4 masking, get_api_key()
- GET/POST/DELETE /api/keys (never returns full values); Keys tab in index.html
DB_NULL_POOL env switch in app/database.py enables a NullPool for tests /
short-lived processes that open a fresh event loop per unit.
2026-08-24 15:37:42 -04:00
|
|
|
|
2026-08-24 14:54:51 -04:00
|
|
|
# ── Camera discovery scraper ───────────────────────────────────────────────
|
2026-08-27 15:46:49 -04:00
|
|
|
# Comma-separated public directory/list/API URLs (Insecam-style pages,
|
|
|
|
|
# plain-text lists, or the ALERTWest JSON API). Empty = built-in defaults
|
2026-08-27 15:54:54 -04:00
|
|
|
# (public-ip-cams README + ALERTCalifornia/ALERTWest official JPEGs +
|
|
|
|
|
# Live-Environment-Streams HLS/YouTube GeoJSON).
|
2026-08-24 14:54:51 -04:00
|
|
|
CAMERA_SOURCE_URLS=
|
|
|
|
|
CAMERA_SCRAPE_INTERVAL=3600
|
|
|
|
|
CAMERA_REQUEST_DELAY=2.0
|
2026-08-27 15:46:49 -04:00
|
|
|
CAMERA_MAX_PER_SOURCE=20000
|
2026-08-24 14:54:51 -04:00
|
|
|
NOMINATIM_URL=https://nominatim.openstreetmap.org
|
|
|
|
|
NOMINATIM_MIN_INTERVAL=1.1
|
|
|
|
|
SNAPSHOT_TTL_SECONDS=300
|
2026-08-24 15:40:31 -04:00
|
|
|
|
masscan: active RTSP (554) camera discovery service
Continuous whole-IPv4 rolling sweep for open TCP 554, feeding the same
cameras table as the passive scraper (discovery_source=masscan).
- masscan_config.py: env-driven knobs (range, ports, rate, retries, excludes)
- masscan_scanner.py: JSON-lines parser, rtsp://IP/ URL + url_hash dedupe,
ip-api geolocation, insert/refresh, NATS publish for new finds
- run_masscan_service.py: long-lived rolling-sweep runner (streams results
in, restarts on pass completion); fails closed without an excludefile
- deploy/: systemd unit + README + excludes file for the Pi host
- .env.example: masscan section
Verified end-to-end against a local Postgres: parse, insert, and dedupe
(0 new on re-ingest) all pass.
2026-08-24 22:23:36 -04:00
|
|
|
# ── masscan active camera discovery (host-level systemd service, NOT compose) ─
|
|
|
|
|
# Continuous rolling sweep for open RTSP port 554 across a range. Runs on the
|
|
|
|
|
# Pi host via deploy/osint-masscan.service (needs root + raw sockets). Results
|
|
|
|
|
# land in the same `cameras` table as the scraper (discovery_source=masscan).
|
2026-08-24 23:36:34 -04:00
|
|
|
# NOTE: 200 pps is the residential-safe default. 1k/10k pps saturated a home
|
|
|
|
|
# uplink. A full 0.0.0.0/0 sweep at 200 pps takes ~8 months (rolling).
|
masscan: active RTSP (554) camera discovery service
Continuous whole-IPv4 rolling sweep for open TCP 554, feeding the same
cameras table as the passive scraper (discovery_source=masscan).
- masscan_config.py: env-driven knobs (range, ports, rate, retries, excludes)
- masscan_scanner.py: JSON-lines parser, rtsp://IP/ URL + url_hash dedupe,
ip-api geolocation, insert/refresh, NATS publish for new finds
- run_masscan_service.py: long-lived rolling-sweep runner (streams results
in, restarts on pass completion); fails closed without an excludefile
- deploy/: systemd unit + README + excludes file for the Pi host
- .env.example: masscan section
Verified end-to-end against a local Postgres: parse, insert, and dedupe
(0 new on re-ingest) all pass.
2026-08-24 22:23:36 -04:00
|
|
|
MASSCAN_RANGE=0.0.0.0/0
|
|
|
|
|
MASSCAN_PORTS=554
|
2026-08-24 23:36:34 -04:00
|
|
|
MASSCAN_RATE=200
|
masscan: active RTSP (554) camera discovery service
Continuous whole-IPv4 rolling sweep for open TCP 554, feeding the same
cameras table as the passive scraper (discovery_source=masscan).
- masscan_config.py: env-driven knobs (range, ports, rate, retries, excludes)
- masscan_scanner.py: JSON-lines parser, rtsp://IP/ URL + url_hash dedupe,
ip-api geolocation, insert/refresh, NATS publish for new finds
- run_masscan_service.py: long-lived rolling-sweep runner (streams results
in, restarts on pass completion); fails closed without an excludefile
- deploy/: systemd unit + README + excludes file for the Pi host
- .env.example: masscan section
Verified end-to-end against a local Postgres: parse, insert, and dedupe
(0 new on re-ingest) all pass.
2026-08-24 22:23:36 -04:00
|
|
|
MASSCAN_RETRIES=1
|
|
|
|
|
MASSCAN_WAIT=0
|
|
|
|
|
MASSCAN_EXCLUDEFILE=/etc/osint-dashboard/masscan-excludes.txt
|
|
|
|
|
MASSCAN_FLUSH_EVERY=250
|
|
|
|
|
|
Add NASA FIRMS active-fire ingest + /api/fires; API keys management page
Coherent merge of two coordinated features on the shared working tree:
FIRMS fire heatmap (backend, t_6e404c14):
- app/fire_sources.py: fetch FIRMS VIIRS area CSV (free MAP_KEY) -> NATS events.fire
- fires hypertable (TimescaleDB, 1-day chunks) with natural-key PK
(latitude, longitude, acq_time, satellite); idempotent ON CONFLICT DO NOTHING
- alembic/versions/002_fires.py; GET /api/fires?bbox=&since= (JSON only)
- POST /api/ingest/fires; ~15 min poll loop (FIRMS_INTERVAL=900) in ingester
- env-driven config (FIRMS_MAP_KEY/DATASET/BBOX/INTERVAL); docs/firms.md covers
the zero-cost GIBS VIIRS_SNPP_Thermal_Anomalies_375m_All tile alternative
- 18 tests (parser, mapping, idempotency, API contract) verified vs real
TimescaleDB+PostGIS (localhost/osint-dashboard-pg image)
API keys page (frontend, t_4433cff2):
- app/keystore.py: api_keys table (self-creating), FIRMS/GEMINI/TELEGRAM
registry with format validation, ****last4 masking, get_api_key()
- GET/POST/DELETE /api/keys (never returns full values); Keys tab in index.html
DB_NULL_POOL env switch in app/database.py enables a NullPool for tests /
short-lived processes that open a fresh event loop per unit.
2026-08-24 15:37:42 -04:00
|
|
|
# ── NASA FIRMS (active fire / hotspot ingest) ──────────────────────────────
|
|
|
|
|
# MAP_KEY is FREE — get one at https://firms.modaps.eosdis.nasa.gov/api/map_key_info/
|
|
|
|
|
# (1-minute signup, no payment). Leave blank to keep fire ingest idle.
|
|
|
|
|
FIRMS_MAP_KEY=
|
|
|
|
|
# NRT VIIRS S-NPP 375m active fire detection (near-real-time).
|
|
|
|
|
FIRMS_DATASET=VIIRS_SNPP_NRT
|
|
|
|
|
# Area to poll as "minlon,minlat,maxlon,maxlat". Narrow it to reduce payload
|
|
|
|
|
# (e.g. CONUS "-125,24,-66,50"). Default covers most of the inhabited globe.
|
|
|
|
|
FIRMS_BBOX=-180,-60,180,75
|
|
|
|
|
# Poll cadence in seconds (~15 min). FIRMS NRT updates every ~5-10 min.
|
|
|
|
|
FIRMS_INTERVAL=900
|
|
|
|
|
# Set to 0 to disable the fire loop entirely.
|
|
|
|
|
INGEST_FIRES=1
|
|
|
|
|
|
|
|
|
|
# ── API keys (managed from the dashboard UI) ──────────────────────────────
|
2026-08-24 15:40:31 -04:00
|
|
|
# Keys such as GEMINI_API_KEY and TELEGRAM_TOKEN are stored in the Postgres
|
|
|
|
|
# `api_keys` table and managed from the dashboard's "Keys" tab
|
|
|
|
|
# (GET/POST/DELETE /api/keys/{name}) — see app/keystore.py. The FIRMS ingestor
|
|
|
|
|
# currently reads FIRMS_MAP_KEY from .env (above); wiring the Keys-UI store as
|
|
|
|
|
# its lookup/fallback is a planned follow-up.
|
2026-08-24 17:28:46 -04:00
|
|
|
|
|
|
|
|
# ── News pipeline (scraper + summarizer, profile `ingest`) ────────────────
|
|
|
|
|
# Hourly: the scraper crawls 257 RSS sources at minute :00 and the summarizer
|
|
|
|
|
# runs the Gemini map-reduce at minute :05, both writing to the shared osint-db
|
|
|
|
|
# (tables `articles` + `article_summaries`, created by alembic 003_news).
|
|
|
|
|
# Consume via GET /api/news and GET /api/news/summaries.
|
|
|
|
|
# GEMINI_API_KEY is REQUIRED for summarization; unset = summarizer idles.
|
|
|
|
|
GEMINI_API_KEY=
|
|
|
|
|
# Optional LLM knobs
|
|
|
|
|
SUMMARY_MODEL=gemini-2.0-flash
|
|
|
|
|
NEWS_BATCH_SIZE=50
|
|
|
|
|
SUMMARY_WINDOW_HOURS=1
|
|
|
|
|
# Futures/markets coupling from the upstream pipeline is OFF by default
|
|
|
|
|
# (irrelevant to OSINT). Set INCLUDE_FUTURES=1 + install yfinance to enable.
|
|
|
|
|
INCLUDE_FUTURES=0
|
|
|
|
|
# Wall-clock scheduling (k8s CronJob replacement): scrape minute, summarize minute
|
|
|
|
|
NEWS_SCRAPE_MINUTE=0
|
|
|
|
|
NEWS_SUMMARIZE_MINUTE=5
|
|
|
|
|
# Run once immediately on container start (seeds data fast), then align to the
|
|
|
|
|
# scheduled minute.
|
|
|
|
|
NEWS_SCRAPE_RUN_ON_START=1
|
|
|
|
|
NEWS_SUMMARIZE_RUN_ON_START=1
|
|
|
|
|
NEWS_LOG_LEVEL=INFO
|
|
|
|
|
# Reserved for the (out-of-scope) Telegram delivery bot.
|
|
|
|
|
TELEGRAM_TOKEN=
|
|
|
|
|
TELEGRAM_CHAT_ID=
|
2026-08-28 03:55:00 +00:00
|
|
|
|
|
|
|
|
# =============================================================================
|
|
|
|
|
# Forgejo container registry (CI publishes here; NOT ghcr.io)
|
|
|
|
|
# =============================================================================
|
|
|
|
|
# forgejo.siriusdevops.com/sirius/osint-dashboard[:tag]
|
|
|
|
|
# forgejo.siriusdevops.com/sirius/osint-dashboard-pg[:tag]
|
|
|
|
|
# forgejo.siriusdevops.com/sirius/osint-news-scraper[:tag]
|
|
|
|
|
# forgejo.siriusdevops.com/sirius/osint-news-summarizer[:tag]
|
|
|
|
|
FORGEJO_REGISTRY=forgejo.siriusdevops.com
|
|
|
|
|
FORGEJO_OWNER=sirius
|