Paramant op IoT en embedded apparaten.

IoT-apparaten, PLC's, OT-gateways en single-board computers kunnen bestanden via Paramant versturen met alleen een vaste API-sleutel. Geen TOTP, geen handmatig inloggen, geen browser nodig.

Hoe een machine zich aanmeldt

Elk API-verzoek aan Paramant meldt zich aan met de header X-Api-Key met uw API-sleutel. De sleutel begint met pgp_, gevolgd door 64 hexadecimale tekens, en wijst uw account aan. Een Authorization: Bearer-header werkt niet voor een pgp_-sleutel: op deze routes leest de relay daar alleen kortlevende sessietokens (pst_) van het webdashboard uit. Zet de sleutel ook nooit in de URL; een verzoek met ?k= wordt geweigerd. Voor machines is dat genoeg. Buiten het inloggen op het webdashboard wordt nergens om een TOTP-code gevraagd.

Maak een eigen API-sleutel per apparaat of soort apparaat. Dan kunt u losse sleutels intrekken zonder dat andere koppelingen last hebben. Dashboard → API-sleutels → Nieuwe sleutel maken.

Ondersteunde apparaten

Raspberry Pi Zero / Zero 2

Volledige Linux-omgeving. Gebruik het Python-voorbeeld hieronder of de Python-SDK (pip install paramant-sdk). TLS 1.3 werkt meteen.

ESP32 / ESP8266

Dat kan, als de firmware AES-256-GCM en HTTPS heeft: mbedTLS in ESP-IDF heeft beide. MicroPython heeft geen AES-GCM; daarvoor hebben wij geen kant-en-klaar voorbeeld. Laat zo'n apparaat via een gateway of een Pi versturen.

OT-gateways

Een gateway die uitgaande HTTPS-verbindingen maakt en een script kan draaien (Python 3 met cryptography), kan het voorbeeld hieronder gebruiken.

Een bestand versturen vanaf een Linux-apparaat

Er is geen route die een leesbaar bestand aanneemt: de relay krijgt alleen versleutelde bytes. Het apparaat versleutelt dus zelf, uploadt de versleutelde blob naar POST /v2/inbound en krijgt een download_token terug. Daarvan maakt het een link naar /get, met de sleutel achter het #, zodat de relay hem nooit ziet. Python 3 met het pakket cryptography:

import os, json, base64, hashlib, struct, urllib.request from cryptography.hazmat.primitives.ciphers.aead import AESGCM API_KEY = os.environ["PARAMANT_API_KEY"] # pgp_... RELAY = "https://health.paramant.app" # the sector your key belongs to SECTOR = "health" PATH = "/var/log/sensor-log.csv" # one block: at most about 5 MB # 1. Seal the file on the device: [uint32-LE name length][name][bytes] name = os.path.basename(PATH).encode() plain = struct.pack("<I", len(name)) + name + open(PATH, "rb").read() key, iv = AESGCM.generate_key(bit_length=256), os.urandom(12) sealed = AESGCM(key).encrypt(iv, plain, None) # 2. Upload the ciphertext with its SHA-256 body = json.dumps({"hash": hashlib.sha256(sealed).hexdigest(), "payload": base64.b64encode(sealed).decode(), "ttl_ms": 3600000}).encode() req = urllib.request.Request(RELAY + "/v2/inbound", data=body, method="POST", headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"}) token = json.load(urllib.request.urlopen(req))["download_token"] # 3. The link: the key travels after the #, the relay never sees it frag = base64.urlsafe_b64encode(key + iv).rstrip(b"=").decode() print(f"https://paramant.app/get?t={token}&r={SECTOR}#{frag}")

Geef de link via elk kanaal aan de ontvanger. Die opent hem in de browser; de pagina ontsleutelt het bestand en pas dan wordt het op de relay gewist. De link werkt één keer en vervalt na de ttl_ms die de relay terugmeldt (maximaal 1 uur op Community, 24 uur op Firm). Eén upload is één blok van hoogstens 5 MB; een groter bestand gaat in meerdere blokken, en dat doet de SDK voor u. Hoe het formaat in elkaar zit, staat in docs/api.md onder "The share link".

Bewaar de API-sleutel in het flashgeheugen of in een omgevingsvariabele, niet ingebakken in de firmware. Gebruik op de ESP32 NVS (Non-Volatile Storage) of een aparte partitie voor inloggegevens. Dan kunt u de sleutel vervangen zonder opnieuw te flashen.

Sleutels vervangen op apparaten in gebruik

Vervang sleutels volgens een vast schema, of meteen als een apparaat buiten gebruik gaat, gerepareerd wordt of door iemand anders in handen is geweest. Zo gaat het:

  1. Maak een nieuwe sleutel in het dashboard.
  2. Zet de nieuwe sleutel op het apparaat (update via het netwerk, beveiligde provisioning of ter plekke).
  3. Controleer of het apparaat met de nieuwe sleutel goed verstuurt.
  4. Trek de oude sleutel in via het dashboard.

Trek de oude sleutel pas in als u zeker weet dat de nieuwe werkt. Een ingetrokken sleutel werkt meteen niet meer. Er is geen overgangstijd.

Limieten op verzoeken

De limieten op verzoeken gelden per IP-adres, niet per API-sleutel: de nginx-configuratie in deze repository zet gewoon API-verkeer in een zone van 60 verzoeken per minuut en uploads in een strengere (nginx-selfhost.conf). De grens die wel per sleutel geldt, gaat over ophalen, niet over uploaden: 50 downloads per uur op Community en 500 per uur op Firm (outbound_per_hour in relay/lib/tiers.js). Daarboven volgt een 429. Stuurt een sensor vaak gegevens, bundel de metingen dan in één bestand voordat u uploadt, in plaats van één bestand per meting. Een bestand mag op elk plan tot 500 MB zijn (file_mb in relay/lib/tiers.js). Het reist in vaste blokken van 5 MB, dus één uploadverzoek draagt één blok.


Veelgestelde vragen

Mijn apparaat krijgt bij elk verzoek een 401.
Controleer of de sleutel in de header X-Api-Key staat (bijvoorbeeld X-Api-Key: pgp_...), niet in Authorization: Bearer en niet in de URL. Kijk ook in het dashboard of de sleutel niet is ingetrokken.
De TLS-handshake mislukt op mijn embedded apparaat.
Paramant vraagt TLS 1.2 of hoger. Oudere firmware gebruikt soms een verouderde CA-bundel. Werk de firmware van het apparaat bij of zet het actuele ISRG Root X1-certificaat van Let's Encrypt erop.
Kan ik de relay zelf hosten op een lokaal netwerk en er vanaf apparaten bij?
Ja. Host een Paramant-relay op uw eigen netwerk en laat de apparaten naar uw interne hostnaam wijzen. Zie de handleiding voor zelf hosten en install-pi.sh voor een relay op een Raspberry Pi.

Zie ook

API-sleutel of TOTP

Waarom machines alleen de API-sleutel nodig hebben.

Volledige API-naslag

Alle endpoints, parameters en antwoordschema's.