Zum Inhalt

English

Referenz der lokalen API

Wie Ihre eigene Software auf dem Gateway ihre Konfiguration vom Bootstrap-Agent liest. Diese Seite ist eine Zusammenfassung; der vollständige Vertrag ist local-api-v1.openapi.yaml im Release-Archiv (Vertragsversion 1.6, interface_version 1).

Transport und Zugriff

  • HTTP/1.1 über einen Unix-Socket, /run/bootstrap-agent/api.sock. Der Agent öffnet keinen Netzwerk-Port. Der Host-Name in einer Anfrage wird ignoriert.
  • Der Zugriff ist die Dateiberechtigung des Sockets: Modus 0660, Gruppe bootstrap-agent. Die Mitgliedschaft in dieser Gruppe ist die ganze Berechtigung. Nehmen Sie nur die Prozesse auf, die die Konfiguration brauchen: Sie enthält die Zugangsdaten für Ihre Zielplattform, und ein Aufruf der Lese-Endpunkte liefert sie.
  • Der Agent protokolliert bei jedem Aufruf, der etwas ändert, die Benutzer-ID des Aufrufers.
curl -s --unix-socket /run/bootstrap-agent/api.sock http://localhost/v1/status | jq .

Der Agent antwortet mit einer Zeile JSON; | jq . rückt sie ein.

Beispielausgabe von cproto-v0.2.0-rc.2 (die Form ist echt, die Werte sind ersetzt). Jeden Aufruf mit seiner echten Antwort zeigt Beispiele der lokalen API.

{
  "interface_version": 1,
  "interface_minor_version": 6,
  "agent_version": "cproto-v0.2.0-rc.2",
  "state": "ready",
  "attestation_mode": "tpm",
  "profile_version": 42,
  "last_checkin": "2026-01-01T12:00:00Z",
  "tpm_transient_avail": 3,
  "tpm_loaded_sessions": 0,
  "tpm_transient_capacity": 3,
  "tpm_transient_used": 0,
  "identity_cert_state": "not_configured",
  "auth_mode": "tpm",
  "auth_mode_source": "server",
  "activation": "listen",
  "profile_ready_marker": "/etc/iot-config/profile-ready"
}

Endpunkte

Aufruf Antwort
GET /v1/status Immer 200 mit dem Zustand des Agenten, siehe unten. Er schlägt nie fehl: Ein unbeantworteter Status sieht aus wie ein abgestürzter Agent.
GET /v1/profile Die ganze aktuelle Konfiguration, genau so, wie die Plattform sie erzeugt hat. 404 mit NO_CONFIG, solange es keine gibt. If-None-Match mit dem ETag ergibt 304.
GET /v1/profile/packages Die Liste der Pakete darin, mit Version und Hash. Gleiche Regeln für 404 und 304.
GET /v1/profile/packages/{id} Der Inhalt eines Pakets, ohne Umschlag. 404, wenn es das Paket oder die Konfiguration nicht gibt.
POST /v1/profile/packages/{id}/ack Meldet dem Agenten, dass Sie die Konfiguration angewendet haben. Body: {"profile_version": 42, "applied": true} (reason ist Freitext, wenn applied false ist; er wird angenommen, nicht gespeichert), siehe applied: false. 204, wenn vermerkt, 400 bei fehlerhaftem Body, 409, wenn die Version nicht die aktuelle ist, 404 bei unbekanntem Paket. Die Version wird zuerst geprüft: Ein unbekanntes Paket mit alter Version bekommt 409. Ein Body ohne applied gilt als applied: false.
GET /v1/events Long Poll, siehe Ohne Polling.

Das Profil kann Geheimnisse enthalten

GET /v1/profile und GET /v1/profile/packages/{id} liefern die Konfiguration ungeschwärzt, einschließlich der Zugangsdaten für Ihre Zielplattform samt privatem Schlüssel. Den Socket können nur der Benutzer des Agenten, root und Mitglieder der Gruppe bootstrap-agent öffnen (Modus 0660). Behandeln Sie alles, was diese Aufrufe liefern, als vertraulich: nie in ein Log, ein Ticket, einen Chat oder einen Fehlerbericht schreiben und nie vom Gateway kopieren. Um eine Konfiguration zu zeigen, nehmen Sie die Paketliste (/v1/profile/packages); sie enthält nur Kennungen, Versionen und Hashes. ?pretty=1 schützt nicht: Es ergänzt Zusammenfassungen der Zertifikate und gibt den privaten Schlüssel trotzdem vollständig aus (geprüft auf dem Labor-Gateway). Sichere Aufrufe zum Kopieren stehen unter Beispiele der lokalen API; die Aufrufe, die Geheimnisse ausgeben, stehen am Ende dieser Seite.

Beispiel für die Form von GET /v1/profile (alle Werte sind erfunden und absichtlich nicht echt; die Struktur von content hängt von Ihrem Template ab):

{"profile_version":42,"packages":[{"id":"example-package","version":42,"sha256":"EXAMPLE-NOT-A-REAL-HASH","content":{"example_key":"EXAMPLE-VALUE-NOT-REAL"}}]}

?pretty=1 an den drei Lese-Aufrufen ergänzt jeden Hash in Hex-Form (sha256_hex) und eine Zusammenfassung jedes Zertifikats (decoded_certs). Es rückt nicht ein (dafür | jq .) und verbirgt nichts: Ein privater Schlüssel wird vollständig ausgegeben, wie ohne den Parameter. sha256 selbst ist Base64, so wie die Plattform es sendet. Die Antwort wird neu zusammengesetzt; bilden oder vergleichen Sie Hashes einer Konfiguration deshalb nur in der einfachen Form.

Zwei Wege zu bestätigen

Ihre Software meldet dem Agenten auf einem von zwei Wegen, dass die Konfiguration angewendet ist. Nehmen Sie die Markierungsdatei.

Die Markierungsdatei (empfohlen) ack über diese API
Was Ihre Software tut Schreibt {"state":"connected"} nach /run/wlpc/target-confirmed, sobald sie mit ihrem Ziel verbunden ist, siehe Das Ziel bestätigen. POST /v1/profile/packages/{id}/ack mit {"profile_version": 42, "applied": true}, einmal für jedes Paket.
Was der Agent tut Bestätigt jedes noch nicht bestätigte Paket mit applied: true. Vermerkt dieses eine Paket.
Was Ihre Software braucht Die Gruppe wlpc. Die Gruppe bootstrap-agent, die Paket-IDs und die aktuelle profile_version.

Die Datei ist ein Schreibvorgang und deckt jedes Paket jeder Konfiguration ab. Rufen Sie ack nur selbst auf, wenn Ihre Software Pakete einzeln anwendet und jedes einzeln bestätigen muss.

Was confirmed sendet. Keiner der beiden Wege sendet es direkt. Der Agent sendet confirmed, sobald jedes Paket der aktuellen Konfiguration mit applied: true bestätigt ist, gleich auf welchem Weg das letzte bestätigt wurde. confirmed setzt das Gerät auf ACTIVE, und das erste confirmed ist der einzige Schritt, der abgerechnet wird, einmal pro Gerät: nicht complete, nicht Check-ins, und ein wiederholtes confirmed nie wieder (siehe Bereit und bestätigt). Ein Prozess des Agenten sendet sie einmal pro Konfiguration. Ein Paket, das auf false zurückgesetzt und wieder bestätigt wird, lässt diesen Prozess sie nicht noch einmal senden; nach einem Neustart sendet der neue Prozess sie für dieselbe Konfiguration noch einmal, wenn ein Paket wieder bestätigt wird, mit einem vorgezogenen Check-in (die letzten beiden Zeilen unten).

Wenn beide genutzt werden, gemessen mit dem Agenten von cproto-v0.2.0-rc.2 gegen einen Testdienst (cproto/e2e/confirmpaths.sh), jeder Fall auf einem frischen Gerät:

Fall Was geschah
Alle Pakete über die API bestätigt, keine Datei confirmed wurde einmal gesendet. Eine danach geschriebene Datei änderte nichts: keine zweite Bestätigung.
Zwei von fünf Paketen über die API, dann die Datei Nach den zweien keine Bestätigung. Die Datei bestätigte die übrigen drei, und confirmed wurde einmal gesendet.
Vier mit applied: true, eines mit applied: false, dann die Datei Keine Bestätigung, und keine einzige Anfrage ging an die Plattform. Die Datei überschrieb danach das false mit true, und confirmed wurde einmal gesendet.
applied: false nach der Bestätigung, die Datei noch da, dann ein Neustart Für das false wurde nichts gesendet. Beim Start las der Agent die Datei, bestätigte das Paket wieder mit true und sendete die Bestätigung mit einem vorgezogenen Check-in noch einmal.
Ein Paket über die API auf false und zurück auf true, durch den Prozess, der bestätigt hatte Keine zweite Bestätigung.
Dasselbe nach einem Neustart Die Bestätigung wurde noch einmal gesendet.

Auf dem Labor-Gateway bestätigte die Datei alle sieben Pakete, und bei einem Agenten, der auf einer gespeicherten Konfiguration gestartet war, führte ein über die API wieder bestätigtes Paket zu einem vorgezogenen Check-in mit der Bestätigung.

Ein ack für eine ältere profile_version wird mit 409 abgelehnt, sodass Software, die noch eine alte Konfiguration anwendet, die neue nicht als geliefert markieren kann. Acks sind idempotent.

applied: false

  • Auf dem Gerät: Das Paket gilt als nicht bestätigt ("acked": false in der Paketliste), und solange ein Paket nicht bestätigt ist, wird kein confirmed gesendet. Der Wert wird gespeichert und übersteht einen Neustart. Ein reason wird angenommen, aber weder gespeichert noch gesendet.
  • Bei der Plattform: nichts. Der Agent sendet für ein ack keine Anfrage, weder mit true noch mit false; er sendet nur confirmed, sobald alle true sind. Die Plattform kann eine gescheiterte Konfiguration nicht von einer unterscheiden, die noch angewendet wird: Sie sieht nur, dass confirmed ausbleibt. Das ist eine bekannte Lücke, siehe Bekannte Lücken und Grenzen.
  • Die Datei gewinnt. Immer wenn der Agent eine Datei mit connected liest (wenn sie geschrieben wird, nach einer neuen Konfiguration und bei jedem Start), bestätigt er jedes nicht bestätigte Paket mit applied: true, auch eines, das Ihre Software auf false gesetzt hat. Software, die eine Konfiguration nicht anwenden kann, darf die Datei nicht schreiben und muss sie entfernen, falls sie da ist.
  • Fehlt applied, gilt das als false. Auf dem Labor-Gateway wurde ein ack nur mit profile_version mit 204 beantwortet, und das Paket stand als nicht bestätigt da.

Zustand

state in GET /v1/status ist einer von:

state Bedeutung
no_config Es gibt (noch) keine Konfiguration. Das ist ein normaler Zustand, kein Fehler, und er kann Monate dauern: Ein Gerät im Regal, das niemand beansprucht hat, bleibt hier. Es ist auch der Zustand, nachdem die Plattform das Gerät abgewiesen hat (unbekannt, nicht beansprucht, gesperrt); den Grund nennt last_error_code. Ihre Software muss ihn beliebig lange aushalten, ohne abzustürzen, ihren Start zu blockieren oder Alarm zu schlagen.
bootstrapping Eine Ersteinrichtung läuft.
ready Eine Konfiguration ist gespeichert und wird ausgeliefert.
error Ein lokaler Fehler: ein defektes TPM, Speicher, der nicht beschreibbar ist, eine fehlende Plattformadresse. Ein Bescheid der Plattform versetzt den Agenten nie hierher.

Weitere Felder: profile_version (ein undurchsichtiger Wert, vergleichen Sie nur mit == und !=; eine höhere Zahl heißt nicht neuer), last_checkin, last_error_code (fehlt, solange es keinen gibt), tpm_transient_avail und tpm_transient_capacity (freie und gesamte transiente TPM-Plätze), tpm_transient_used, tpm_loaded_sessions, identity_cert_state, auth_mode, auth_mode_source, activation (in diesem Agenten immer listen) und profile_ready_marker (der Pfad der Markerdatei). Ob es ein neueres Feld gibt, erkennen Sie an interface_minor_version.

last_error_code trägt den öffentlichen Fehlercode der Plattform unverändert oder einen der eigenen TPM-Fehlercodes des Agenten, zum Beispiel TPM_STUCK_POWER_CYCLE_REQUIRED, siehe TPM-Slots. Eine Ablehnung, die die Plattform bei einem späteren Check-in schickt, setzt ihn ebenfalls, und ein Gerät, das eine Konfiguration hält, bleibt ready. Die Konsole zeigt einen solchen abgewiesenen Kontakt nicht, siehe Bekannte Lücken und Grenzen; lesen Sie ihn hier oder im Log des Agenten ab.

Fehler

Eine Fehlerantwort ist {"code": "..."} mit einem von NO_CONFIG, NOT_FOUND, MALFORMED_REQUEST, STALE_PROFILE_VERSION oder INTERNAL. Ein unbekannter Pfad bekommt 404 mit NOT_FOUND. Ebenso eine Methode, die ein Pfad nicht annimmt (zum Beispiel POST oder DELETE auf /v1/status, GET auf .../ack): 404, nicht 405. Was zu tun ist, wenn ein Gerät in no_config bleibt, steht unter Fehlerbehebung.

Ohne Polling

Sie müssen GET /v1/status nicht jede Sekunde oder alle zwei Sekunden abfragen, um von einer neuen Konfiguration zu erfahren. Stattdessen zwei Wege:

  • Long Poll. GET /v1/events?profile_version=PROFILE_VERSION wartet, bis sich die Version ändert (Antwort 200 mit der neuen profile_version) oder 60 Sekunden vergehen (204). Ist die übergebene Version schon veraltet, antwortet er sofort, sodass eine Änderung zwischen zwei Abfragen nicht verloren geht. Eine geschlossene Keep-alive-Verbindung ist normal; verbinden Sie sich neu.
  • Eine Markerdatei. Nach jeder neu gespeicherten Konfiguration, und erst wenn sie sicher geschrieben ist, ersetzt der Agent die Datei /etc/iot-config/profile-ready. Eine systemd-Path-Unit reagiert darauf, siehe Software starten und bestätigen. Ein unveränderter Check-in berührt die Datei nicht.