Öffentliche API
Eine REST-API für alles in der Organisation: Geräte, Gruppen, Zugriffsregeln, Netzwerke, DNS, Registrierungsschlüssel, Mitglieder und Aktivität. Authentifiziert wird mit einem Zugriffstoken.
Das Dashboard baut auf einer REST-API auf, und Ihre eigenen Werkzeuge können dieselbe API nutzen. Was das Dashboard mit Geräten, Gruppen, Zugriffsregeln, Netzwerken, DNS, Registrierungsschlüsseln und Mitgliedern tut, kann auch ein Skript über HTTPS tun. Es kann etwa Zugriffsregeln in der Versionsverwaltung pflegen, Gruppen aus einem Inventar befüllen, die Aktivität in ein Log-System übernehmen oder in einem Test prüfen, was ein Gerät erreichen kann.
Die Basis-URL lautet https://app.sxaccess.com, und jeder Pfad beginnt mit /api. Anfragen und Antworten verwenden JSON.
Authentifizierung
Jede Anfrage enthält ein Zugriffstoken im Header Authorization, nach dem Wort Token: Authorization: Token sxp_.... Token beginnen immer mit sxp_, sodass Secret-Scanner ein Token erkennen können, das in ein Repository oder ein Log gelangt ist.
Stellen Sie Token für ein Dienstkonto aus, nicht für eine Person. Die Automatisierung funktioniert dann weiter, wenn Personen ausscheiden, und unter Aktivität erscheint das Dienstkonto als Urheber jeder Änderung. Mitglieder, die Eigentümer, Administrator oder Netzwerkadministrator sind, können auch für sich selbst ein Token erstellen: im Kontomenü unter Profile Settings → Tokens. Dieses Token funktioniert nicht mehr, sobald das Mitglied gesperrt oder aus der Organisation entfernt wird. Ein Token handelt mit der Rolle seines Kontos und in der Organisation, in der es ausgestellt wurde; siehe Rollen.
Das Dashboard ruft dieselbe API mit der Anmeldesitzung der Person auf, die es gerade benutzt; Skripte und Werkzeuge verwenden ein Zugriffstoken. Pfade unter /api/auth/ bedienen die Anmeldeseiten und nehmen kein Token entgegen.
Ein Token erhalten
- 1
Ein Dienstkonto anlegen
Wählen Sie unter People → Service accounts die Schaltfläche Create service account. Benennen Sie das Konto nach dem System, das es nutzen wird, etwa
ci-provisioner, setzen Sie Role auf die Rolle mit den geringsten Rechten, die für die Aufgabe genügt, und wählen Sie dann Create service account. Voreingestellt ist User: Damit kann das Konto alles lesen, aber nichts ändern. Ein Skript, das Zugriffsregeln ändert, braucht Network Admin oder Admin. - 2
Ein Token erstellen
Öffnen Sie das Dienstkonto, wechseln Sie zum Tab Tokens und wählen Sie Create token. Tragen Sie unter Name einen Namen ein und legen Sie Expires in fest: 1 bis 365 Tage, standardmäßig 30. Nur Eigentümer und Administratoren können Token für ein Dienstkonto erstellen.
- 3
Jetzt kopieren
Das Token wird einmalig angezeigt, direkt nach dem Erstellen. SXAccess speichert nur einen Hash davon und kann es nicht erneut anzeigen; legen Sie es also sofort in Ihrer Secret-Verwaltung oder im Secret-Store Ihres CI-Systems ab. Erstellen Sie vor dem Ablauf das nächste Token, stellen Sie Ihr Werkzeug um und löschen Sie dann das alte.
Organisationen
Jeder Aufruf wirkt in genau einer Organisation. Ein Zugriffstoken wirkt immer in der Organisation, in der es ausgestellt wurde; ein Werkzeug, das zwei Organisationen verwaltet, braucht also ein Token aus jeder. GET /api/organizations liefert die Organisation, in der ein Aufruf wirkt, als Liste mit einem Eintrag.
Eine Person, die Mitglied mehrerer Organisationen ist und die API mit ihrer Anmeldesitzung aufruft, wählt eine davon mit dem Header X-Organization-Id aus, gesetzt auf die ID der Organisation; ohne diesen Header wirkt der Aufruf in ihrer Standardorganisation. Zugriffstoken brauchen den Header nicht, und er versetzt ein Token auch nicht in eine andere Organisation. Wie Sie Organisationen anlegen und wechseln, beschreibt die Seite Organisationen.
Rollen
Ein Token darf, was die Rolle seines Kontos in dieser Organisation erlaubt, und nicht mehr. Die Rolle wird bei jeder Anfrage neu gelesen; eine geänderte Rolle gilt also ab dem nächsten Aufruf. Dienstkonten dürfen unabhängig von ihrer Rolle alles in ihrer Organisation lesen; die Rolle bestimmt, was sie ändern dürfen. Die vollständige Matrix steht unter Rollen und Berechtigungen.
| Rolle | Was ein Token mit dieser Rolle darf |
|---|---|
owner | Alles, einschließlich des Löschens der Organisation. Dienstkonten können diese Rolle nicht erhalten. |
admin | Alles Übrige: Geräte, Mitglieder und Dienstkonten, Registrierungsschlüssel, Gruppen, Zugriffsregeln, Geräteanforderungen, Netzwerke, Routen, DNS und die Einstellungen der Organisation. |
network_admin | Gruppen, Zugriffsregeln, Geräteanforderungen, Netzwerke mit ihren Ressourcen und Routing-Geräten, Routen und DNS anlegen, ändern und löschen. Geräte, Mitglieder, Registrierungsschlüssel, Aktivität und Einstellungen lesen, ohne sie zu ändern. |
auditor | Alles lesen, nichts ändern. |
user | Keine Verwaltungsrechte. Diese Rolle ist für Personen gedacht, die nur ihre eigenen Geräte verbinden. |
Endpunkte
Die Pfade sind so geschrieben, wie die API sie nennt. Eine Sammlung beantwortet GET mit einer Liste und POST mit einem neuen Objekt; der eigene Pfad eines Objekts, etwa /api/groups/{groupId}, beantwortet GET, PUT und DELETE. Die Tabelle nennt die Ausnahmen.
| Pfad | Was er enthält |
|---|---|
/api/devices | Geräte. ?name= und ?ip= beschränken die Liste auf Geräte, deren Name oder Tunneladresse den Wert enthält. PUT benennt ein Gerät um und schaltet seinen SSH-Server und den Sitzungsablauf ein oder aus. Einen POST gibt es nicht: Geräte kommen durch Registrierung hinzu. |
/api/devices/{deviceId}/reachable-devices | Die Geräte, mit denen sich dieses Gerät nach den aktuellen Zugriffsregeln verbinden kann. Nur GET; siehe das Beispiel. |
/api/enrollment-keys | Registrierungsschlüssel. Der Schlüssel selbst steht nur in der Antwort auf POST, und expires_in wird in Sekunden angegeben. Danach lassen sich nur auto_groups und revoked ändern. |
/api/access-rules | Zugriffsregeln. Jede enthält ihre Regel in rules, einem Array mit einem Eintrag: sources, destinations (Gruppen-IDs) oder eine destinationResource, protocol, ports, bidirectional und action. source_device_requirements wendet Geräteanforderungen auf die Quellen an. |
/api/device-requirements | Geräteanforderungen und ihre Prüfungen: sx_version_check, os_version_check, geo_location_check, device_network_range_check und process_check. |
/api/groups | Gruppen mit ihren Geräten und Ressourcen. Die Gruppe All enthält jedes Gerät und lässt sich weder ändern noch löschen. |
/api/networks | Netzwerke. Unter jedem liegt /{networkId}/resources mit den Hosts, Subnetzen und Domains, die es erreichbar macht, und /{networkId}/connectors mit seinen Routing-Geräten: ein Gerät oder Gerätegruppen, jeweils mit Metrik und Masquerade. /api/networks/resources und /api/networks/connectors listen sie über alle Netzwerke hinweg auf (nur GET). |
/api/network-routes | Routen: ein Adressbereich oder eine Liste von Domains, geleitet über ein Routing-Gerät oder eine Gerätegruppe. Ein Internet-Gateway ist eine Route nach 0.0.0.0/0. |
/api/dns/servers | DNS-Server. Jeder Eintrag enthält bis zu drei Serveradressen, die Gruppen, deren Geräte sie nutzen, und die Match-Domains, für die sie antworten. |
/api/dns/config | DNS-Einstellungen: die Gruppen, die von der DNS-Verwaltung ausgenommen sind. GET und PUT. |
/api/activity | Aktivität: die letzten 10.000 Ereignisse der Organisation, das neueste zuerst, ohne Filter und ohne Paginierung. Nur GET; um sie in ein anderes System zu übernehmen, fragen Sie den Endpunkt regelmäßig ab und überspringen die ids, die Sie bereits haben. |
/api/users | Mitglieder und Dienstkonten. ?service_user=true listet nur Dienstkonten, false nur Mitglieder. POST lädt ein Mitglied per E-Mail ein oder legt mit "is_service_user": true ein Dienstkonto an. /{userId} beantwortet PUT (Rolle, automatisch zugewiesene Gruppen, Sperre) und DELETE, aber kein GET; /{userId}/invite sendet eine Einladung erneut. |
/api/users/me | Das Mitglied, das den Aufruf ausführt, mit seiner Rolle und seinen Berechtigungen. Nur GET. Das Token eines Dienstkontos erhält hier 403; prüfen Sie ein solches Token stattdessen mit GET /api/organizations. |
/api/users/{userId}/api-tokens | Zugriffstoken eines Mitglieds oder Dienstkontos. POST mit name und expires_in (Tage, 1 bis 365) antwortet mit plain_token, das nur dieses eine Mal erscheint. Der eigene Pfad eines Tokens beantwortet GET und DELETE. |
/api/organizations | Die Organisation, in der der Aufruf wirkt, als Liste mit einem Eintrag (GET). PUT /api/organizations/{organizationId} ändert ihre Einstellungen; siehe das Beispiel. |
/api/geo/countries | Ländercodes und unter /{country}/cities die Städte eines Landes, für Geräteanforderungen, die den Standort prüfen. Nur GET. |
Konventionen
- Bezeichner sind opake Zeichenketten wie
p64dm3gk7ku6rc5asbde. Lesen Sie sie aus der API; zerlegen Sie sie nicht und erfinden Sie keine. - Verweise erfolgen über IDs. Eine Zugriffsregel nennt Gruppen-IDs, keine Gruppennamen; schlagen Sie die Gruppen also zuerst nach. Eine ID, die keine Gruppe der Organisation bezeichnet, wird aus der Regel weggelassen statt abgelehnt; prüfen Sie daher, ob jede Abfrage eine Gruppe gefunden hat.
- Anfrage-Bodys werden streng geprüft. Ein Body darf auf jeder Ebene nur die Felder enthalten, die sein Schema auflistet. Jedes andere Feld wird mit 400 und einer Meldung abgelehnt, die das Feld nennt.
- PUT ersetzt. Bauen Sie den Body aus dem auf, was
GETgeliefert hat: Behalten Sie jedes Feld, das die Anfrage annimmt, ändern Sie die gewünschten und lassen Sie Felder weg, die die Anfrage nicht auflistet, etwaid.
Fehler
Jeder Fehler hat denselben Body: {"message": "...", "code": 403, "error_code": "..."}. code wiederholt den HTTP-Status, und message ist für Menschen geschrieben. error_code steht nur dort, wo ein Client Fehler unterscheiden muss; verzweigen Sie danach, nie nach dem Text von message.
| Status | Bedeutung |
|---|---|
| 400 | Der Body ist kein gültiges JSON, enthält ein Feld, das die Anfrage nicht annimmt (die Meldung nennt es), oder ein Feld mit falschem Typ. |
| 401 | Das Token fehlt oder wird abgelehnt. error_code nennt den Grund: authentication_required (kein Header Authorization oder ein unbekanntes Schema), token_expired oder token_invalid. |
| 403 | Die Rolle des Kontos, dem das Token gehört, erlaubt den Vorgang nicht. Die eigenen Einstellungen eines Mitglieds zu Passwort, Zwei-Faktor, Passkeys und Profil lehnen Zugriffstoken mit interactive_session_required ab; ändern Sie diese im Dashboard. |
| 404 | Das Objekt existiert in dieser Organisation nicht, oder kein Endpunkt hat diesen Pfad (endpoint not found). |
| 405 | Den Pfad gibt es, aber nicht für diese Methode, etwa GET auf /api/users/{userId} (method not allowed for this endpoint). |
| 409 | Das Objekt kollidiert mit einem bestehenden, etwa bei einem Gruppennamen, der bereits vergeben ist. |
| 412 | Eine Vorbedingung ist nicht erfüllt, etwa beim Löschen einer Geräteanforderung, die eine Zugriffsregel noch nutzt, oder eines Geräts, das Routing-Gerät eines Netzwerks ist. |
| 422 | Ein Wert ist ungültig, etwa ein leerer Name, ein Port außerhalb von 1 bis 65535 oder eine Token-Laufzeit außerhalb von 1 bis 365 Tagen. |
| 429 | Zu viele Versuche. Begrenzt sind nur die Anmeldung (/api/auth/) und die eigenen Sicherheitseinstellungen eines Mitglieds; keines von beiden wird mit einem Zugriffstoken aufgerufen. Warten Sie, bevor Sie es erneut versuchen. |
| 500 | Der Server konnte die Anfrage nicht bearbeiten. Versuchen Sie es später erneut, und wenn der Fehler bleibt, wenden Sie sich an den Support. |
Beispiele
Die Beispiele laufen in einer POSIX-Shell mit curl und jq. Setzen Sie einmalig das Token und zwei Abkürzungen und prüfen Sie dann, ob das Token funktioniert; das Token stammt aus Ihrer Secret-Verwaltung. Die Prüfung gibt 200 aus, wenn das Token funktioniert, und 401, wenn es fehlt, abgelaufen oder falsch ist.
export SXACCESS_TOKEN='sxp_...'API=https://app.sxaccess.com/apiAUTH="Authorization: Token $SXACCESS_TOKEN"curl -sS -o /dev/null -w '%{http_code}\n' "$API/organizations" -H "$AUTH"Geräte auflisten
Die Liste enthält jedes Gerät der Organisation, mit seiner Tunneladresse und der Angabe, ob es gerade verbunden ist.
curl -sS "$API/devices" -H "$AUTH" | jq '.[] | {id, name, ip, connected}'curl -sS "$API/devices?name=db" -H "$AUTH" | jq -r '.[].name'Abfragen, was ein Gerät erreichen kann
Aus den Zugriffsregeln abzuleiten, was ein Gerät erreichen kann, ist fehleranfällig. /api/devices/{deviceId}/reachable-devices liefert die Antwort, nachdem jede Zugriffsregel und jede Geräteanforderung ausgewertet wurde: die Geräte, mit denen sich dieses Gerät verbinden darf, und die Geräte, die sich mit ihm verbinden dürfen, einschließlich der Routing-Geräte, die seinen Datenverkehr zu Netzwerkressourcen weiterleiten. Protokolle und Ports gehören nicht zur Antwort; darüber entscheiden die Zugriffsregeln.
Setzen Sie DEVICE auf die id des Geräts aus GET /api/devices. Das zweite Beispiel endet mit einem Exit-Status ungleich null, wenn db-01 in der Antwort fehlt. Deshalb eignet sich dieser Endpunkt für Prüfungen in Tests.
DEVICE=mv5ovp30rnue20llr362curl -sS "$API/devices/$DEVICE/reachable-devices" -H "$AUTH" \ | jq '.[] | {name, ip, connected}'curl -sS "$API/devices/$DEVICE/reachable-devices" -H "$AUTH" \ | jq -e 'any(.[]; .name == "db-01")' > /dev/nullEine Zugriffsregel anlegen
Dieses Beispiel erlaubt der Gruppe Engineering, die Gruppe Production databases über TCP 5432 zu erreichen, in eine Richtung. Es braucht ein Token, dessen Rolle Zugriffsregeln ändern darf: Eigentümer, Administrator oder Netzwerkadministrator. Die Regel verweist über IDs auf Gruppen; der erste Block schlägt deshalb beide Gruppen nach und gibt ihre IDs aus. Prüfen Sie, dass keine davon leer ist: Eine ID, die keine Gruppe bezeichnet, wird aus der Regel weggelassen statt abgewiesen.
"bidirectional": false beschränkt die Regel auf eine Richtung; true erlaubt zusätzlich den Zielen, Verbindungen zu den Quellen zu öffnen. Fügen Sie source_device_requirements mit den IDs von Geräteanforderungen hinzu, um diese von den Quellen zu verlangen. Fragen Sie anschließend ab, was ein Gerät aus Engineering erreichen kann, um zu prüfen, ob die Regel tut, was Sie beabsichtigt haben.
SRC=$(curl -sS "$API/groups" -H "$AUTH" | jq -r '.[] | select(.name == "Engineering") | .id')DST=$(curl -sS "$API/groups" -H "$AUTH" | jq -r '.[] | select(.name == "Production databases") | .id')echo "from $SRC to $DST"curl -sS -X POST "$API/access-rules" -H "$AUTH" \ -H 'Content-Type: application/json' --data-binary @- <<EOF | jq .{ "name": "Engineering to production databases", "description": "TCP 5432, one way", "enabled": true, "rules": [ { "name": "Engineering to production databases", "enabled": true, "action": "accept", "protocol": "tcp", "ports": ["5432"], "bidirectional": false, "sources": ["$SRC"], "destinations": ["$DST"] } ]}EOFOrganisationseinstellungen ändern
PUT /api/organizations/{organizationId} nimmt die Einstellungen der Organisation als ein Objekt entgegen. Lesen Sie sie mit GET, ändern Sie, was Sie ändern wollen, und senden Sie das vollständige settings-Objekt zurück. Dieses Beispiel setzt die Session length für Geräte, die per Anmeldung registriert wurden (Settings → Security; sie gilt, solange Expire device sessions eingeschaltet ist), auf 12 Stunden. Es braucht das Token eines Eigentümers oder Administrators. Der erste Block liest die Organisation, in der das Token wirkt. Der zweite sendet das vollständige settings-Objekt mit einer Änderung zurück: device_login_expiration ist die Sitzungsdauer in Sekunden, 43200 also 12 Stunden.
curl -sS "$API/organizations" -H "$AUTH" > organization.jsonORG_ID=$(jq -r '.[0].id' organization.json)jq '{settings: (.[0].settings | .device_login_expiration = 43200)}' organization.json \ | curl -sS -X PUT "$API/organizations/$ORG_ID" -H "$AUTH" \ -H 'Content-Type: application/json' --data-binary @- | jq .Terraform
Wenn Sie SXAccess mit Terraform verwalten, ruft der Provider dieselbe API auf. Behandeln Sie ihn also wie jeden anderen Client: mit einem eigenen Dienstkonto, einem eigenen Token und der Rolle mit den geringsten Rechten, die abdeckt, was er verwaltet. Wenn Sie Gruppen, Zugriffsregeln, Netzwerke, Routen und DNS als Code verwalten, erhalten Sie ein Review vor jeder Änderung, eine Historie danach und eine schnelle Antwort auf die Frage, was sich geändert hat, wenn etwas nicht mehr funktioniert.

