ORP is a single 45 MB Rust binary that ingests AIS, ADS-B, MAVLink, OPC-UA, MQTT, Modbus, Zeek, syslog, GRIB, CoT, KLV (MISB ST 0601), CCSDS+SGP4, HL7 v2.5, Kafka, NATS and 25 more protocols into one queryable real-time graph — with an ORP-QL query language, mTLS-secured federation mesh, Ed25519-signed tamper-evident audit log, OIDC JWKS verification (RS256/ES256), Argon2id keystore, and a built-in COP map. No JVM. No Postgres. No Kubernetes. Just ./orp start and you're ingesting in 30 seconds. The slot it fills: the new SQLite/Postgres for real-time multi-source backends — but military-grade out of the box.
🎬 Demo GIF coming with the first tagged release. Until then — the transcript:
$ orp doctor
✓ protoc on PATH found
✓ DuckDB writable ok at ./data.duckdb
✓ RocksDB writable ok at ./state.db (parent directory writable)
✓ Server port free :9090 is bindable
✓ Config validation no config.yaml found — defaults will be used
✓ Cert chain validity skipped — pass --https-url to test
✓ ready — run `orp start --template maritime`.
$ orp start --template maritime
INFO Initializing DuckDB storage at ./data.duckdb
INFO 🌍 Connecting to AISStream.io — live global AIS data
INFO Starting HTTP server on 0.0.0.0:9090
INFO Dashboard: http://localhost:9090/
$ orp query "MATCH (s:ship) WHERE s.speed > 25 RETURN s.name, s.speed LIMIT 5"
╭───────────────┬───────╮
│ s.name │ speed │
├───────────────┼───────┤
│ MSC ARIES │ 28.4 │
│ EVER GIVEN │ 25.2 │
╰───────────────┴───────╯
2 rows in 4.3ms
A new shape of system needs a new comparison set. ORP is not a database, not a SCADA, not a SIEM — it's a single-binary fusion engine that absorbs all of those into one queryable graph.
| SQLite | Postgres | Lattice OS | Maven OS / Anduril | ORP | |
|---|---|---|---|---|---|
| Single binary, no daemons | ✅ | ❌ | ❌ | ❌ | ✅ |
| Embeddable in another process | ✅ | ❌ | ❌ | ✅ (via orp-core crate) | |
| First-class real-time ingest | ❌ | ❌ partial (LISTEN/NOTIFY) | ✅ | ✅ | ✅ (50k events/s) |
| Protocol adapters out of the box | 0 | 0 | proprietary | proprietary | 39 open |
| Graph query language | ❌ | extensions only | proprietary | proprietary | ORP-QL (open) |
| Live federation mesh | ❌ | logical replication only | ✅ closed | ✅ closed | ✅ open |
| Edge / Raspberry Pi capable | ✅ | ❌ | ❌ | ✅ 45 MB, ARM64 | |
| Built-in COP / map UI | ❌ | ❌ | ✅ | ✅ | ✅ |
| License | public domain | PostgreSQL | proprietary | proprietary | Apache 2.0 |
| Cost | free | free | undisclosed (8-figure deals) | undisclosed | free |
The pitch in one sentence: SQLite-style "single binary, zero config" pushed up the stack to where Lattice OS / Maven OS / Palantir AIP currently live.
# Install (works after the first tagged release — see "Building from Source" until then)
curl -fsSL https://raw.githubusercontent.com/shieldofsteel/orp/master/scripts/install.sh | sh
# Or build from source:
git clone https://github.com/shieldofsteel/orp && cd orp
brew install protobuf # or: apt install -y protobuf-compiler
cargo build --release
# Diagnose the host first
./target/release/orp doctor
# Launch with the maritime template
./target/release/orp start --template maritime
# Ships appear on your screen in 30 seconds — open http://localhost:9090That's it. No YAML sprawl. No microservices. No Kubernetes. One process, one port, everything included.
For the 10-minute "from zero to ingesting your own data" tour, see docs/QUICKSTART.md. For copy-paste recipes (AIS, ADS-B, MAVLink, Modbus, Zeek, audit-log export, federation, continuous alerts), see docs/RECIPES.md.
Fuses data from any source — 39 protocol adapters, a universal JSON ingest endpoint, and a connector SDK. If it outputs data, ORP can consume it.
Builds a live knowledge graph — every entity (ship, aircraft, vehicle, sensor, threat) becomes a node. Relationships auto-form. The graph updates in real time.
Relays real-time media sources — register RTSP/RTMP/HLS/MJPEG/WebRTC/SRT/ONVIF/KLV camera streams, relay HTTP/JPEG/MJPEG/HLS streams in-binary, validate risky LAN URLs explicitly, redact embedded credentials, and project every stream into the graph as a media_stream. See docs/MEDIA.md.
Renders a military-grade COP — a full-featured map with 4 tile layers, directional arrows, course vectors, lasso select, and a timeline scrubber. Not a dashboard — an operational picture.
Lets you query anything — ORP-QL is a purpose-built query language combining SQL analytics with Cypher-style graph traversal. Query across sensors, entities, and time.
Alerts you before it matters — anomaly detection and threat scoring run continuously. When a ship deviates from its pattern-of-life, you know.
Runs anywhere — a laptop, a Raspberry Pi, a warship, a data center. --headless for embedded deployments. Docker for cloud. ARM binaries for edge.
ORP ships with the cryptographic primitives a defense / federal procurement reviewer expects, all in the single binary, all configurable via flags or env vars:
| Capability | What it does | How to turn on |
|---|---|---|
| Inbound TLS | axum-server + rustls (no native-tls / openssl) terminates HTTPS for the REST + WebSocket API. |
--tls-cert <pem> --tls-key <pem> (or orp gen-cert for dev). |
| Inbound mTLS | Optional client-cert auth — server requires every caller to present a cert signed by your CA. | --tls-client-ca <pem> |
| HSTS | Strict-Transport-Security: max-age=31536000 when TLS is active. |
Automatic when --tls-cert is set. |
| Federation mTLS | Dedicated rustls listener on a separate port (default 9443) requires connecting peers to present a client cert signed by the federation CA. | --federation-tls --federation-cert/key/ca <pem> |
| Federation Ed25519 signing | Each federated payload carries a signature over (timestamp || peer_id || canonical_json(payload)); receivers verify against the sending peer's pinned pubkey. |
--federation-signing-key <pem> and per-peer signing_pubkey in config. |
| Federation replay protection | Per-peer monotonic sequence numbers; receiver rejects seq <= last_seen. |
Automatic with federation TLS. |
| Federation confidence cap | Receiver clamps incoming confidence to a per-peer max (default 0.9) so a compromised peer can't overwrite truth-of-record. |
peers[].max_confidence_cap in config. |
| OIDC JWKS verification | Real RS256 / ES256 verification of JWTs against discovery.jwks_uri; caches the JWKS with TTL + refresh-on-kid-miss; multi-IdP routing by iss. |
oidc.providers[] in config (Keycloak, Auth0, Okta, Azure AD). |
| Argon2id API key store | OWASP-2023 floor (m=19 MiB, t=2, p=1), PHC strings, persisted to a separate *-auth.duckdb file with last_used_at + revoke. |
--bootstrap-admin-key on first start, then orp api-keys subcommands. |
| Argon2id password hashing | Same floor, fresh OsRng salt per call, PHC strings (no SHA-256 / no thread_rng). |
Active when the user-management module is wired. |
| Signed audit log | Every state change is Ed25519-signed and chained (each entry signs prev_hash); chain is replayed on startup; audit verify and audit export CLI subcommands let an external auditor prove tamper-evidence without ORP running. |
Default on for persistent storage; audit export --out audit.jsonl --public-key <hex>. |
| SSRF defence | Outbound HTTP from notification webhooks (Webhook/Slack/Telegram), HTTP poller, and OIDC discovery is gated by a validate-then-pin client (rejects loopback / RFC1918 / cloud-metadata addresses unless explicitly opted in). | Automatic; allow_private_targets: true per channel for legitimate localhost integrations. |
| WebSocket identity propagation | JWT sub / permissions / org_id flow through every broadcast event; ABAC sees the real caller (no hardcoded "ws-client"+["admin"]). |
Automatic when JWT or API-key auth is configured. |
| Notification circuit breaker | Per-channel breaker after 5 consecutive failures (5 min cooldown) + ±25% retry jitter via OsRng. |
Automatic; configurable per channel. |
| CSRF cookie | OIDC CSRF state generated via OsRng::fill_bytes(32) → URL-safe base64 (~256 bits of entropy). State cookie is HMAC-SHA256 signed (closed length-extension forgery) and verified with constant-time hmac::Mac::verify_slice. Refuses to issue/verify when enabled=true + client_secret empty (no silent dev-key fallback in production). |
Active when OIDC is configured. |
| Persistent audit signing key | Ed25519 secret + public sidecar at ${XDG_DATA_HOME}/orp/audit-key.{ed25519,pub.ed25519} (mode 0600 / 0644). Atomic publish; sidecar self-heals if the previous run was killed mid-write. Signatures emitted before a restart are verifiable after one. |
Automatic for persistent mode; ephemeral on --in-memory. |
| At-rest envelope encryption | AES-256-GCM seal of the audit-log details column. Wire format {"orpaead1": "<base64>"} — keeps the JSON column type contract, supports mixed-mode (legacy plaintext rows still read). Captured DB file → ciphertext, not PII. |
Set ORP_AT_REST_KEY_PATH or pre-create ${XDG_DATA_HOME}/orp/at-rest.key (32 raw bytes, 0600). |
| SMTP STARTTLS / TLS-465 | lettre 0.11 with rustls + ring + webpki-roots. Implicit TLS on 465, STARTTLS upgrade on every other port. AUTH LOGIN now runs over the encrypted channel (no more cleartext credentials). |
Automatic per smtp_port selection. |
| Sanctions list signature verification | Detached Ed25519 sig (<path>.sig, 64 raw bytes) verified before parsing. Pinned pubkey is enforced on every reload so a disk-writeable attacker cannot swap the file post-load. |
SanctionsDatabase::load_signed(path, &pubkey). |
| CycloneDX 1.5 SBOM + cosign | Release CI emits bom.cdx.json and signs every artifact (binaries, SBOM, checksums) with sigstore cosign keyless OIDC (Fulcio + Rekor). Satisfies SLSA-3 provenance for federal RFPs. |
Automatic on tag push (.github/workflows/release.yml). |
| Multi-domain classification labels | orp_security::Classification (U / CUI / NR / C / NC / S / NS / TS / CTS + SCI compartments + dissem controls + ATOMAL) with CAPCO banner() + dominates() ABAC predicate. Wire-level OrpEvent.classification proto field + optional X-Classification HTTP response header banner. |
ORP_CLASSIFICATION_BANNER="TOP SECRET//SI//NOFORN" env var enables the header. |
Closed in v0.3.0 (from the project's own audit reports):
- ✅ Federation has TLS + payload integrity (was plain HTTP, no peer auth)
- ✅ Inbound HTTP supports TLS (was
axum::serveon plain TCP) - ✅ OIDC verifies external JWTs against the IdP's JWKS (was discovered-then-ignored)
- ✅ Notifications no longer SSRF (was missing the guard
http_pollergot) - ✅ WebSocket no longer hands every JWT holder admin events (was discarding claims)
- ✅ API keys + passwords use Argon2id (was unsalted SHA-256)
Closed in v0.3.1 (media relay hardening + Wave 2 P-audit small):
- ✅ Media relay DELETE cancels in-flight relays (CancellationToken)
- ✅ Media relay slow-loris closed (process-wide Semaphore, 60s idle timeout, 4 GiB session cap)
- ✅ Media relay IPv4-mapped IPv6 SSRF (
[::ffff:127.0.0.1]rejected) - ✅ HLS rewriter covers every spec'd attribute-bearing tag (
EXT-X-{KEY,MAP,SESSION-KEY,MEDIA,PRELOAD-HINT,PART,RENDITION-REPORT}) - ✅ HLS userinfo smuggling rejected; playlist body capped at 1 MiB; per-id handler
validate_id()guards - ✅ Persistent audit signing key (F2)
- ✅ Sanctions list signature verification (F8)
- ✅ TLS backend unified on rustls (F9 —
orp-connectorflipped reqwest + tokio-tungstenite to rustls-tls) - ✅ CycloneDX 1.5 SBOM + cosign keyless signing
- ✅ Multi-domain classification scaffolding (
U/CUI/NR/C/NC/S/NS/TS/CTS+ SCI + dissem + ATOMAL) - ✅ TAK Protocol v1 wire codec — first Rust crate (
orp-tak) - ✅ Persistent audit chain Linux-CI fix (DuckDB ns→µs precision)
- ✅ Resolver→AuditLogger plumbing (entity-match feedback in the signed chain)
Closed in v0.3.2 (full integration + remaining Wave 2 P-audit + crypto-audit follow-ups):
- ✅ CSRF HMAC + constant-time verify (F5)
- ✅ SMTP STARTTLS via lettre — credentials no longer cleartext (F6)
- ✅ At-rest envelope encryption for audit-log
details(F7) - ✅ Sanctions reload re-verifies pinned pubkey — closes the F8 reload bypass
- ✅ Audit-key public sidecar self-heals after partial-write crash
- ✅ CSRF refuses to issue cookie when
enabled=true+client_secretempty (no silent dev-key fallback) - ✅
orp-takwired intoorp-connector::adapters::cot— accepts both UDP mesh (tak://) and TCP stream (tak-tcp://) framings, falls through to plainudp://for legacy ATAK - ✅
OrpEvent.classification+Entity.classificationproto fields - ✅
X-Classificationresponse header middleware (env-driven)
Pending v0.4 hardening: full DuckDB encryption-extension support (whole-file rather than per-column), RocksDB EncryptedEnv wrapping, FIPS-mode build, ABAC dominance enforcement on classification (currently advisory).
Full audit history: docs/SECURITY.md · docs/TLS.md · docs/OIDC.md · docs/FEDERATION_TLS.md
ORP speaks the languages your sensors already use. 39 protocol adapters across:
- Maritime — NMEA 0183, AIS (msg types 1–5, 9, 18, 27), AISStream, NMEA 2000, ACARS
- Aviation — ADS-B / Mode S, ASTERIX, GRIB (Section 7 unpacking incl. simple/grid/CCSDS), METAR
- Drone autonomy — MAVLink v2 (heartbeat, global_position_int, attitude, status_text, battery, GPS_RAW)
- Space — CCSDS + SGP4 (TLE-based orbit propagation)
- Military / tactical / ISR — CoT (bidirectional, TAK Server compatible), TAK Protocol v1 wire codec (UDP mesh
0xBF/01/0xBF+ TCP stream length-prefixed — first Rust implementation;tak://andtak-tcp://URL schemes plug straight into the CoT adapter), STIX/TAXII, NFFI (STANAG 5527), CEF, MISB ST 0601 KLV (tags 1–25, video metadata) - Real-time media relay — in-binary HTTP/JPEG/MJPEG/HLS relay plus stream registration for RTSP, RTMP, WebRTC/WHEP, SRT, ONVIF, V4L2/USB, file, raw KLV, and KLV-in-MPEG-TS
- Industrial / IoT — OPC-UA, Modbus TCP/RTU, MQTT, SparkplugB, DNP3, CAN/J1939, BACnet, LoRaWAN
- Cyber / network — Syslog (RFC 3164/5424), PCAP, Zeek, NetFlow / IPFIX
- Streaming / messaging — Apache Kafka (feature-gated), NATS / JetStream (feature-gated)
- Healthcare — HL7 v2.5 over MLLP
- Civic / disaster — CAP (Common Alerting Protocol), GTFS-RT
- Universal — HTTP poller (with SSRF guard + DNS-rebinding pinning), WebSocket client, CSV watcher, Database tail, GeoJSON, generic JSON API
Full per-protocol detail and status table → docs/PROTOCOLS.md (generated from the adapters list — see also crates/orp-connector/src/adapters/).
Don't see your protocol? The connector SDK is ~50 lines of Rust. Build one →
┌─────────────────────────────────────────────────────────────────────┐
│ ORP SINGLE BINARY │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌─────────────────────────┐ │
│ │ CONNECTORS │ │ FUSION │ │ QUERY ENGINE │ │
│ │ │ │ ENGINE │ │ │ │
│ │ NMEA/AIS │──▶│ │──▶│ ORP-QL │ │
│ │ ADS-B │ │ Entity │ │ (SQL + Graph hybrid) │ │
│ │ CoT / TAK │ │ Resolution │ │ │ │
│ │ OPC-UA │ │ │ │ DuckDB (analytics) │ │
│ │ MQTT │ │ Knowledge │ │ Graph projection (DuckDB) │ │
│ │ Modbus │ │ Graph │ │ │ │
│ │ Syslog │ │ │ └─────────────────────────┘ │
│ │ HTTP/WS │ │ Anomaly │ │
│ │ CSV / DB │ │ Detection │ ┌─────────────────────────┐ │
│ │ + 9 more │ │ │ │ API & REALTIME │ │
│ └──────────────┘ │ Threat │──▶│ │ │
│ │ Scoring │ │ REST API (v1) │ │
│ ┌──────────────┐ │ │ │ WebSocket (live push) │ │
│ │ FEDERATION │ │ ABAC + │ │ ORP-to-ORP mesh sync │ │
│ │ │──▶│ Ed25519 │ └─────────────────────────┘ │
│ │ Peer ORPs │ │ Signing │ │
│ │ (mesh sync) │ └──────────────┘ ┌─────────────────────────┐ │
│ └──────────────┘ │ WEB UI │ │
│ │ Map (4 tile layers) │ │
│ ┌──────────────┐ │ Dashboard │ │
│ │ STORAGE │ │ Entity Inspector │ │
│ │ │ │ Query Console │ │
│ │ DuckDB │ │ Search Panel │ │
│ │ (entities, │ │ Alert Feed │ │
│ │ history) │ │ Timeline Scrubber │ │
│ │ Graph proj. │ └─────────────────────────┘ │
│ │ (in-DuckDB) │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Full architecture deep dive → ARCHITECTURE.md.
Runnable demos, each with its own README.md and run.sh:
| Example | Shows |
|---|---|
examples/quickstart-ais/ |
Universal-ingest API + ORP-QL with a sample AIS dataset (no internet needed). |
examples/two-node-federation/ |
Two ORP nodes peered together; data on one shows up on the other. |
examples/saved-queries/ |
A directory of .orpql files loaded as saved queries and monitor rules. |
examples/adapter-config/ |
Annotated config.yaml with 6 adapters configured side-by-side. |
cd examples/quickstart-ais && ./run.sh- docs/QUICKSTART.md — 10-minute tour: install → ingest → query → connect a real adapter → federate.
- docs/RECIPES.md — copy-paste recipes for the most common tasks.
- docs/CONFIG.md — every config field, env var, and CLI flag.
- docs/CLI_REFERENCE.md — every
orpsubcommand. - docs/ORP_QL_GUIDE.md — the query language.
- docs/CONNECTOR_GUIDE.md — write your own adapter in ~50 lines.
- docs/API_REFERENCE.md — REST + WebSocket reference.
- docs/SECURITY.md — OIDC, ABAC, Ed25519 audit log.
- ARCHITECTURE.md — component-by-component deep dive.
- CHANGELOG.md — what landed when.
ORP ships a criterion-based benchmark suite that covers the parser, storage, stream-processor, and query hot paths.
cargo bench --workspace # full suite (~5–10 min)
cargo bench -p orp-connector # parser benches only (~1–2 min)
cargo bench -p orp-storage # DuckDB write/query benches- Post-v0.2.0 baseline numbers:
benches/baseline.md. - CI policy + how to add new benches:
docs/BENCHES.md. - Criterion HTML reports land in
target/criterion/report/index.html.
Benchmarks are dev-only — criterion lives in [dev-dependencies], so the release binary stays single-binary.
| Dependency | Required | Version | Purpose |
|---|---|---|---|
| Rust toolchain | yes | 1.75+ (stable) | Compile core binary |
protoc |
yes | 3.20+ | orp-proto/build.rs compiles protobuf event schemas |
| Node.js | optional | 20+ | Build the React frontend (omit for --headless builds) |
| Docker | optional | any | Containerized deploy via the provided Dockerfile |
cmake, pkg-config |
yes (Linux) | system | Native deps for duckdb, rocksdb, rustls |
# 1. Install protoc + native deps
# macOS: brew install protobuf
# Debian/Ubuntu: sudo apt install -y protobuf-compiler cmake pkg-config libssl-dev
# Fedora: sudo dnf install -y protobuf-compiler cmake openssl-devel
# Arch: sudo pacman -S protobuf cmake pkgconf openssl
# 2. Install Rust 1.75+ (skip if already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# 3. Clone and build
git clone https://github.com/shieldofsteel/orp
cd orp
cargo test --workspace # 1,362 tests
cargo build --release # target/release/orp (~45 MB, statically linked)
# 4. Cross-compile for Raspberry Pi (ARM64)
rustup target add aarch64-unknown-linux-gnu
cargo build --release --target aarch64-unknown-linux-gnu
# 5. Docker
docker build -t orp .
docker run -p 9090:9090 orp start --template maritime
# 5a. Distroless image (recommended for production)
docker build -t orp:distroless --target distroless .
docker run -p 9090:9090 orp:distroless --template maritimeThe distroless target is the recommended production image. It is built
from gcr.io/distroless/cc-debian12:nonroot: smaller than the Debian-slim
runtime, has no shell or package manager (so an attacker who lands a code
execution can't sh, apt, curl, etc.), and always runs as the pre-baked
nonroot user (uid/gid 65532) — --user 0:0 is not allowed.
| TAK Server | FreeTAKServer | Palantir | ORP | |
|---|---|---|---|---|
| Open source | Restricted GOSS | EPL | ❌ | Apache 2.0 |
| Modern web UI | ❌ Android-first | ❌ | ✅ | ✅ |
| Maritime domain | Minimal | Minimal | Limited | First-class |
| Aviation domain | ❌ | ❌ | Limited | ✅ ADS-B, ASTERIX |
| Protocol parsers | CoT only | CoT only | Proprietary | 39 open adapters |
| Multi-tenant SaaS | ❌ | ❌ | ✅ | ✅ |
| AI/anomaly detection | ❌ | ❌ | ✅ | ✅ |
| Edge / Raspberry Pi | ❌ | ❌ | ✅ 45MB, headless | |
| Query language | ❌ | ❌ | Proprietary | ORP-QL (open) |
| Federation mesh | Limited | Limited | ✅ | ✅ |
| Cost | Free | Free | $50–500M | Free |
ORP is early. The protocol universe is large. Help is welcome.
Highest-impact contributions:
- New protocol adapters — See docs/CONNECTOR_GUIDE.md — a basic adapter is ~50 lines of Rust. Wishlist: ROS 2 / DDS, IEC 61850, ARINC 429, SAE J2735, Link 16 (J-series via JREAP), STANAG 4586. Already shipped: MISB ST 0601 KLV, Apache Kafka, NATS, CCSDS+SGP4, HL7 v2.5, MAVLink v2.
- Test coverage — 1,362 tests and growing. More protocol parsing tests, more edge cases, more fuzz harnesses on parser adapters welcome.
- Frontend features — React/TypeScript. See frontend/src/components/.
- Documentation — real-world deployment guides, integration recipes.
- Performance — benchmarks, profiling, optimization.
# Run tests
cargo test
# Check lints (must be zero warnings)
cargo clippy -- -D warnings
# Format
cargo fmt
# Run a specific adapter test
cargo test -p orp-connector nmeaIssues are tracked on GitHub. PRs welcome. No CLA required.
Apache 2.0 — see LICENSE.
Use it commercially. Fork it. Embed it in products. Build a business on it. The only thing you can't do is sue us for patent infringement using patents you contributed.
ORP — single-binary, single-port, every-protocol — because operational awareness shouldn't cost $50M.