Uptimeify Docs

Claim-Flow (service_auth & anonym)

Wie ein Agent aus einer Registrierung ein nur lesendes, kontogebundenes Zugriffstoken macht, indem ein angemeldeter Nutzer ihn autorisiert.

Claim-Flow

Ein Claim bindet die Registrierung eines Agenten an die Organisation eines angemeldeten Nutzers (oder an einen einzelnen Kunden darin) und gewährt ein nur lesendes (api.read) Zugriffstoken. Agenten erhalten dabei nie Schreibzugriff. Es gibt zwei Wege zu einem Claim:

  • service_auth startet die Claim-Zeremonie sofort und liefert den user_code direkt an den aufrufenden Agenten zurück (eine vertrauenswürdige Integration im Device-Flow-Stil).
  • Eine anonymous-Registrierung (siehe Agent-Authentifizierung) ist sofort nutzbar und kann optional später per POST /agent/identity/claim hochgestuft werden: der user_code wird dem Agenten auf diesem Weg nie zurückgegeben; nur der angemeldete Nutzer sieht ihn.

1. Mit service_auth registrieren

POST https://uptimeify.io/agent/identity

FeldTypErforderlichBeschreibung
typestringja"service_auth"
login_hintstringjaE-Mail des Nutzers, der den Agenten autorisieren wird. Muss ein @ enthalten.
curl -X POST https://uptimeify.io/agent/identity \
  -H 'Content-Type: application/json' \
  -d '{"type":"service_auth","login_hint":"user@deinkunde.com"}'
{
  "registration_id": "reg_…",
  "claim": {
    "user_code": "WDJB-MJHT",
    "verification_uri": "https://uptimeify.io/claim",
    "expires_in": 600,
    "interval": 5
  },
  "claim_token": "clm_…",
  "post_claim_scopes": ["api.read"]
}

Zeige verification_uri und user_code deinem Nutzer an (ein Prompt im Stil des RFC-8628-Device-Flows). Die Registrierung startet mit status: pending und erzeugt kein Zugriffstoken, bis die Zeremonie abgeschlossen ist. Poll dazu mit dem claim_token in Schritt 3 unten.

user_code und claim_token laufen beide nach expires_in Sekunden ab (600s / 10 Minuten); rufe erneut POST /agent/identity auf, um eine neue Zeremonie zu starten, falls die Zeit abläuft.

2. Oder: eine bestehende anonymous-Registrierung claimen

POST https://uptimeify.io/agent/identity/claim

FeldTypErforderlichBeschreibung
claim_tokenstringjaDas clm_… aus einem früheren Aufruf von POST /agent/identity {"type":"anonymous"}.
emailstringjaE-Mail des Nutzers, der den Claim autorisieren wird. Muss ein @ enthalten.
curl -X POST https://uptimeify.io/agent/identity/claim \
  -H 'Content-Type: application/json' \
  -d '{"claim_token":"clm_…","email":"user@deinkunde.com"}'
{
  "verification_uri": "https://uptimeify.io/claim?claim_attempt=cat_…",
  "claim_attempt_token": "cat_…",
  "expires_in": 600,
  "interval": 5
}

Beachte, was fehlt: user_code. Auf diesem Weg erfährt der Agent den Code nie, nur der angemeldete, an die E-Mail gebundene Nutzer sieht ihn, auf der /claim-Seite. Die Registrierung selbst bleibt während der ganzen Zeremonie active und funktioniert durchgehend mit ihrem tools.public-Scope weiter: das Claimen fügt nur api.read hinzu, es entzieht dem anonymen Zugriff während des laufenden Vorgangs nichts. Ein erneuter Aufruf dieses Endpunkts vor Ablauf überschreibt Code/Attempt-Token und setzt das 10-Minuten-Fenster zurück.

Eine Registrierung kann nur einmal geclaimt werden: Ein zweiter Aufruf von POST /agent/identity/claim (oder ein service_auth-Claim, der immer schon vorab gebunden ist) nach erfolgter Bestätigung liefert 409 claimed_or_in_flight.

3. Menschliche Zustimmung unter /claim

Der gebundene Nutzer muss unter genau dem oben verwendeten login_hint/email bei Uptimeify angemeldet sein und entweder den vom Agenten angezeigten user_code eintippen oder den verification_uri-Link öffnen (der beim anonymen Weg ?claim_attempt=… trägt). Die Uptimeify-Web-App löst das über zwei sitzungscookie-authentifizierte Endpunkte zum Bestätigungsbildschirm auf: diese ruft der Agent nicht selbst auf, sie sind hier nur der Vollständigkeit halber dokumentiert:

  • GET /api/agent-claim/context?claim_attempt=<token>: liefert für den angemeldeten, gebundenen Nutzer { registration_id, agent_type, scope, bound_email, user_code, expires_at }, damit die UI zeigen kann, was autorisiert wird (und beim anonymen Weg den Code vorausfüllen kann).
  • POST /api/agent-claim/confirm { user_code }: der angemeldete Nutzer sendet den Code zur Autorisierung. Bei Erfolg: { ok: true, registration_id }.

Die Bestätigung bindet die Registrierung an die Organisation des Nutzers, oder, wenn dessen Rolle ihn auf genau einen Kunden beschränkt, an diesen einen Kunden. Ein admin oder ein uneingeschränkter editor bindet die gesamte Organisation; ein readonly- (oder editor-)Nutzer, der auf genau einen Kunden beschränkt ist, bindet diesen Kunden; jeder andere Fall (kein als einzelner Scope darstellbarer Kunde, z. B. eine Rolle responder, oder ein readonly-Nutzer mit mehreren zugewiesenen Kunden) lässt die Bestätigung fehlschlagen: der Agent sieht dann expired_token/invalid_claim_token, statt jemals ein zu breites oder mehrdeutiges Token zu erhalten.

4. Auf Abschluss pollen

POST https://uptimeify.io/oauth2/token (application/x-www-form-urlencoded)

FeldErforderlichBeschreibung
grant_typejaurn:uptimeify:agent-auth:grant-type:claim
claim_tokenjaDas clm_… aus Schritt 1 (bzw. die ursprüngliche anonyme Registrierung aus Schritt 2).
curl -X POST https://uptimeify.io/oauth2/token \
  --data-urlencode 'grant_type=urn:uptimeify:agent-auth:grant-type:claim' \
  --data-urlencode 'claim_token=clm_…'

Poll nicht schneller als das interval aus Schritt 1/2 (5 Sekunden). Jeder Poll liefert eines von:

StatusHTTPerrorBedeutung
Noch nicht bestätigt400authorization_pendingWeiter im interval pollen.
Zu schnell gepollt400slow_downDrossle dich: du hast schneller als interval gepollt.
Token/Registrierung weg400expired_tokenDer Claim-Token ist unbekannt, seine Registrierung wurde widerrufen/ist abgelaufen, das äußere 24h-Fenster ist verstrichen, oder er wurde bereits durch einen früheren Poll eingelöst.
Bestätigt200-Erfolg: siehe unten.

Bei Erfolg:

{
  "access_token": "wsma_…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "api.read",
  "identity_assertion": "eyJ…"
}

Der claim_token ist einmal verwendbar: Er wird beim ersten erfolgreichen Poll atomar verbraucht, sodass niemals zwei gleichzeitige/wiederholte Poller beide ein Token erzeugen können. Das Einlösen widerruft in derselben Alles-oder-nichts-Operation auch alle vorherigen tools.public-Zugriffstokens derselben Registrierung: die Vorab-Tokens einer anonymen Registrierung funktionieren nach dem Claim nicht mehr.

Speichere die zurückgegebene identity_assertion (ein EdDSA-JWT mit rund 24 Stunden Gültigkeit, wie im Basis-Flow) und tausche sie erneut über den Grant urn:ietf:params:oauth:grant-type:jwt-bearer (siehe Agent-Authentifizierung), um nach Ablauf frische api.read-Zugriffstokens zu erzeugen. Die Claim-Zeremonie musst du dafür nicht wiederholen.

5. Das Token verwenden (nur lesend)

Das wsma_-Zugriffstoken aus einem abgeschlossenen Claim ist nur lesend und auf die Organisation (bzw. den einzelnen Kunden) des autorisierenden Nutzers begrenzt: GET /api/websites*, GET /api/incidents* und GET /api/health. Jeder Schreibzugriff oder jede Anfrage außerhalb dieser Allowlist liefert 403 mit data.code = agentTokenReadOnly.

Noch nicht verfügbar

identity_assertion als Registrierungs-type (ID-JAG, womit eine bereits vertraute externe OIDC-Identität ohne jede Claim-Zeremonie direkt ein Token erzeugen könnte) ist noch nicht aktiviert. Verlasse dich nicht darauf; POST /agent/identity {"type":"identity_assertion"} liefert derzeit 400 issuer_not_enabled.

Häufige Fehler

HTTPerror / data.codeWoBedeutung
400service_auth_not_enabledPOST /agent/identityservice_auth ist auf diesem Deployment nicht aktiviert.
400invalid_requestPOST /agent/identity, POST /agent/identity/claim, /api/agent-claim/*Fehlendes/ungültiges login_hint, claim_token, email oder user_code.
400invalid_claim_tokenPOST /agent/identity/claimUnbekannter Claim-Token, oder die Registrierung des Tokens ist nicht anonymous, oder sie wurde widerrufen.
404invalid_claim_tokenGET /api/agent-claim/contextDer claim_attempt-Token ist unbekannt/abgelaufen, oder der angemeldete Nutzer ist nicht die gebundene E-Mail, beides ununterscheidbar (fail-closed).
400invalid_claim_tokenPOST /api/agent-claim/confirmDer user_code ist falsch/abgelaufen, oder der Zugriff des bestätigenden Nutzers lässt sich nicht auf einen einzelnen Org-/Kunden-Scope auflösen.
409claimed_or_in_flightPOST /agent/identity/claimDie Registrierung ist bereits geclaimt (organizationId ist schon gesetzt).
400claim_expiredPOST /agent/identity/claimDas äußere 24h-Claim-Fenster (ab Erstellung der Registrierung) ist verstrichen.
400authorization_pendingPOST /oauth2/token (Claim-Grant)Der Nutzer hat noch nicht bestätigt: weiter pollen.
400slow_downPOST /oauth2/token (Claim-Grant)Schneller als interval (5s) gepollt, drossle dich.
400expired_tokenPOST /oauth2/token (Claim-Grant)Der Claim-Token/die Registrierung ist abgelaufen, wurde widerrufen oder bereits eingelöst.
403agentTokenReadOnlyJeder /api/*-Aufruf mit wsma_-TokenSchreibversuch, oder ein Pfad außerhalb der nur-lesenden Allowlist des Tokens.
429-Jeder Endpunkt obenRate-Limit überschritten (siehe Agent-Authentifizierung).

Die vollständige, kanonische Liste findest du in der Fehlercode-Referenz.

Auf dieser Seite