astrate

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2026 License: Apache-2.0

README

Astrate

Astrate is a lean, single-binary re-implementation of the Astarte IoT platform in Go: a modular monolith (pairing, MQTT ingestion, engine, REST APIs in one process) backed by PostgreSQL + TimescaleDB, with an embedded MQTT broker — built to stay wire-compatible with the official Astarte device SDKs while running comfortably on a 1–2 GB VPS or at the edge, with no Kubernetes and no Cassandra. Alongside Astarte's BSON payloads it natively accepts a documented plain-JSON profile for ultra-constrained clients (e.g. AtomVM devices).

Status

Pre-release, under active milestone-driven development. The architecture and plan are frozen in:

  • docs/DESIGN.md — architectural design (service mapping, data model, wire compatibility, security/pairing)
  • docs/ROADMAP.md — milestones M0–M9, verification tiers, SDK conformance checkpoints
  • docs/OPERATIONS.md — running Astrate: configuration, deployment profiles, backups, and the CA re-keying runbook

Quick start (docker compose)

Brings up TimescaleDB and Astrate (development profile: plaintext MQTT, self-signed broker cert, a throwaway master key — see docs/OPERATIONS.md before exposing it):

docker compose --profile full up -d --build
curl localhost:8080/astrate/v1/readiness        # {"status":"ok",...}
curl localhost:8080/astrate/v1/metrics          # Prometheus metrics

Configure everything from one TOML file or ASTRATE_* environment variables; see internal/config/config.example.toml for the annotated reference. Only the database DSN and (outside dev mode) the broker TLS files are required.

astrate -config /etc/astrate/astrate.toml       # file
ASTRATE_DATABASE_DSN=postgres://… astrate        # env-only

On a bare VPS, run apt install postgresql-16 timescaledb, then the single static astrate binary — no Kubernetes, no Cassandra. See docs/OPERATIONS.md.

Development

Requires Go (see go.mod) and Docker (for integration tests).

make tools             # install pinned dev tooling (golangci-lint)
make build             # static compile -> dist/astrate
make lint test         # T1: lint + unit tests
make test-integration  # T2: tests against a TimescaleDB container
make up                # local TimescaleDB only (fast T2 iteration)

License

This project is licensed under a Modified Apache 2.0 License (Source-Available).

It grants all rights standard to the Apache 2.0 License, with the express exclusion of SECO S.p.A., its subsidiaries, affiliates, contractors, and partners acting on its behalf. See the LICENSE file for the full legal text and restriction terms.

Note that this is not an OSI-approved open source licence: the exclusion clause discriminates against a specific entity, which the Open Source Definition does not permit. Choose dependencies and downstream usage accordingly.

Trademarks

"AtomVM" is a trademark/project of Davide Bettio (github.com/bettio, github.com/atomvm/AtomVM). "Clea Astarte" and other Clea-branded names mentioned in this project's documentation belong to SECO S.p.A. Mentions here are references made in the context of protocol/API compatibility, not claims of affiliation, endorsement, or ownership.

Directories

Path Synopsis
cmd
astrate command
Command astrate is the single Astrate binary (docs/ROADMAP.md §9 file 8.4): it wires the store, ingestion engine, embedded MQTT broker, pairing, the M7 REST surfaces, and the observability endpoints into one process driven by one TOML config, with signal-driven graceful shutdown.
Command astrate is the single Astrate binary (docs/ROADMAP.md §9 file 8.4): it wires the store, ingestion engine, embedded MQTT broker, pairing, the M7 REST surfaces, and the observability endpoints into one process driven by one TOML config, with signal-driven graceful shutdown.
Package docs embeds the Swagger UI static files and OpenAPI YAML specs so they are served directly from the astrate binary without external files.
Package docs embeds the Swagger UI static files and OpenAPI YAML specs so they are served directly from the astrate binary without external files.
examples
flow-container-echo command
Minimal Astrate Flow container contract: POST /v1/message with a Message JSON body and echo it back (or drop on empty array / 204).
Minimal Astrate Flow container contract: POST /v1/message with a Message JSON body and echo it back (or drop on empty array / 204).
internal
appengine
Package appengine is the AppEngine API (docs/DESIGN.md §3.7, ROADMAP §8.2): the operator/application surface for device status, interface data queries, server-owned publishing, groups, and the live event socket.
Package appengine is the AppEngine API (docs/DESIGN.md §3.7, ROADMAP §8.2): the operator/application surface for device status, interface data queries, server-owned publishing, groups, and the live event socket.
appengine/channels
Package channels implements the upstream Phoenix Channels V2 wire protocol served at /appengine/v1/socket/websocket.
Package channels implements the upstream Phoenix Channels V2 wire protocol served at /appengine/v1/socket/websocket.
appengine/stream
Package stream is the AppEngine live event socket (docs/DESIGN.md §3.7, §1.1 deviation; ROADMAP §8.2 file 7.9): a WebSocket (with an SSE fallback) at /astrate/v1/{realm}/socket fed by the engine's in-process fan-out bus.
Package stream is the AppEngine live event socket (docs/DESIGN.md §3.7, §1.1 deviation; ROADMAP §8.2 file 7.9): a WebSocket (with an SSE fallback) at /astrate/v1/{realm}/socket fed by the engine's in-process fan-out bus.
auth
Package auth implements the JWT validation and Astarte authorization-claim layer shared by every Astrate REST surface (docs/DESIGN.md §4.2).
Package auth implements the JWT validation and Astarte authorization-claim layer shared by every Astrate REST surface (docs/DESIGN.md §4.2).
broker
Package broker embeds the mochi-mqtt server and gives it Astarte MQTT v1 semantics (docs/DESIGN.md §3.1–§3.4): mTLS device identity with CN = "<realm>/<device_id>", the §3.2 ACL matrix, persistent sessions in a bbolt file (so session_present survives Astrate restarts), device lifecycle bookkeeping, and an inline publishing facade for the engine and AppEngine.
Package broker embeds the mochi-mqtt server and gives it Astarte MQTT v1 semantics (docs/DESIGN.md §3.1–§3.4): mTLS device identity with CN = "<realm>/<device_id>", the §3.2 ACL matrix, persistent sessions in a bbolt file (so session_present survives Astrate restarts), device lifecycle bookkeeping, and an inline publishing facade for the engine and AppEngine.
config
Package config loads Astrate's single TOML configuration file with ASTRATE_* environment overrides (docs/DESIGN.md §5.1, ROADMAP §9 file 8.1).
Package config loads Astrate's single TOML configuration file with ASTRATE_* environment overrides (docs/DESIGN.md §5.1, ROADMAP §9 file 8.1).
engine
Package engine is the heart of Astrate (docs/ROADMAP.md §7): it consumes every accepted device PUBLISH from the broker intake, validates it against the realm's compiled interface schemas (docs/DESIGN.md §2.6), and persists it through per-shard micro-batches with strict per-device ordering and ack-after-commit semantics (docs/DESIGN.md §1.4, §5.3).
Package engine is the heart of Astrate (docs/ROADMAP.md §7): it consumes every accepted device PUBLISH from the broker intake, validates it against the realm's compiled interface schemas (docs/DESIGN.md §2.6), and persists it through per-shard micro-batches with strict per-device ordering and ack-after-commit semantics (docs/DESIGN.md §1.4, §5.3).
engine/forward
Package forward provides Forwarder implementations that deliver non-HTTP trigger actions to downstream systems.
Package forward provides Forwarder implementations that deliver non-HTTP trigger actions to downstream systems.
engine/stream
Package stream is the in-process live fan-out bus (docs/ROADMAP.md §7.2 file 6.13, docs/DESIGN.md §1.1): the engine publishes every committed data operation and device lifecycle event, and consumers — the M7b WebSocket/SSE endpoint, tests — subscribe per realm with optional filters.
Package stream is the in-process live fan-out bus (docs/ROADMAP.md §7.2 file 6.13, docs/DESIGN.md §1.1): the engine publishes every committed data operation and device lifecycle event, and consumers — the M7b WebSocket/SSE endpoint, tests — subscribe per realm with optional filters.
engine/triggers
Package triggers compiles stored Astarte trigger definitions into fast matchers, renders the upstream-parity SimpleEvent JSON payloads, and executes HTTP webhook actions with retry (docs/ROADMAP.md §7.2 files 6.10–6.12, docs/DESIGN.md §1.1).
Package triggers compiles stored Astarte trigger definitions into fast matchers, renders the upstream-parity SimpleEvent JSON payloads, and executes HTTP webhook actions with retry (docs/ROADMAP.md §7.2 files 6.10–6.12, docs/DESIGN.md §1.1).
flow
Package flow implements stream-based message routing through a block graph, mirroring Astarte Flow's core concepts: messages belong to streams (identified by key), streams are processed in order within a lane, and different streams may interleave across lanes.
Package flow implements stream-based message routing through a block graph, mirroring Astarte Flow's core concepts: messages belong to streams (identified by key), streams are processed in order within a lane, and different streams may interleave across lanes.
flow/blocks
Package blocks registers the built-in Flow block catalog used to instantiate stored pipelines (milestone v2.0: block factory).
Package blocks registers the built-in Flow block catalog used to instantiate stored pipelines (milestone v2.0: block factory).
flow/blocks/astartesource
Package astartesource implements the AstarteSource Flow block (issue #27, astarte_flow parity): a Source that subscribes to Astrate's existing live event bus (internal/engine/stream) and converts device events into FlowMessages, connecting device ingestion to operator-defined pipelines.
Package astartesource implements the AstarteSource Flow block (issue #27, astarte_flow parity): a Source that subscribes to Astrate's existing live event bus (internal/engine/stream) and converts device events into FlowMessages, connecting device ingestion to operator-defined pipelines.
flow/blocks/container
Package container implements the Flow "container" block (Design B / #43 PoC).
Package container implements the Flow "container" block (Design B / #43 PoC).
flow/blocks/virtualdevicepool
Package virtualdevicepool implements the virtual_device_pool block (issue #84): it publishes pipeline messages as registered virtual devices through the engine ingest path — storage rows without MQTT.
Package virtualdevicepool implements the virtual_device_pool block (issue #84): it publishes pipeline messages as registered virtual devices through the engine ingest path — storage rows without MQTT.
flowapi
Package flowapi is the operator-facing Flow surface: realm-scoped pipeline CRUD (store) and named durable flow lifecycle (store + flow.Manager).
Package flowapi is the operator-facing Flow surface: realm-scoped pipeline CRUD (store) and named durable flow lifecycle (store + flow.Manager).
housekeeping
Package housekeeping is the instance-admin Housekeeping API (docs/DESIGN.md §3.7, ROADMAP §8.1 files 7.3–7.4): realm provisioning and teardown, guarded by instance-level JWT keys carrying a_ha.
Package housekeeping is the instance-admin Housekeeping API (docs/DESIGN.md §3.7, ROADMAP §8.1 files 7.3–7.4): realm provisioning and teardown, guarded by instance-level JWT keys carrying a_ha.
httpx
Package httpx holds small protocol-level HTTP middlewares shared across the mounted APIs.
Package httpx holds small protocol-level HTTP middlewares shared across the mounted APIs.
observability
Package observability owns Astrate's Prometheus registry and the health/readiness/metrics HTTP surface under /astrate/v1 (docs/DESIGN.md §5.2).
Package observability owns Astrate's Prometheus registry and the health/readiness/metrics HTTP surface under /astrate/v1 (docs/DESIGN.md §5.2).
pairing
Package pairing implements Astarte's Pairing API surface (docs/DESIGN.md §4.4 flows A–C): device registration with show-once credentials secrets, CSR-based credential issuance through the embedded per-realm CA, broker discovery, and certificate verification — all wire-compatible with upstream so official device SDKs and astartectl run unmodified.
Package pairing implements Astarte's Pairing API surface (docs/DESIGN.md §4.4 flows A–C): device registration with show-once credentials secrets, CSR-based credential issuance through the embedded per-realm CA, broker discovery, and certificate verification — all wire-compatible with upstream so official device SDKs and astartectl run unmodified.
pairing/ca
Package ca implements Astrate's embedded per-realm certificate authority (docs/DESIGN.md §4.3), replacing upstream Astarte's CFSSL sidecar.
Package ca implements Astrate's embedded per-realm certificate authority (docs/DESIGN.md §4.3), replacing upstream Astarte's CFSSL sidecar.
realm
Package realm is the Realm Management API (docs/DESIGN.md §3.7, ROADMAP §8.1 files 7.1–7.2): the operator-facing surface for installing and versioning interfaces, managing triggers, and rotating a realm's JWT auth key.
Package realm is the Realm Management API (docs/DESIGN.md §3.7, ROADMAP §8.1 files 7.1–7.2): the operator-facing surface for installing and versioning interfaces, managing triggers, and rotating a realm's JWT auth key.
store
Package store is Astrate's single PostgreSQL/TimescaleDB access layer (docs/DESIGN.md §1.3): every domain package reads and writes the database through it, and it imports none of them.
Package store is Astrate's single PostgreSQL/TimescaleDB access layer (docs/DESIGN.md §1.3): every domain package reads and writes the database through it, and it imports none of them.
swagger
Package swagger serves the embedded Swagger UI and OpenAPI YAML specs at /swagger/ and /api/ respectively.
Package swagger serves the embedded Swagger UI and OpenAPI YAML specs at /swagger/ and /api/ respectively.
testutil
Package testutil provides the shared test harness used across Astrate's verification tiers (docs/ROADMAP.md §0.2): the T2 TimescaleDB container helper and the golden-file comparison helper.
Package testutil provides the shared test harness used across Astrate's verification tiers (docs/ROADMAP.md §0.2): the T2 TimescaleDB container helper and the golden-file comparison helper.
Package migrations embeds Astrate's SQL schema migrations (transcribed from docs/DESIGN.md §2.2–2.5) so the binary self-migrates at startup through golang-migrate's iofs source (docs/ROADMAP.md §3.1 file 2.6).
Package migrations embeds Astrate's SQL schema migrations (transcribed from docs/DESIGN.md §2.2–2.5) so the binary self-migrates at startup through golang-migrate's iofs source (docs/ROADMAP.md §3.1 file 2.6).
pkg
astarteapi
Package astarteapi implements the JSON envelope conventions shared by every Astarte-compatible REST surface: success bodies are wrapped as {"data": ...}, error bodies as {"errors": {"detail": "..."}} (or the field-keyed changeset shape used by 422 validation failures), and request bodies arrive wrapped as {"data": ...}.
Package astarteapi implements the JSON envelope conventions shared by every Astarte-compatible REST surface: success bodies are wrapped as {"data": ...}, error bodies as {"errors": {"detail": "..."}} (or the field-keyed changeset shape used by 422 validation failures), and request bodies arrive wrapped as {"data": ...}.
deviceid
Package deviceid implements Astarte's 128-bit device identifier and its canonical encodings: the 22-character unpadded base64url wire form used in MQTT topics, REST paths and certificate CNs, and the canonical UUID form used by operators and tooling.
Package deviceid implements Astarte's 128-bit device identifier and its canonical encodings: the 22-character unpadded base64url wire form used in MQTT topics, REST paths and certificate CNs, and the canonical UUID form used by operators and tooling.
interfaceschema
Package interfaceschema parses, validates, and compiles Astarte interface definitions — the dynamic typed schemas (datastreams and properties) that devices and applications exchange data through.
Package interfaceschema parses, validates, and compiles Astarte interface definitions — the dynamic typed schemas (datastreams and properties) that devices and applications exchange data through.
payload
Package payload implements the dual-format Astarte data-payload codec (docs/DESIGN.md §3.5): standard BSON `{v, t}` documents as produced by the official Astarte device SDKs, and the strict Astrate JSON profile (§3.5.3) for constrained clients (AtomVM and friends) on the same topics with the same semantics.
Package payload implements the dual-format Astarte data-payload codec (docs/DESIGN.md §3.5): standard BSON `{v, t}` documents as produced by the official Astarte device SDKs, and the strict Astrate JSON profile (§3.5.3) for constrained clients (AtomVM and friends) on the same topics with the same semantics.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL