Inspiration Every day, SOC analysts at US electric utilities, water districts, and grid operators spend 2–3 hours manually correlating threat data across six or more tools — Censys for ICS discovery, Google News for OSINT, the MITRE ATT&CK website for technique mapping, CISA's KEV catalog for exploited vulnerabilities, and three separate geo-feeds to check whether a wildfire or earthquake just turned a routine exposure into an active crisis. They get an IP and a port from Shodan or Censys. That's it. No context. No prioritization. No geo-situational awareness. Just a raw data point that might be critical — or might be nothing — and no way to tell without an hour of tab-switching.
We asked: what if a Strands agent handled all of that autonomously? What if you typed "Monitor grid assets in the Southeast US" and an agent discovered the exposed devices, searched for relevant threat intelligence, mapped every finding to MITRE ATT&CK, cross-referenced CISA's exploited vulnerability catalog, fused live geo-event data from GDACS, NASA FIRMS, USGS, and NOAA, and produced a complete, cited, SOC-ready dossier — only alerting you when a P1 finding surfaces? That's Strands Guardian.
What it does Strands Guardian is an autonomous AI agent built with the Strands Agents SDK that orchestrates seven specialized tools to deliver end-to-end ICS/SCADA threat intelligence:
Discover — The agent queries the Censys Platform API v3 for exposed ICS/SCADA services (Modbus TCP, Siemens S7, DNP3, EtherNet/IP, IEC-104, BACnet) scoped to US infrastructure. When no API key is present, it falls back to realistic mock data so the entire pipeline is demo-able with zero configuration.
Analyze — For each discovered asset, the agent runs a multi-layered intelligence fusion: SerpApi structured search (primary) composes a strategic brief from dated, cited headlines; Tavily advanced search serves as AI-native fallback. Every brief carries source attribution with publication dates, relevance scores, MITRE ATT&CK technique mappings (with confidence level, rationale, and evidence snippets), and CISA KEV/NVD cross-references.
Geo-Fuse — A cached geo-event store aggregates five real-time feeds simultaneously: GDACS (global disasters), NASA FIRMS (VIIRS active-fire pixels with severity from Fire Radiative Power), USGS (earthquakes ≥ M4.5, past 7 days), NOAA CAP (active US weather alerts via polygon centroids), and SerpApi/Tavily locale-scoped news sweeps. Each finding shows nearby events with haversine distance and compass bearing — so an Ontario wildfire correctly registers as a cross-border threat to a Michigan grid asset.
Dossier & Alert — The agent synthesizes all findings into a SOC-ready dossier per asset, available in Markdown, JSON, and CSV formats. Each dossier includes a P1–P3 priority score (computed from threat count, KEV matches, ATT&CK techniques, and geo-event severity), and P1 findings trigger immediate Slack/webhook alerts with full context.
How we built it We built Strands Guardian as a Python package using the Strands Agents SDK. Each of the seven agent tools is registered via the @tool decorator, allowing the Bedrock-hosted LLM to autonomously decide which tools to invoke and in what sequence. The agent receives a natural-language prompt and runs the full pipeline without human intervention — only surfacing when a P1 finding demands a real decision.
The architecture is modular: tools live in src/strands_guardian/tools/, geo feed ingestors in feeds/, data models in models/, and shared utilities (haversine distance, timed cache with configurable TTL) in utils/. Every tool has both a live implementation (hitting real APIs via httpx async clients) and a mock fallback, so the project runs end-to-end with zero API keys for demo and CI purposes.
The agent integration uses Strands' Agent class with a detailed system prompt that defines the operating procedure, tool descriptions, and decision rules. When the Strands SDK is not installed, the project gracefully falls back to a standalone pipeline mode that exercises the same tools in a deterministic sequence — this is what powers the demo video.
We generated the demo video and architecture diagram programmatically using Pillow and FFmpeg, keeping all assets reproducible from Python scripts in the repository.
text
User: "Monitor grid assets in the Southeast US" ↓ Strands Agent (Bedrock Claude) — autonomous loop ↓ ├─ discover_ics_assets(region="Southeast US") │ → 5 exposed ICS endpoints │ ├─ For EACH asset: │ ├─ search_threat_intel(asset) │ ├─ map_mitre_attack(protocol) │ ├─ check_cisa_kev(vendor, product) │ └─ get_geo_events(lat, lon, radius=200mi) │ → haversine distance + compass bearing │ ├─ Agent synthesizes → generate_dossier() │ └─ If P1 → send_alert(Slack/webhook) Challenges we ran into Cross-border geo-awareness. Early on we realized that a simple radius query would miss threats originating in Canada or Mexico. We implemented haversine distance calculations with compass bearings so that a GDACS disaster alert 50km north of the US border correctly registers as a proximate threat to nearby American grid assets. The bearing label (N, NE, E, etc.) gives analysts instant spatial intuition without needing to visualize a map.
API resilience and graceful degradation. Live OSINT APIs have rate limits, downtime, and varying response formats. We built a primary/fallback chain (SerpApi → Tavily) and designed every tool to operate in mock mode when keys are absent. The agent produces identical-quality output in mock mode, making it possible to demo the full pipeline without configuring a single credential.
Strands SDK availability. The Strands Agents SDK is a new library, and we needed the project to be functional even without it installed. We built a dual-mode architecture: when Strands is available, the LLM autonomously orchestrates tools; when it's not, a deterministic standalone pipeline exercises the same code. This also serves as a natural test harness.
Priority scoring calibration. Translating multi-dimensional threat data into a single P1/P2/P3 score required careful weighting. A CISA KEV match with known ransomware use should always trigger P1, regardless of other factors. We iterated on the scoring formula until mock scenarios produced analyst-validated priorities.
Accomplishments that we're proud of Zero-config demo: Clone the repo, run pip install -e . and strands-guardian "Monitor the Southeast US", and see the full pipeline — 5 assets discovered, analyzed, geo-fused, and dossiers generated — with no API keys required. Seven production-grade agent tools: Each tool has a live implementation, mock fallback, comprehensive docstrings, and returns structured data that the agent (or pipeline) can reason over. The tool registry is the entire product surface. Cross-border geo-fusion: The haversine + bearing system treats North America as a single threat landscape, correctly flagging threats that cross national boundaries — something most ICS monitoring tools simply ignore. SOC-ready output: Generated dossiers include dated citations, confidence-scored ATT&CK mappings, CISA KEV cross-references with ransomware flags, and proximity-aware geo-events — everything an analyst needs in one document. Reproducible assets: The thumbnail, architecture diagram, and demo video are all generated from Python scripts in the repo, making them easy to update or regenerate for future iterations. What we learned Strands SDK makes agent orchestration elegant. The @tool decorator pattern is remarkably clean — wrapping an async function with @tool and letting the LLM decide when to call it removes an entire class of workflow boilerplate. The system prompt effectively becomes the architecture. Mock data must be realistic to be useful. Our first pass at mock data used obviously fake IPs and generic threat descriptions. Demo viewers tuned out. When we switched to realistic protocol fingerprints (actual ICS vendors, products, firmware versions) and plausible threat headlines (referencing real APT groups, real CVE patterns), the demo became immediately compelling. Geo-context is the multiplier. An exposed Modbus TCP device is a routine finding. An exposed Modbus TCP device 40km from an active wildfire with FRP=187 during a Volt Typhoon campaign alert — that's a P1. Layering real-time geo-events onto asset data transformed our priority scoring from theoretical to genuinely actionable. SOC analysts need citations, not AI confidence. Early dossier drafts had AI-generated summaries without source links. Every analyst who reviewed them asked the same question: "Where did this come from?" We learned to front-load dates, URLs, and source names — "SerpApi, 2026-08-15" beats "AI analysis says" every time. What's next for Strands Guardian Bedrock AgentCore deployment: Deploy the agent on Amazon Bedrock AgentCore for production-grade orchestration with managed scaling and observability. STIX 2.1 bidirectional ingest: Currently we generate STIX output; next we'll import STIX/TAXII threat feeds so external intelligence automatically enriches asset dossiers. Watchlist diffing: Snapshot the exposed-asset landscape daily and alert on new ICS exposures appearing on the grid, turning the tool from reactive analysis into proactive monitoring. ATT&CK Navigator layers: Generate downloadable layer files per asset so analysts can overlay findings onto the official MITRE Navigator tool for visual correlation. Multi-country expansion: The architecture is geo-aware by design. Extending beyond country_code: US to NATO ally grids is primarily a policy decision, not an engineering one.
Built With
- ai-agent
- amazon-bedrock
- bacnet
- censys-api
- cisa-kev
- claude
- dnp3
- ethernet-ip
- geo-event-fusion
- haversine
- httpx
- ics-scada
- iec-104
- mitre-attack
- modbus-tcp
- osint
- python
- serpapi
- siemens-s7
- soc-automation
- stix-2.1
- strands-agents-sdk
- tavily
- threat-intelligence

Log in or sign up for Devpost to join the conversation.