KI-Agenten sollten https://remote.ivjn.us/SKILL.md abrufen.
HTTP-API für Agent-Operationen
Native versiegelte Operationen unterstützen jetzt reine HTTP-Clients. Verwenden Sie remote-cli --transport http oder REMOTE_TRANSPORT=http. POST /api/sealed/connections erstellt eine Verbindung, POST /input übermittelt signierte Handshakes oder Chiffretext, GET /events ruft Ergebnisse ab und DELETE schließt die Verbindung. Kryptografie und Geräteautorisierung bleiben beim Client. Die bisherigen Geräteaktions-Endpunkte liefern weiterhin 409; die Geräteverbindung bleibt unverändert. HTTP-Anfragen müssen dieselbe Exchange-Instanz erreichen. Nach 90 Sekunden ohne Aktivität läuft die Verbindung ab. Eingaben werden seriell gesendet; Wiederholungen behalten Sequenznummer und Chiffretext bei. Verarbeitete Ereignisse werden mit after bestätigt. Web Console, Mobilgeräte und LAN behalten ihren Transport. Vorlagen erfordern weiterhin manage.
https://remote.ivjn.us/sealed-http.md
HTTP 409 / Sealed sessions are required. bei Geräteaktionen verlangt eine versiegelte Sitzung; ein Bearer-Token allein genügt nicht. Verwenden Sie remote-cli --profile alice exec lab -- uname -a oder bei reinem HTTP remote-cli --profile alice --transport http exec lab -- uname -a. Die CLI führt weiterhin den signierten Handshake und die Ende-zu-Ende-Verschlüsselung aus.
Basis-URL
Produktiver Exchange:
https://exchange.ivjn.us
Bei selbst gehosteten Bereitstellungen verwenden Sie Ihren eigenen HTTPS-Origin. Alle folgenden Pfade sind relativ zu dieser Basis. Senden Sie JSON mit Content-Type: application/json.
Authentifizierung
Jede Route unter /api/* (außer öffentlichen Hilfsrouten für Authentifizierung/Registrierung) erfordert:
Authorization: Bearer <token>
<token> kann Folgendes sein:
- Sitzungstoken einer Passwortanmeldung aus
POST /api/auth/login - Primärer API-Schlüssel eines Operators (das langlebige Token, das beim Erstellen des Operator-Kontos einmalig angezeigt wird)
Beide werden vom selben authenticate_operator-Pfad akzeptiert, den auch Konsole und CLI verwenden.
Passwortanmeldung
curl -sS -X POST 'https://exchange.ivjn.us/api/auth/login' \
-H 'Content-Type: application/json' \
-d '{"email":"alice@example.com","password":"your-password-here"}'
email ist die Kontoidentität und muss eine gültige Adresse sein. Der Dienst normalisiert sie (Leerzeichen entfernen, Kleinschreibung) und verlangt eine verifizierte Adresse. Bestehende Bereitstellungen können weiterhin { "username": "alice", "password": "..." } senden, bis diese Konten auf E-Mail umgestellt sind; ein Wert mit @ in username wird als E-Mail-Adresse behandelt. Ungültige Adressen werden vor der Passwortprüfung abgelehnt.
Beispielantwort:
{
"username": "alice",
"email": "alice@example.com",
"tenant_id": "00000000-0000-0000-0000-000000000000",
"token": "<prefix>.<secret>",
"expires_in": 2592000
}
Verwenden Sie token als Bearer-Zugangsdaten. Rufen Sie POST /api/auth/logout mit demselben Header auf, um diese Sitzung zu widerrufen. Primäre Operator-API-Schlüssel werden durch die Abmeldung nicht widerrufen.
Operator-API-Schlüssel (primäres Token)
TOKEN='<prefix>.<secret>' # issued at operator creation; store offline
curl -sS 'https://exchange.ivjn.us/api/devices' \
-H "Authorization: Bearer ${TOKEN}"
Geräte auflisten
curl -sS 'https://exchange.ivjn.us/api/devices' \
-H "Authorization: Bearer ${TOKEN}"
Jeder Eintrag enthält id, name, online, enabled, info, Zeitstempel und active_sessions. Das Geräteinventar besteht aus Exchange-Metadaten. Das Auflisten eines Geräts stellt keine versiegelte Sitzung her, wie sie für dessen Bedienung erforderlich ist.
HTTP-Ablehnung von Geräteaktionen und Sitzungsverwaltung
Alle Geräteoperationen verwenden versiegelte WebSocket-Sitzungen. Die folgenden HTTP-Routen können den Client-/Geräte-Handshake nicht herstellen und liefern daher HTTP 409 für authentifizierte, autorisierte Anfragen, die die Eingabevalidierung bestehen. Die Ablehnung erfolgt vor der Weiterleitung an das Gerät: Kein Befehl, keine Sensoranfrage, Netzwerkprüfung, Aktualisierung, ubus-Aufruf, Hold-Auftragsanfrage oder feste Befehlsvorlage wird an den Agent gesendet. Auch ein verbundenes Gerät macht diese Routen nicht ausführbar.
Authentifizierung, Berechtigungen und Eingabevalidierung gelten weiterhin. Ungültige Zugangsdaten liefern 401, verbotene Operationen 403; ungültige Befehle, URLs oder Anfragetexte behalten ihre Validierungsfehler einschließlich 400. Der Versiegelungsfehler 409 ersetzt keine vorhergehenden Validierungs- oder Autorisierungsfehler. Berechtigungsprüfungen für feste Befehlsvorlagen folgen deren Richtlinie; auch bestandene Prüfungen erlauben keine HTTP-Ausführung.
| Methode und Pfad | Verhalten nach Authentifizierung, Autorisierung und Validierung |
|---|---|
POST /api/devices/{id}/exec |
409: innerhalb einer versiegelten WebSocket-Sitzung ausführen |
GET /api/devices/{id}/exec/holds |
409: Hold-Aufträge innerhalb einer versiegelten WebSocket-Sitzung prüfen |
POST /api/devices/{id}/exec/holds/{job_id}/kill |
409: Hold-Aufträge innerhalb einer versiegelten WebSocket-Sitzung beenden |
GET /api/devices/{id}/exec/holds/{job_id}/cat |
409: Hold-Auftragsausgabe innerhalb einer versiegelten WebSocket-Sitzung lesen |
POST /api/devices/{id}/sensors |
409: Sensoren innerhalb einer versiegelten WebSocket-Sitzung erfassen |
POST /api/devices/{id}/net |
409: Netzwerkprüfungen innerhalb einer versiegelten WebSocket-Sitzung ausführen |
POST /api/devices/{id}/update |
409: Aktualisierungen innerhalb einer versiegelten WebSocket-Sitzung prüfen oder anwenden |
POST /api/devices/{id}/ubus |
409: ubus innerhalb einer versiegelten WebSocket-Sitzung aufrufen |
POST /api/devices/{id}/commands/{cmd}/run |
409: feste Befehlsvorlage abrufen und innerhalb einer versiegelten WebSocket-Sitzung mit einem vom Gerät autorisierten Manage-Grant ausführen |
Diese gültige Aktionsanfrage prüft beispielsweise die Ablehnung; sie ist keine Schnittstelle zur Befehlsausführung:
curl -i -X POST "https://exchange.ivjn.us/api/devices/${DEVICE_ID}/exec" \
-H "Authorization: Bearer ${TOKEN}" \
-H 'Content-Type: application/json' \
-d '{"command":"uname -a","timeout_secs":30}'
Erwarten Sie HTTP 409 mit der englischen Fehlermeldung Sealed sessions are required. (entsprechend der Anfragesprache lokalisiert). Stellen Sie zur Ausführung der Operation eine native versiegelte WebSocket-Sitzung her. Diese HTTP-Route liefert keine erfolgreiche Antwort mit Befehlsausgabe.
Exchange-Sitzungsverwaltung
Sitzungsinventar und Abbruch bleiben über HTTP verfügbar, da sie Exchange-Routing-Metadaten verwalten. Sie führen keine Geräteoperationen aus und öffnen keine zusätzliche Gerätesitzung.
| Methode und Pfad | Erfolgsantwort |
|---|---|
GET /api/devices/{id}/sessions |
{sessions:[DeviceSessionInfo], limit, count} |
POST /api/devices/{id}/sessions/{session_id}/kill |
{session_id, released} |
Die Felder von DeviceSessionInfo sind session_id (numerische geräteseitige ID), operator_session_id, kind, hold, age_secs und deadline_unix_ms. limit ist max_sessions_per_device (standardmäßig 32); count ist die aktuelle Listenlänge. Die Auflistung liest direkt den lokalen Exchange-Hub-Zustand; ein lokal offline befindliches Gerät liefert 503. Kill verwendet die geräteseitige ID, sendet den passenden Abbruch (auch für gehaltenes Exec) und gibt die Route lokal frei, selbst wenn das Gerät nicht antwortet. Eine fehlende Sitzung oder ein lokal offline befindliches Gerät liefert HTTP 200 mit released:false. Operatoren mit Leserechten erhalten bei beiden Endpunkten 403.
curl -sS "https://exchange.ivjn.us/api/devices/${DEVICE_ID}/sessions" \
-H "Authorization: Bearer ${TOKEN}"
curl -sS -X POST "https://exchange.ivjn.us/api/devices/${DEVICE_ID}/sessions/${SESSION_ID}/kill" \
-H "Authorization: Bearer ${TOKEN}"
Bevor Exchange eine volle Sitzungsgrenze ablehnt, bereinigt es Routen nicht mehr verbundener Operatoren und Routen nach Ablauf ihrer Frist: Exec-Zeitlimit + 15 Sekunden, Dateiübertragung 3600 Sekunden + 15 Sekunden, andere Arten 24 Stunden. Gehaltenes Exec innerhalb seiner Frist wird bei Operator-Trennung abgekoppelt, statt beendet zu werden.
Native versiegelte CLI-Operationen
Die CLI stellt versiegelte Sitzungen im Rahmen normaler Geräteoperationen her. Schließen Sie zuerst die Genehmigung der Arbeitsbereichs-Root und die Geräteautorisierung ab; siehe versiegelte Sitzungen. Klartext kann nicht gewählt werden. Normale Befehle benötigen keinen zusätzlichen Versiegelungsparameter:
remote-cli exec "$DEVICE_ID" -- uname -a
remote-cli shell "$DEVICE_ID"
remote-cli exec-holds "$DEVICE_ID"
remote-cli exec-hold-cat "$DEVICE_ID" "$JOB_ID"
remote-cli exec-hold-kill "$DEVICE_ID" "$JOB_ID"
remote-cli sensors "$DEVICE_ID" --json
remote-cli net "$DEVICE_ID" ping 1.1.1.1
remote-cli net "$DEVICE_ID" http https://example.com/
remote-cli ubus "$DEVICE_ID" system board '{}'
remote-cli commands list "$DEVICE_ID"
remote-cli commands run "$DEVICE_ID" "$COMMAND_ID"
Hold-Auftragsoperationen laufen innerhalb versiegelter Sitzungen; die Exchange-Sitzungsverwaltung ist separat über remote-cli sessions und remote-cli session-kill verfügbar. Das Abrufen von Metadaten fester Befehlsvorlagen autorisiert keine Ausführung: Das Gerät muss den Manage-Grant des versiegelten Operators akzeptieren.
Schlüsselverzeichnis und Grant-Weiterleitung für versiegelte Sitzungen
Exchange speichert öffentliche Operator-Schlüssel und vom Eigentümer signierte rsg1.-Grant-Tokens, damit Clients einander finden. Dies ist keine Autorisierung. Geräte prüfen die Eigentümersignatur weiterhin anhand ihrer lokalen Richtlinie. Exchange indiziert lediglich die Token-Nutzlast (owner_key, operator_key, device_id, level, expires_at) und wertet einen Upload niemals als Berechtigung. Exchange kann Root-Signaturen nicht fälschen, jedoch Zugangsdaten zurückhalten, einem automatisch genehmigenden Root-Client eine falsche Mitgliederliste präsentieren, Metadaten beobachten oder den Dienst verweigern.
Die Arbeitsbereichs-Root (rsr1.) und Grant-Einladungen (rsi1.) verwenden dieselbe Art der Weiterleitung. Exchange prüft das Token-Format und die Ed25519-Selbstsignatur (eine Einladung muss außerdem zum gespeicherten Root-Schlüssel passen) und entscheidet nicht, welche Operator-Schlüssel genehmigt sind. GET /api/seal/roster ist eine Superadmin-Ansicht der Mitglieder, Rollen und operator_device_grants. Clients dürfen einen neu aufgetauchten Schlüssel erst vertrauen, wenn der Root-Client ihn lokal genehmigt. Siehe docs/sealed-sessions.md.
Jedes authentifizierte Arbeitsbereichsmitglied darf Schlüssel auflisten, seinen eigenen Schlüssel registrieren und Grants hochladen (Grants authentifizieren sich selbst). DELETE eines Schlüssels ist auf das registrierende Konto beschränkt (Administratoren dürfen beliebige löschen). DELETE eines Grants ist auf den Uploader beschränkt (Administratoren dürfen beliebige löschen). GET /api/seal/grants überspringt abgelaufene Zeilen.
Der Nachweis zur Schlüsselregistrierung ist eine Ed25519-Signatur über:
remote-seal-key-register:v1:<workspace_id>:<operator_id>:<public_key>:<issued_at_ms>
issued_at_ms muss innerhalb von ±10 Minuten der Serveruhr liegen. public_key und proof verwenden Standard-Base64 (32-Byte-Schlüssel, 64-Byte-Signatur).
| Methode und Pfad | Anfragetext | Erfolg |
|---|---|---|
POST /api/seal/keys |
{"public_key","label"?,"proof","issued_at_ms"} |
registrierter Schlüssel (Upsert für dasselbe Konto) |
GET /api/seal/keys |
— | [{operator_id, username, email, public_key, label, created_at, last_seen_at}] |
DELETE /api/seal/keys/{key} |
— | 204 ({key} ist der URL-codierte öffentliche Schlüssel) |
POST /api/seal/grants |
{"tokens":["rsg1.…"]} |
{stored:[…], errors:[…]} |
GET /api/seal/grants?mine=1 |
— | Grants, deren operator_key einer der registrierten Schlüssel des Aufrufers ist. Jeder Grant, dessen owner_key nicht die veröffentlichte Root ist, enthält außerdem chain (Zertifikat-Tokens, möglicherweise leer) |
GET /api/seal/grants?owner_key=… |
— | von diesem Eigentümerschlüssel signierte Grants |
DELETE /api/seal/grants/{id} |
— | 204 |
PUT /api/seal/root |
{"token":"rsr1.…","rotation":"rsx1.…"?} |
gespeicherte Arbeitsbereichs-Root. Nur Superadmin. Format und eigene Signatur des Schlüssels werden geprüft; dies ist keine Genehmigung. rotation (optional) muss von der aktuell veröffentlichten Root signiert sein und die neue Root benennen; Exchange sendet dann seal_root {token, rotation} an verbundene versiegelte Geräte. Diese ändern ihre feste Zuordnung nur, wenn die Rotation von ihrer bereits vertrauten Root signiert ist. Ohne gültige Rotation behalten Geräte mit festgelegter alter Root diese bei |
GET /api/seal/root |
— | {workspace_id, root_key, payload, signature, token, created_at}, oder 404, wenn keine veröffentlicht ist |
POST /api/seal/invitations |
{"token":"rsi1.…"} |
gespeicherte Einladung. Nur Superadmin und erst, nachdem eine Root existiert |
GET /api/seal/invitations |
— | nicht abgelaufene Einladungen, neueste zuerst ([], wenn keine vorhanden) |
GET /api/seal/roster |
— | {members:[{operator_id, username, email, role, restricted, enabled, keys:[{public_key, label}], device_grants:[{device_id, can_manage}]}]}. Nur Superadmin. Enthält deaktivierte Mitglieder |
Ein nicht verfügbares Verzeichnis umgeht weder die Anforderung versiegelter Sitzungen noch die erforderlichen Geräte-Grants. GET /api/seal/root liefert 404, wenn keine Arbeitsbereichs-Root veröffentlicht wurde.
# Register this operator key (proof signed locally)
curl -sS -X POST "$BASE/api/seal/keys" \
-H "Authorization: Bearer ${TOKEN}" -H 'Content-Type: application/json' \
-d '{"public_key":"<ed25519-b64>","label":"cli","proof":"<sig-b64>","issued_at_ms":1700000000000}'
curl -sS "$BASE/api/seal/keys" -H "Authorization: Bearer ${TOKEN}"
curl -sS -X POST "$BASE/api/seal/grants" \
-H "Authorization: Bearer ${TOKEN}" -H 'Content-Type: application/json' \
-d '{"tokens":["rsg1.…"]}'
curl -sS "$BASE/api/seal/grants?mine=1" -H "Authorization: Bearer ${TOKEN}"
Zwischenzertifikate (rsc1.)
Exchange speichert Zwischenzertifikate, damit ein Nicht-Root-Schlüssel Grants signieren kann, die Geräte akzeptieren. Es prüft die Ed25519-Signatur des Ausstellers und kann kein Zertifikat fälschen. Der Upload eines Tokens ist keine Autorisierung: Der Aufrufer muss der Operator des Ausstellers sein. Ein von der Root signiertes Zertifikat (issuer_key entspricht der veröffentlichten Arbeitsbereichs-Root) darf nur vom Arbeitsbereichs-Superadmin veröffentlicht werden. Ein Zwischenzertifikat darf nur von dem Konto veröffentlicht werden, dessen registrierter Seal-Schlüssel issuer_key ist; der Aussteller muss selbst Subjekt eines gespeicherten, nicht widerrufenen, nicht abgelaufenen Zertifikats mit can_issue sein. Das untergeordnete Zertifikat muss innerhalb der Stufe, des Gerätebereichs und der Gültigkeit des übergeordneten bleiben (dieselben Prüfungen wie auf Geräten). Eine erneute Veröffentlichung desselben Paars (issuer_key, subject_key) ersetzt die ältere Zeile und hebt den Widerruf auf.
GET /api/seal/certs/chain?subject_key= liefert {chain:[tokens]} entlang der Ausstellerverknüpfungen bis zur veröffentlichten Root, höchstens 4 Zertifikate, das von der Root ausgestellte zuerst, oder 404. Jedes authentifizierte Mitglied darf es aufrufen. GET /api/seal/grants?mine=1 ergänzt diese chain bei Grants, deren Signierer nicht die Root ist, sodass Clients sie mit dem Grant erhalten. Bei von der Root signierten Grants fehlt chain.
GET /api/seal/certs listet alle Zeilen einschließlich widerrufener auf (Administratoren und Superadmin). DELETE /api/seal/certs/{serial} (Konto des Ausstellers oder Superadmin) setzt revoked. Dies stoppt lediglich die Verteilung. Geräte akzeptieren eine bereits vorhandene Kopie bis zu ihrem Ablauf weiter; ein harter Widerruf erfolgt über revoked_keys in der Geräterichtlinie. {serial} ist die URL-codierte Seriennummer in Standard-Base64.
| Methode und Pfad | Anfragetext | Erfolg |
|---|---|---|
POST /api/seal/certs |
{"token":"rsc1.…"} |
gespeichertes Zertifikat (Upsert nach Aussteller und Subjekt) |
GET /api/seal/certs/chain?subject_key= |
— | {chain:["rsc1.…"]}, von der Root ausgestelltes zuerst, oder 404 |
GET /api/seal/certs |
— | [{serial, issuer_key, subject_key, token, expires_at_ms, created_at, revoked}]. Administrator oder Superadmin |
DELETE /api/seal/certs/{serial} |
— | 204. Aussteller oder Superadmin. Stoppt nur die Verteilung |
curl -sS -X POST "$BASE/api/seal/certs" \
-H "Authorization: Bearer ${TOKEN}" -H 'Content-Type: application/json' \
-d '{"token":"rsc1.…"}'
curl -sS "$BASE/api/seal/certs/chain?subject_key=<ed25519-b64>" \
-H "Authorization: Bearer ${TOKEN}"
Sicherung des Arbeitsbereichs-Root-Schlüssels (optional)
PUT / GET / DELETE /api/seal/backup speichern einen opaken rsb1.-Blob pro Konto. PUT und GET sind nur Superadmins erlaubt: Der Blob enthält den privaten Root-Schlüssel des Arbeitsbereichs, clientseitig mit Argon2id (64 MiB, t=3, p=1) und ChaCha20-Poly1305 verschlüsselt. Die Passphrase ist optional; eine Mindeststärke wird nicht erzwungen. Bei leerer oder schwacher Passphrase kann jeder Besitzer des Blobs (einschließlich Exchange) den Root-Schlüssel entschlüsseln und sämtliche Geräte kontrollieren. Der Upload ist optional; Clients können den Root-Schlüssel (rsk1.) stattdessen exportieren und offline aufbewahren. Exchange prüft den Präfix rsb1. und die Länge von blob und entschlüsselt niemals. GET ist pro Konto und Prozess auf 5 Anfragen pro Stunde begrenzt (HTTP 429). Lese-, Schreib- und Löschvorgänge werden ausschließlich mit der Bytezahl auditiert. Antworten senden Cache-Control: no-store.
| Methode und Pfad | Anfragetext | Erfolg |
|---|---|---|
PUT /api/seal/backup |
{"blob":"rsb1.…"} |
{blob, updated_at} |
GET /api/seal/backup |
— | {blob, updated_at}, oder 404, wenn nichts gespeichert ist. Ratenbegrenzt |
DELETE /api/seal/backup |
— | 204, auch wenn keine Zeile existiert |
curl -sS -X PUT "$BASE/api/seal/backup" \
-H "Authorization: Bearer ${TOKEN}" -H 'Content-Type: application/json' \
-d '{"blob":"rsb1.…"}'
curl -sS "$BASE/api/seal/backup" -H "Authorization: Bearer ${TOKEN}"
curl -sS -X DELETE "$BASE/api/seal/backup" -H "Authorization: Bearer ${TOKEN}"
Root-Ketten-Authentifizierung der Browsererweiterung
Browseroperationen verwenden native versiegelte WebSocket-Sitzungen. Die Erweiterung erzeugt selbst einen Ed25519-Operator-Schlüssel. Mit einem Operator-Bearer-Token ruft sie tenant_id / operator_id von /api/auth/me ab und sendet anschließend POST /api/seal/keys mit {public_key, label, proof, issued_at_ms}. Der Besitznachweis (PoP) signiert:
remote-seal-key-register:v1:<workspace_id>:<operator_id>:<public_key>:<issued_at_ms>
Schlüssel und Signatur sind Standard-Base64 (32/64 Bytes); die Zeit muss innerhalb von ±10 Minuten der Serveruhr liegen. Die Registrierung beweist den Schlüsselbesitz, keine Autorisierung. Die Erweiterung synchronisiert GET /api/seal/root, GET /api/seal/grants?mine=1 und Zertifikat-Tokens, die Grants beiliegen oder über GET /api/seal/certs/chain?subject_key=<url-encoded-key> abgerufen werden. Grants müssen sich direkt oder über eine gültige Zertifikatskette bis zur vertrauenswürdigen Arbeitsbereichs-Root prüfen lassen und den richtigen Gerätebereich, die richtige Stufe und Gültigkeit aufweisen. Die Registrierung per Gerätetoken bleibt von diesem Verzeichnisablauf mit Operator-Token getrennt.
Die Erweiterung prüft eingehende native Hellos anhand ihrer Root und fügt ihr eigenes signiertes Hello/Grant/Kette in SealAccept.peer ein. CLI/Konsole prüfen diesen Nachweis und verlangen peer.operator_key == accept.device_key, bevor sie die signierte Antwort akzeptieren. Rust-Agents verwenden ihre normale Root-Richtlinie, wenn die Erweiterung als Operator agiert. Ungültige/fehlende Nachweise führen zur Ablehnung; es gibt keinen separaten Browser-Vertrauensspeicher/keine separate Oberfläche und keinen Legacy-Fallback. TOFU für native Geräte und Arbeitsbereichs-Root bleibt bestehen; die Erweiterung speichert ihre erste Root pro Server/Arbeitsbereich und lehnt Änderungen ab.
Sicherheit: Prüfen Sie die erste Root über einen unabhängigen Kanal; PoP oder eine Serverrolle sind keine Root-Genehmigung. Prüfen Sie unbekannte Schlüssel vor automatischer Genehmigung durch den Root-Client. Schützen Sie Endpunktprofile/Schlüssel und gehostete Skripte. Das Löschen aus dem Verzeichnis widerruft keine zwischengespeicherten signierten Zugangsdaten. Exchange kann Metadaten sehen, Zugangsdaten zurückhalten oder den Dienst verweigern; Versiegelung isoliert keinen feindlichen Operator mit vollständigem CDP-Zugriff.
WebSocket oder HTTPS wählen
| Bedarf | Verwendung |
|---|---|
| Befehle, Hold-Aufträge prüfen oder abbrechen, Sensoren, Netzwerkprüfungen, Aktualisierungen, ubus, feste Befehlsvorlagen | Native versiegelte WebSocket-Sitzung |
| Interaktives PTY, Streaming-Ausgabe, Dateiübertragung, Android-Bildschirm/Baum/Tippen | Native versiegelte WebSocket-Sitzung |
| Authentifizierung, Geräteinventar, Schlüssel-/Grant-/Zertifikatsverzeichnis, Root-Backup | HTTPS-API |
| Exchange-Routingsitzungen auflisten und abbrechen | HTTPS-Endpunkte der Sitzungsverwaltung |
| Live-Gerätepräsenz und langlebige Operatorverbindung | WebSocket; Geräteoperationen auf dieser Verbindung erfordern weiterhin Versiegelung |
Browser-Ticket-Ablauf (Zugangsdaten gelangen niemals in die WebSocket-URL):
POST /api/ws-ticketmitAuthorization: Bearer ….- Mit
GET /ws/browserverbinden und als ersten JSON-Frame{"ticket":"…"}senden. - Vor jeder Geräteoperation den nativen versiegelten Client-/Geräte-Handshake herstellen. Grant und Zertifikatskette des Operators müssen sich anhand der vom Gerät vertrauten Root validieren lassen.
Native Clients verwenden GET /ws/operator mit Operator-Authentifizierung und derselben Anforderung versiegelter Sitzungen. Eine WebSocket-Verbindung oder erfolgreiche Kontoanmeldung allein autorisiert keine Geräteoperation. Siehe Webkonsole und Web Push, Protokoll und versiegelte Sitzungen.
Übersicht der Fehlerstatus
| Status | Typische Ursache |
|---|---|
400 |
Ungültige Aktionseingabe, etwa ein leerer Befehl oder eine ungültige Update-Quell-URL; Validierung erfolgt vor der Ablehnung wegen erforderlicher Versiegelung |
401 |
Fehlendes oder ungültiges Bearer-Token |
403 |
Konto- oder Geräteberechtigungen autorisieren die Anfrage nicht |
409 |
Gültige, autorisierte HTTP-Geräteaktion erfordert eine versiegelte WebSocket-Sitzung; keine Weiterleitung an das Gerät |
404 |
Fehlender Verzeichniseintrag oder unveröffentlichte Arbeitsbereichs-Root gemäß Endpunktvertrag |
429 |
Endpunktspezifische Ratenbegrenzung, einschließlich Lesen von Arbeitsbereichs-Root-Backups |
503 |
Das Sitzungsinventar findet das Gerät nicht im lokalen Exchange-Hub-Zustand |
HTTP-Geräteaktionsrouten warten nicht auf Agent-Ausgaben; ihr normales autorisiertes Ergebnis ist daher 409, kein Ausführungserfolg, Offline-Weiterleitungsfehler oder HTTP-Ausführungszeitlimit. Fehler von Metadaten-, Authentifizierungs- und Verzeichnis-APIs behalten ihre endpunktspezifische Bedeutung.
Manueller Validierungsplan
Verwenden Sie ein Testkonto und ein Gerät mit bekannten Berechtigungen. HTTP-Ablehnungsprüfungen erfordern keine Ausführung auf einem Gerät:
- Authentifizieren Sie sich und listen Sie Geräte über HTTPS auf; prüfen Sie Konto- und Geräteberechtigungen.
- Senden Sie eine gültige Anfrage an jede Geräteaktionsroute der Ablehnungstabelle. Erwarten Sie HTTP
409und bestätigen Sie, dass keine Aktion den Agent erreicht, einschließlich Lesen von Hold-Aufträgen und Ausführen fester Befehlsvorlagen. - Prüfen Sie ungültige Zugangsdaten, gesperrte Konten und ungültige Eingaben separat. Erwarten Sie Authentifizierungs-, Berechtigungs- und Validierungsfehler, statt bei jeder Anfrage
409anzunehmen. - Lesen Sie das Exchange-Sitzungsinventar. Testen Sie den Abbruch einer ausdrücklich ausgewählten entbehrlichen Testsitzung und prüfen Sie
released; eine fehlende Sitzung liefertreleased:false. Das Auflisten von Sitzungen eines lokal offline befindlichen Geräts liefert503. - Schließen Sie Root-Genehmigung und Grants ab und führen Sie dann eine harmlose native CLI-Operation aus, etwa
remote-cli exec "$DEVICE_ID" -- uname -a. Prüfen Sie den Erfolg über den versiegelten Handshake. Ein fehlender oder ungültiger Geräte-Grant muss zur Ablehnung führen. - Prüfen Sie Schlüsselregistrierung, Grant-/Zertifikatsabruf, optionales Root-Backup und Browser-Root-Kettenauthentifizierung unabhängig; diese HTTPS-APIs bleiben gemäß den beschriebenen Verträgen verfügbar.
Audit-Exportziele
Nur PostgreSQL Exchange unterstützt diese API, getrennt nach authentifiziertem Workspace. Nur Administratoren und Superadministratoren; andere Konten erhalten 403. exchange-worker und eine Konfigurationsoberfläche in Web-/Mobil-Console werden nicht unterstützt.
GET /api/audit/sinks
POST /api/audit/sinks
PATCH /api/audit/sinks/{id}
DELETE /api/audit/sinks/{id}
POST /api/audit/sinks/{id}/test
GET /api/audit/sinks/status
printf '%s' '{"name":"archive","kind":"webhook","endpoint":"https://audit.example.net/events","secret":"REPLACE-WITH-RANDOM-SECRET","mode":"full"}' | remote-cli audit sink add
remote-cli audit sink list
printf '%s' '{"interval_ms":500,"batch_size":16}' | remote-cli audit sink update 1
remote-cli audit sink test 1
remote-cli audit sink status
remote-cli audit sink remove 1
Standard throttled sendet gespeicherte Audit-Einträge: Text über 256 KiB behält 250 KiB am Anfang und 6 KiB am Ende, Dateien nur als Hash, Streams nach Sitzungsende. full erfasst vor dem Kürzen und teilt Original-JSON und Binärdaten in Blöcke (Standard 1 MiB), mit Vorgangs-/Asset-ID, Sequenz, Offset, Endmarkierung, SHA-256 und Gesamtgröße. Bei sealed senden beide Modi nur Metadaten und Verweise/Hashes des Geheimtexts, keinen Endpunkt-Klartext.
Secrets und Header werden verschlüsselt gespeichert und als *** angezeigt. PATCH erhält ***; null entfernt einen Header. Asynchrone dauerhafte FIFO-Warteschlangen und exponentielle Wiederholungen. Volle throttled-Queues verwerfen und zählen die ältesten Einträge; full-Disk-Queues üben Rückstau aus. Status zeigt Erfolg/Fehler, Rückstand, dropped und gaps. Löschen verwirft ausstehende Daten und protokolliert die Anzahl; Konfigurationsänderungen werden in derselben Transaktion auditiert.
Webhooks verwenden JSON-events mit base64-Bytes. X-Remote-Timestamp und X-Remote-Signature: sha256=<hex> prüfen HMAC-SHA256(timestamp + "." + unveränderter Body). OTel verwendet OTLP/HTTP JSON /v1/logs, body.bytesValue für Blöcke, Attribute remote.device.id / remote.operator / remote.action und konfigurierbares service.name. gRPC benötigt einen Collector, kein direkter Export.
Es folgen Standardkonfiguration, Webhook-Nutzlast, Signaturprüfung und Collector-Beispiele. Den unveränderten HTTP-Body prüfen; vor 2xx dauerhaft speichern und anhand delivery_id deduplizieren. In Loki 3.x allow_structured_metadata aktivieren, in Grafana eine Loki-Datenquelle hinzufügen und {service_name="remote-exchange"} abfragen. Für gRPC pipeline exporters auf [otlp/grpc] ändern. In Produktion TLS und Authentifizierung verwenden.
{"name":"collector","kind":"otel","mode":"throttled","endpoint":"https://collector.example.net:4318/v1/logs","headers":{"Authorization":"Bearer REPLACE"},"service_name":"remote-exchange","resource":{"deployment.environment.name":"production"},"batch_size":32,"interval_ms":1000,"chunk_bytes":1048576,"queue_limit":10000,"overflow_bytes":10737418240,"actions":[],"devices":[],"operators":[],"enabled":true,"ca_pem":null}
{"version":1,"events":[{"delivery_id":123,"type":"full","mode":"full","entry":{"id":42,"action":"exec","operator_name":"alice","device_id":"dev"},"data":{"kind":"binary","asset_id":"asset-uuid","path":"/data_base64","sequence":0,"offset":0,"last":true,"data_base64":"YWJj","total_size":3,"sha256":"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad","context":{"direction":"output","frame_sequence":0,"stream_offset":0}}}]}
import hashlib, hmac, time
def verify(headers, raw_body, secret):
stamp = headers['X-Remote-Timestamp']
if abs(time.time() - int(stamp)) > 300:
raise ValueError('expired webhook')
expected = 'sha256=' + hmac.new(
secret.encode(), stamp.encode() + b'.' + raw_body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, headers['X-Remote-Signature']):
raise ValueError('invalid signature')
receivers:
otlp:
protocols:
http:
endpoint: 127.0.0.1:4318
processors:
batch: {}
exporters:
otlphttp/loki:
endpoint: http://loki:3100/otlp
otlp/grpc:
endpoint: telemetry.example.net:4317
headers:
Authorization: "${env:OTEL_AUTHORIZATION}"
tls:
insecure: false
service:
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp/loki]
| Audit-Feld | OTLP-Feld |
|---|---|
| service_name / resource | Resource service.name / attributes |
| entry.started_at | timeUnixNano |
| entry.id / delivery_id | remote.audit.id / remote.delivery.id |
| entry.device_id / operator_name / action | remote.device.id / remote.operator / remote.action |
| entry.tenant_id | remote.workspace.id |
| entry.started_at / ended_at / detail | remote.started_at / remote.ended_at / remote.result |
| traceId / spanId | traceId / spanId |
| data.data_base64 | body.bytesValue / remote.chunk.* |
| stored events | body.stringValue |