Die API programmatisch nutzen
Diese Seite zeigt, wie deine Integration sich authentifiziert und die
/v1-Endpunkte aufruft. Voraussetzung: ein technischer User
mit username + secret.
Zur Erinnerung: Es ist dieselbe API, die auch das Frontend nutzt – siehe Überblick. Öffnest du im Browser die Entwicklertools und schaust dir die Netzwerk-Aufrufe der Oberfläche an, siehst du exakt die Endpunkte und Payloads, die auch dir zur Verfügung stehen.
Der Ablauf in drei Schritten
1. username + secret ──► Cognito InitiateAuth ──► IdToken (≈ 8 h gültig)
2. IdToken ──► Authorization: Bearer …
3. Aufruf ──► GET/POST/… https://<API-HOST>/v1/…
Schritt 1 – Token holen
Tausche username + secret per Cognito InitiateAuth (Flow
USER_PASSWORD_AUTH) gegen ein ID-Token. Das ist exakt derselbe Flow, den auch
das Frontend beim Login verwendet.
curl -X POST https://cognito-idp.eu-central-1.amazonaws.com/ \
-H "X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth" \
-H "Content-Type: application/x-amz-json-1.1" \
-d '{
"AuthFlow": "USER_PASSWORD_AUTH",
"ClientId": "<CLIENT_ID>",
"AuthParameters": {
"USERNAME": "svc-ab12cd34ef56@svc.leitstand.eu",
"PASSWORD": "<SECRET>"
}
}'
Die Antwort enthält unter AuthenticationResult:
IdToken– gehört in denAuthorization-Header (gültig ca. 8 Stunden).RefreshToken– damit holst du ohne erneute Secret-Eingabe ein frisches IdToken (FlowREFRESH_TOKEN_AUTH).
Leitstand prüft das ID-Token – es trägt aud = App-Client-ID und
cognito:groups mit Tenant und Rolle. Verwende IdToken, nicht AccessToken.
Schritt 2 & 3 – API aufrufen
Hänge das IdToken als Bearer-Token an jeden /v1-Aufruf:
curl https://app.leitstand.eu/v1/apps \
-H "Authorization: Bearer <IdToken>"
Schreiben (nur editor):
curl -X POST https://app.leitstand.eu/v1/apps \
-H "Authorization: Bearer <IdToken>" \
-H "Content-Type: application/json" \
-d '{"name": "Neue App", "status": "active"}'
Basis-URL
Verwende die App-Domain, die /v1 an die API weiterleitet, z. B.
https://app.leitstand.eu – das Frontend nutzt in Produktion relative Pfade auf
genau dieser Domain. Alternativ funktioniert die direkte API-Gateway-URL.
Rollen & Berechtigungen
| Rolle | Lesen (GET) | Schreiben (POST/PUT/DELETE) |
|---|---|---|
viewer | ✅ | ❌ → 403 |
editor | ✅ | ✅ |
Ein viewer, der schreibend zugreift, erhält 403 Forbidden. Alle Aufrufe
sind automatisch auf den Tenant des technischen Users beschränkt.
Fehlercodes
| Status | Bedeutung |
|---|---|
401 | Token fehlt, ist abgelaufen oder ungültig → neues Token holen |
403 | Rolle reicht nicht (z. B. viewer schreibt) oder User deaktiviert |
400 | Fehlerhafte Anfrage (z. B. Pflichtfeld fehlt, Validierung) |
404 | Objekt nicht gefunden (auch: gehört nicht zu deinem Tenant) |
409 | Konflikt (z. B. Löschen, solange noch Referenzen bestehen) |
Endpunkt-Überblick
Die wichtigsten /v1-Endpunkte (Lesen mit viewer, Schreiben mit editor):
| Ressource | Endpunkte |
|---|---|
| Applikationen | GET/POST /v1/apps, GET/PUT/DELETE /v1/apps/{id} |
| Infrastruktur | GET/POST /v1/infrastructure, … /v1/infrastructure/{id} |
| Fähigkeiten | GET/POST /v1/capabilities, … /v1/capabilities/{id} |
| Org-Einheiten | GET/POST /v1/org-units, … /v1/org-units/{id} |
| Schnittstellen | GET/POST /v1/interfaces, … /v1/interfaces/{id} |
| Projekte | GET/POST /v1/projects, … /v1/projects/{id} |
| Landschaft | GET /v1/landscape |
| Dashboard | GET /v1/dashboard, GET /v1/freshness |
| CSV | GET /v1/csv/export, POST /v1/csv/import |
Die maßgebliche, vollständige API-Beschreibung steht als API-Referenz
bereit – direkt aus der OpenAPI-Spezifikation des Backends gerendert. Sie listet
alle Endpunkte, Parameter, Felder und Antwortschemata und ist die Quelle der Wahrheit,
falls diese Seite und die Implementierung je auseinanderlaufen. Die Spec lässt sich
dort auch als openapi.yaml herunterladen.
Vollständiges Beispiel (Python, nur Standardbibliothek)
Token holen und eine Liste lesen – ganz ohne zusätzliche Pakete:
import json
import urllib.request
USERNAME = "svc-ab12cd34ef56@svc.leitstand.eu"
SECRET = "<dein-secret>"
CLIENT_ID = "<deine-client-id>"
REGION = "eu-central-1"
API_BASE = "https://app.leitstand.eu"
def get_id_token():
req = urllib.request.Request(
f"https://cognito-idp.{REGION}.amazonaws.com/",
data=json.dumps({
"AuthFlow": "USER_PASSWORD_AUTH",
"ClientId": CLIENT_ID,
"AuthParameters": {"USERNAME": USERNAME, "PASSWORD": SECRET},
}).encode(),
headers={
"X-Amz-Target": "AWSCognitoIdentityProviderService.InitiateAuth",
"Content-Type": "application/x-amz-json-1.1",
},
method="POST",
)
with urllib.request.urlopen(req) as r:
return json.load(r)["AuthenticationResult"]["IdToken"]
def get(path, token):
req = urllib.request.Request(
API_BASE + path, headers={"Authorization": f"Bearer {token}"})
with urllib.request.urlopen(req) as r:
return json.load(r)
token = get_id_token()
print(get("/v1/apps", token))
Im Backend-Repository liegen unter examples/ zwei lauffähige Skripte als
Startpunkt: public_api_smoketest.py (nur lesende Aufrufe) und
public_api_writetest.py (End-to-End-Schreibtest). Beide brauchen nur die
Python-Standardbibliothek.
Token-Lebensdauer & Erneuerung
- Das IdToken ist rund 8 Stunden gültig. Hol bei Bedarf ein neues – für
lang laufende Prozesse über das
RefreshToken(REFRESH_TOKEN_AUTH), sonst einfach erneut perUSER_PASSWORD_AUTH. - Rotieren oder Deaktivieren eines technischen Users entwertet alle laufenden Tokens sofort.
Technische User per API verwalten
Technische User lassen sich nicht nur in der Oberfläche, sondern auch über die API
verwalten – allerdings nur mit einem Admin-Token. Ein technischer User hat das
nie (er kann nicht admin sein); diese Endpunkte rufst du also mit dem Token eines
menschlichen Admins auf.
| Aktion | Endpoint |
|---|---|
| Auflisten | GET /v1/technical-users |
| Anlegen | POST /v1/technical-users |
| Secret rotieren | POST /v1/technical-users/{username}/rotate |
| Rolle ändern | PUT /v1/technical-users/{username}/role |
| Deaktivieren | DELETE /v1/technical-users/{username} |
| Reaktivieren | POST /v1/technical-users/{username}/reactivate |
Sicherheitshinweise
- Secret wie ein Passwort behandeln: niemals in Git, Logs oder Tickets. Lege es in einem Secret-Manager ab.
- Least Privilege:
viewerwählen, wenn Schreibrechte nicht nötig sind. - Eine Integration, ein technischer User: So kannst du einzelne Credentials gezielt rotieren oder sperren, ohne andere Integrationen zu stören.
- Regelmäßig rotieren und nicht mehr genutzte technische User deaktivieren.