System Architecture Overview¶
Bedrock is a tactical situational-awareness system: operators and devices share position, chat, drawings, and voice over a resilient routed data plane, with cryptographic identity and classification enforcement. It is 8 independent git repos (no umbrella monorepo).
The repos¶
| Repo | Language | Role |
|---|---|---|
directory |
TypeScript (AdonisJS) | Identity authority — FIDO2 login, signs IdentityToken/ServerToken, issues group keys, publishes the revocation list. The root of trust. |
common |
Rust (waypoint_common) |
Canonical shared crate — AuthEnvelope pack/verify, token protos, SIDC parser, outbox policy. The contract every client/server mirrors. |
server |
Rust (waypoint node) |
Content-blind Zenoh Relay + Storage — routes LIVE traffic under a closed ACL and validates retained ingest/replay under Directory authority. |
android |
Kotlin | Tactical client — engine + Zenoh transport + MapLibre map UI. |
web |
TypeScript (AdonisJS + Inertia) | COP / decision-support browser client — Zenoh-over-WSS, server-side recorder tier. Hosts the targeting board, detections, client-side track fusion (server-side fusion deferred), EW/control-measure authoring, planning (estimate/sync matrix/comms-net/versioning/replay export), and the /api/feed/* force-tracking ingest API. |
node |
Rust | Headless GPS / sensor daemon — position/heartbeat publisher through one configured TLS/QUIC router. |
gateway |
Rust | Interop bridge — translates to/from CoT/TAK, ADatP-3, NFFI, etc. |
infrastructure |
Ansible | On-prem rack provisioning + PKI/TLS for deployments. |
The PETRA 1.0 Server is a statically provisioned, content-blind Relay + Storage role. See the normative Zenoh and DDIL data-plane contract for its degraded topologies, opaque addressing, and recovery boundary, and the status roadmap for release evidence.
Expendable does not mean storage-free
The Manifesto's component table calls Server “stateless” as shorthand for having no Core authority or application source of truth. Its longer trust rule requires bounded durable store-and-forward. A Server may be rebuilt or replaced, but while running it persists authorized opaque values only within the offline horizon and remains content-blind, group-key-free, and unable to mint authority.
Feed ingestion is handled by an additional component, bedrock-nifi-processors (Apache
NiFi), which is not one of the 8 core repos but produces feed data into web: it normalises
external AIS / ADS-B / GeoJSON feeds and writes them into the track_hits Postgres table via
the least-privilege nifi_ingest role, from where web fans them out to the COP.
How they fit¶
flowchart TB
DIR["<b>directory</b><br/>identity authority"]
COMMON["<b>common</b><br/>canonical contract<br/>(compiled by all)"]
subgraph clients [ ]
direction LR
AND["android"]
WEB["web"]
NODE["node<br/>(GPS daemon)"]
end
R1["<b>server</b><br/>router A"]
R2["<b>server</b><br/>router B"]
GW["gateway"]
EXT["CoT/TAK, ADatP-3,<br/>NFFI … (external)"]
NIFI["<b>NiFi</b><br/>(bedrock-nifi-<br/>processors)"]
FEEDS["AIS / ADS-B /<br/>GeoJSON feeds<br/>(external)"]
PROD["force-tracking<br/>producers (external)"]
DIR -->|"FIDO2 login, tokens,<br/>group key, revocations · HTTPS"| AND
DIR --> WEB
DIR --> NODE
AND <-->|"Zenoh TLS"| R1
WEB <-->|"Zenoh WSS"| R1
NODE <-->|"configured Zenoh TLS/QUIC"| R1
R1 <-->|"gossip / private-CA TLS"| R2
R1 --> GW --> EXT
FEEDS -->|"AIS/ADS-B/GeoJSON"| NIFI
NIFI -->|"INSERT track_hits<br/>(nifi_ingest role)"| WEB
PROD -->|"/api/feed/* · JWT"| WEB
COMMON -.->|contract| AND
COMMON -.-> WEB
COMMON -.-> NODE
COMMON -.-> R1
COMMON -.-> R2
COMMON -.-> GW
End-to-end flow¶
- Login (HTTPS → Directory). Operator authenticates with a FIDO2 assertion (devices
use a single-use registration token). The Directory returns a 5×7-day
IdentityTokenbatch and the device's Ed25519 signing key (public half =principal_sign_keyin the token). Seesecurity/pki.md. - Connect (Zenoh). The client opens a configured TLS or QUIC Zenoh session, obtains the
endpoint-local Directory-signed
ServerTokenfrom the closed router-token control family, and binds that token to the selected endpoint before any application publish, subscription, or retained query. The token carries the router identity, classification ceiling, coverage cells, and replay-receipt public key. Group keys come from/api/group-keyand are never delivered by a router. - Send. Each message content is sealed with AES-256-GCM under the deployment group
key (
SealedContent), wrapped in anAuthEnvelope— Ed25519device_signatureover signed-cleartextclassification+owner_principal_idfields plus the sealed payload — andputon a cell-routed key expression (waypoint/<cell>/<topic>/...). Heartbeats remain plaintext. Seeprotocol/wire-protocol.md. - Relay / store. The router applies the required default-deny peer/action/key policy and verifies the generic publication or query authorization. It reads only signed-cleartext metadata needed for the classification and storage gates, durably buffers eligible opaque ciphertext within the offline horizon, and fans it out to subscribers and federated routers. It never decodes application payloads, holds a group key, or interprets ORBAT, membership, ownership, drawing, target, plan, or report semantics.
- Receive. Every receiver runs the full envelope verify + revocation gate before any
DB write or UI event. See
security/model.md. - Interop. The gateway subscribes to the mesh and translates to/from external
tactical formats. See
protocol/interop-standards/. - Feed ingestion (HTTP, into web). Two seams feed external tracks into the web COP:
external AIS / ADS-B / GeoJSON feeds flow through NiFi, which writes them into the
track_hitsPostgres table (least-privilegenifi_ingestrole); and external force-tracking producers post to/api/feed/*authenticated by a signed HS256 JWT (API credential). Web then fans the tracks out to operators and applies client-side track fusion (server-sidefused_tracksis deferred). Seeprotocol/ingest-api.md.
Where each concern is documented¶
- Identity / authenticity / revocation →
security/model.md - Trust roots, tokens, key issuance →
security/pki.md - Wire format, namespace, handshake →
protocol/wire-protocol.md - PETRA 1.0 Zenoh roles, DDIL, and opaque addressing →
zenoh-ddil-data-plane.md - Bearer-neutral Android and mobile-rack connectivity →
bearer-neutral-connectivity.md - Post-horizon authoritative state recovery →
protocol/authoritative-snapshots.md - Store-and-forward outbox →
protocol/outbox.md - Interop / symbology standards →
protocol/interop-standards/ - Operator workflows (onboard, revoke, create server, rotate keys) →
training/ - Term definitions →
glossary.md
Note: identity is token-only — the Directory's Ed25519 signature over the token, with no per-app X.509 client certificate (see
pki.md). Member content is AES-256-GCM sealed under the deployment group key before it enters the envelope (server-blind E2E confidentiality); the router is payload-blind and group-key-free. This is live and uniform across all clients (android, web, node, gateway) — only heartbeats travel plaintext, and there is no plaintext-content fallback. Seesecurity/model.mdandarchitecture/status-roadmap.md.