shadowbroker-osint-platform
```markdown
What this skill does
```markdown
---
name: shadowbroker-osint-platform
description: Real-time multi-domain OSINT dashboard aggregating aircraft, ships, satellites, earthquakes, CCTV, GPS jamming, and geopolitical events on a unified map interface.
triggers:
- set up shadowbroker osint dashboard
- track private jets and aircraft with shadowbroker
- add a new data layer to shadowbroker
- configure shadowbroker backend api
- deploy shadowbroker with docker
- extend shadowbroker with custom feeds
- shadowbroker satellite tracking setup
- build osint map with shadowbroker
---
# ShadowBroker OSINT Platform
> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.
ShadowBroker is a self-hosted, real-time geospatial intelligence dashboard built with **Next.js** (frontend), **MapLibre GL** (map rendering), and **FastAPI + Python** (backend). It aggregates public OSINT feeds — ADS-B aircraft, AIS ships, satellite TLEs, USGS earthquakes, CCTV networks, GPS jamming, conflict events, and more — into a single dark-ops map interface.
---
## Installation
### Prerequisites
- Docker + Docker Compose **or** Podman + podman-compose
- Git
### Quick Start (Linux/macOS)
```bash
git clone https://github.com/BigBodyCobain/Shadowbroker.git
cd Shadowbroker
./compose.sh up -d
```
### Quick Start (Windows)
```bash
git clone https://github.com/BigBodyCobain/Shadowbroker.git
cd Shadowbroker
docker-compose up -d
```
Open **http://localhost:3000** in your browser.
### Force Podman engine
```bash
./compose.sh --engine podman up -d
```
### Update to latest version
```bash
git pull origin main
# Linux/macOS
./compose.sh down
./compose.sh up --build -d
# Windows
docker compose down
docker compose up --build -d
```
### Clear stale cache after update
```bash
docker compose build --no-cache
docker image prune -f
```
### View backend logs
```bash
./compose.sh logs -f backend
# or
docker compose logs -f backend
```
---
## Architecture Overview
```
Frontend (Next.js + MapLibre GL) → Backend (FastAPI + Python) → Public APIs
:3000 :8000
```
- **Frontend**: TypeScript/Next.js app with MapLibre GL for WebGL map rendering, layer toggles, control panels.
- **Backend**: FastAPI server that proxies, caches, and aggregates public data feeds (OpenSky, CelesTrak, USGS, GDELT, aisstream.io, NASA FIRMS, etc.).
- **No external database required** — data is cached on disk and in memory.
### Kubernetes / Helm (Advanced)
```bash
helm repo add bjw-s-labs https://bjw-s-labs.github.io/helm-charts/
helm repo update
helm install shadowbroker ./helm/chart --create-namespace --namespace shadowbroker
```
---
## Environment Variables
Create a `.env` file in the project root (never commit secrets):
```env
# AIS vessel stream (required for maritime layer)
AISSTREAM_API_KEY=your_key_here
# NASA FIRMS fire hotspots (required for fire layer)
NASA_FIRMS_API_KEY=your_key_here
# Optional: override default ports
FRONTEND_PORT=3000
BACKEND_PORT=8000
```
Reference in code as `process.env.AISSTREAM_API_KEY` (frontend) or `os.environ["AISSTREAM_API_KEY"]` (backend).
---
## Key Data Layers & Sources
| Layer | Source | Notes |
|---|---|---|
| Commercial flights | OpenSky Network | ~5,000+ aircraft, no key needed |
| Private/military jets | adsb.lol | Includes owner identification |
| Maritime AIS | aisstream.io WebSocket | 25,000+ vessels, API key required |
| Satellites | CelesTrak TLE + SGP4 | 2,000+ active, no key needed |
| Earthquakes | USGS real-time feed | 24h window |
| Fire hotspots | NASA FIRMS VIIRS | API key required |
| Conflict events | GDELT | Last 8 hours |
| Ukraine frontline | DeepState Map GeoJSON | Live |
| CCTV cameras | TfL, TxDOT, NYC DOT, Singapore LTA | No key needed |
| GPS jamming | ADS-B NAC-P analysis | Computed from flight data |
| SDR receivers | KiwiSDR network | 500+ nodes |
| Satellite imagery | NASA GIBS MODIS / Esri / Sentinel-2 | No key needed |
---
## Backend API (FastAPI) — Key Endpoints
Base URL: `http://localhost:8000`
```
GET /api/flights/commercial # OpenSky commercial aircraft
GET /api/flights/private # Private/GA aircraft
GET /api/flights/military # Military aircraft
GET /api/flights/private-jets # HNW individual jets with owner info
GET /api/ships # AIS vessel positions
GET /api/satellites # Real-time satellite positions (SGP4)
GET /api/earthquakes # USGS 24h earthquake feed
GET /api/fires # NASA FIRMS hotspots
GET /api/gdelt/conflict # GDELT conflict events
GET /api/carriers # US Navy carrier strike group positions
GET /api/cctv # Aggregated CCTV camera feeds
GET /api/gps-jamming # Computed GPS jamming zones
GET /api/space-weather # NOAA geomagnetic Kp index
GET /api/internet-outages # Georgia Tech IODA outage data
GET /api/news # SIGINT/OSINT RSS aggregation
GET /api/region-dossier?lat=&lon= # Country profile + head of state
GET /api/sentinel?lat=&lon= # Sentinel-2 latest image for coordinates
```
---
## Frontend Usage — Adding a Custom Layer (TypeScript)
The frontend communicates with the backend via `fetch`. Example pattern for a new data layer:
```typescript
// src/hooks/useCustomLayer.ts
import { useEffect, useState } from "react";
interface CustomFeature {
id: string;
lat: number;
lon: number;
label: string;
}
export function useCustomLayer(enabled: boolean) {
const [features, setFeatures] = useState<CustomFeature[]>([]);
useEffect(() => {
if (!enabled) return;
const fetchData = async () => {
const res = await fetch("http://localhost:8000/api/your-endpoint");
const data = await res.json();
setFeatures(data.features ?? []);
};
fetchData();
const interval = setInterval(fetchData, 30_000); // refresh every 30s
return () => clearInterval(interval);
}, [enabled]);
return features;
}
```
### Adding the layer to MapLibre GL
```typescript
// Inside your map component
import maplibregl from "maplibre-gl";
function addCustomLayer(map: maplibregl.Map, features: CustomFeature[]) {
const sourceId = "custom-layer";
const layerId = "custom-layer-points";
const geojson: GeoJSON.FeatureCollection = {
type: "FeatureCollection",
features: features.map((f) => ({
type: "Feature",
geometry: { type: "Point", coordinates: [f.lon, f.lat] },
properties: { id: f.id, label: f.label },
})),
};
if (map.getSource(sourceId)) {
(map.getSource(sourceId) as maplibregl.GeoJSONSource).setData(geojson);
} else {
map.addSource(sourceId, { type: "geojson", data: geojson });
map.addLayer({
id: layerId,
type: "circle",
source: sourceId,
paint: {
"circle-radius": 6,
"circle-color": "#00ff88",
"circle-opacity": 0.85,
},
});
}
}
```
---
## Backend — Adding a Custom FastAPI Endpoint (Python)
```python
# backend/routers/custom.py
from fastapi import APIRouter
import httpx
import asyncio
from functools import lru_cache
import time
router = APIRouter()
_cache: dict = {"data": None, "ts": 0}
CACHE_TTL = 60 # seconds
async def fetch_source_data() -> list[dict]:
async with httpx.AsyncClient(timeout=10) as client:
resp = await client.get("https://example-public-api.org/data.json")
resp.raise_for_status()
return resp.json()
@router.get("/api/custom-feed")
async def custom_feed():
now = time.time()
if _cache["data"] is None or now - _cache["ts"] > CACHE_TTL:
raw = await fetch_source_data()
_cache["data"] = [
{"id": item["id"], "lat": item["latitude"], "lon": item["longitude"], "label": item["name"]}
for item in raw
]
_cache["ts"] = now
return {"features": _cache["data"], "count": len(_cache["data"])}
```
Register in `main.py`:
```python
from routers Related in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.