Security architecture

Ingest, storage, encryption, retention

This page describes the production architecture of OpenSense as it exists today (2026-05). It is opinionated and pragmatic, not a Tier-I data centre. We optimise for "small business operator can answer their insurance questionnaire honestly" rather than "ISO 27001 today".

Data flow

data flowopensense · eu-central
DEVICEEDGEINGEST + RULESSTORAGEOUTBOUNDShelly H&THTTPS (GET/POST)Aqara THZigbee → MQTTEfento NS-TLoRaWAN → TTNDIY ESP32HTTPS or MQTTSClamp meterHTTPSCADDY · TLS 1.3→ /v1/ingest→ /v1/ingest/shelly→ /v1/ingest/lorawan→ MQTT bridge :8883per-device tokenrate limit 60/minpayload sanity→ /app (UI)→ /v1/* (mgmt)→ /v1/reports→ /v1/measurementsINGEST SERVICEJSON validatedevice matchchannel resolvesanity rangeidempotency (24h)dedupe (ts, ch)RULE ENGINErange / deltawindows (rrule)grace periodstate machineevent emitTIMESCALE · MEASUREMENTSraw 13 morollup 5 m 5 yrrollup 1 h 5 yrrollup 1 d foreverLUKS at resthourly backupshetzner falkensteinAUDIT + EVENTSappend-onlySHA-256 chaindaily head pubno UPDATEno DELETEOUTBOUNDTelegramEmailWebhookPDFretry+ digestOK · service nominalWARN · degradedALARM · pagedarrows: data direction · one-waySCH-001 · DATA FLOW · REV B · 2026-05 · NOT TO SCALE · NOT A MARKETING ILLUSTRATION

Where the data lives

  • Region: eu-central (Hetzner Falkenstein, Germany).
  • Host: a dedicated Hetzner VPS (pingerHE), one EU subnet, EU legal entity for the data controller relationship.
  • Database: TimescaleDB on the same host, on a dedicated volume.
  • Object storage (for PDFs and backups): a separate Hetzner volume, in the same DC. Encrypted at rest via LUKS.
  • MQTT broker: EMQX, single instance, same host.

There is no US-region failover. There is no off-EU replica.

Encryption

  • In transit, public: TLS 1.3 only, via Caddy. Certificates from Let's Encrypt, auto-renewed. SSL Labs grade A+.
  • In transit, internal: localhost loop on the host. Postgres and EMQX are bound to 127.0.0.1. There is no encryption on those loops because they do not leave the host.
  • At rest: LUKS on the data volume. Backups are encrypted with age (the keypair lives outside the host).

Retention

Data classDefault retention
Raw measurements13 months
5-minute rollups5 years
1-hour rollups5 years
1-day rollupsforever (small)
Alert eventsforever
PDF reports renderedregenerated on demand; not stored long-term
API request logs30 days
Outbound notification logs90 days
Backups (PG dump + storage)30 days, hourly retained for 7 d, daily for 30

Retention is non-negotiable downward. A customer asking us to drop raw retention to 30 d is asking for a non-compliant product; we refuse. Upward extensions are a Team-tier or Enterprise-tier option.

Backups

  • Hourly logical Postgres dumps to the dedicated backup volume, encrypted with age, retained 7 days.
  • Daily full dumps retained 30 days.
  • Weekly off-site dump to a separate Hetzner storage box, also encrypted.
  • We have not tested restore from offsite in the last 30 days. Restoring it monthly is a Q3 task; until then, treat the off-site dump as belt-and-braces, not as guaranteed.

Secrets

  • Per-device ingest tokens — bcrypt-stored, last-used timestamped, rotatable any time.
  • User API tokens — same.
  • Postgres / EMQX / Postmark / Telegram bot secrets — held in a single env file owned by root:root, mode 0400. No HashiCorp Vault, no KMS. Single-tenant infrastructure does not justify the operational overhead.

What is not in this architecture

We are honest about the gaps so customers do not assume more than is there.

  • No HSM. All keys are in process memory.
  • No SOC 2 / ISO 27001 attestation. Roadmap, not today.
  • No SAML / SSO. Magic-link only. Coming with the Team tier.
  • No air-gapped on-prem offering. Not on the roadmap.
  • No live failover. A 30-minute downtime budget is acceptable to the customer base (smaller than a fridge defrost cycle).

For customers who need any of the above, talk to us — we will tell you honestly whether OpenSense fits.