Mandact — The Trust Layer of the Agent Economy

Entwickler · Schnellstart

In 10 Minuten zum ersten allow

Ihr Agent fragt Mandact vor jeder Handlung und handelt nur bei «allow». Für einen Test braucht es weder Zahlungsmittel noch Händler: Erfinden Sie eine Handlung, etwa «Hardware bis CHF 500 bei ACME AG», und schicken Sie verschiedene Beträge und Gegenparteien. Sie sehen allow, deny mit Grund, Eskalation und den Beleg.

Weg 1 · Mandact signiert

Der Schlüssel des Agenten liegt verschlüsselt bei Mandact. Zwei Aufrufe vor der Handlung, einer danach — in jeder Sprache.

Scope agents:present

Weg 2 · Agent signiert selbst

Der Agent hält seinen Ed25519-Schlüssel selbst; Mandact kennt nur den öffentlichen. Kryptografisch das stärkere Modell.

eigene did:key im Assistenten

Weg 3 · Gateway

Der Agent spricht nicht mehr direkt mit dem Zielsystem. Mandact prüft jede Anfrage und leitet nur bei allow weiter — die Prüfung lässt sich nicht überspringen.

Token gwt_… pro Instanz

  1. 1 · Konto anlegen

    Registrieren und den zweiten Faktor einrichten. Ohne ihn lassen sich keine API-Schlüssel erzeugen.

  2. 2 · Agent und Mandat anlegen

    Neues Mandat im Assistenten. Im Schritt «Agent» die Kennung leer lassen (Weg 1) oder die did:key Ihres Agenten eintragen (Weg 2). Grenzen setzen: Handlungstyp, Betrag pro Handlung und Monat, Gegenpartei, Eskalationsschwelle. Den gebundenen Wortlaut prüfen und das Mandat aktivieren.

  3. 3 · API-Schlüssel erzeugen

    Einstellungen → API-Schlüssel. Scopes: agents:present, verify, consumptions:write, executions:write, mandates:read, evidence:read. Der Schlüssel wird genau einmal angezeigt.

  4. 4 · Die drei Aufrufe einbauen

    Vor der Handlung signieren lassen und prüfen, danach verbuchen und melden. Die Mandats-ID steht auf der Detailseite des Mandats.

Die Aufrufe

Umgebung: MANDACT_API_KEY und MANDATE_ID. Die Handlung muss bei present und verify identisch sein — beide Seiten binden denselben Kontext-Digest.

Absicht signieren lassen (Weg 1)

curl -s -X POST https://mandact.com/api/v1/agents/present \
  -H "authorization: Bearer $MANDACT_API_KEY" \
  -H "content-type: application/json" \
  -d '{"mandate_id":"'$MANDATE_ID'",
       "action":{"type":"purchase.goods",
                 "amount":{"value":120,"currency":"CHF"},
                 "counterparty":"ACME AG"}}' > pres.json
# → { presentation, custody: "custodial", note }

Prüfen — gehandelt wird nur bei «allow»

curl -s -X POST https://mandact.com/api/v1/verify \
  -H "authorization: Bearer $MANDACT_API_KEY" \
  -H "content-type: application/json" \
  -H "idempotency-key: $(uuidgen)" \
  -d '{"presentation":'"$(jq .presentation pres.json)"',
       "action":{"type":"purchase.goods",
                 "amount":{"value":120,"currency":"CHF"},
                 "counterparty":"ACME AG"}}'
# → allow:    { decision, consumption_token, receipt, mat_compact }
# → deny:     { decision, reasons: ["MD-302"], reason_text, receipt }
# → escalate: { decision, escalation: { id, expires_at } }

Nach der Handlung: verbuchen und Ausführung melden

curl -s -X POST https://mandact.com/api/v1/consumptions \
  -H "authorization: Bearer $MANDACT_API_KEY" -H "content-type: application/json" \
  -d '{"consumption_token":"<token>","final_amount":120,"currency":"CHF",
       "action_type":"purchase.goods","counterparty":"ACME AG",
       "context_digest":"'"$(jq -r .presentation.ctx pres.json)"'"}'
curl -s -X POST https://mandact.com/api/v1/executions \
  -H "authorization: Bearer $MANDACT_API_KEY" -H "content-type: application/json" \
  -d '{"reservation_token":"<token>","outcome":"erfolgreich",
       "executed_amount":120,"executed_currency":"CHF","external_ref":"PO-4711"}'

Beleg als Streitfall-Dossier holen und ohne Mandact prüfen

curl -s "https://mandact.com/api/v1/verifications/<rcp_…>/dossier?mat=<mat_compact>" \
  -H "authorization: Bearer $MANDACT_API_KEY" > dossier.json
node verify-dossier.mjs dossier.json --mat <mat_compact>
# → VALID … MAT: gueltig (ES256, kid …)

Weg 2: Der Agent signiert selbst

Der Beispiel-Agent erzeugt einen Ed25519-Schlüssel und zeigt dessen did:key. Diese tragen Sie im Assistenten bei «Kennung» ein; Mandact speichert nur den öffentlichen Schlüssel und signiert für diesen Agenten nie. Die Presentation muss die Organisation mitsignieren, bei der sie geprüft wird — den Wert liefert der Status-Endpunkt als presentation_verifier.

node beispiel-agent.mjs schluessel
# → agent-key.pem + did:key:z6Mk…
curl -s https://mandact.com/api/v1/mandates/$MANDATE_ID/status -H "authorization: Bearer $MANDACT_API_KEY"
# → { limits, agent_did, presentation_verifier }
AGENT_KEY_FILE=agent-key.pem node beispiel-agent.mjs allow

Weg 3: Durch das Gateway

Zum Ausprobieren ohne eigenes Zielsystem gibt es ein neutrales Echo-Ziel, das nur zurücksagt, was ankam — ohne Nebeneffekte.

  1. Konnektoren → neue Instanz → Gateway einrichten. Ziel: https://mandact.com/api/sandbox/echo, Mandat wählen, optional ein Ziel-Credential hinterlegen. Das Token gwt_… wird einmal angezeigt.
  2. Einen ersten POST senden. Mandact legt das Werkzeug «http.post:/bestellung» an und lehnt ab, solange es keiner Handlung Ihres Mandats zugeordnet ist.
  3. In der Instanz das Werkzeug der Handlung zuordnen, etwa purchase.goods. Danach entscheidet das Mandat.
curl -s -X POST https://mandact.com/api/gateway/http/bestellung \
  -H "authorization: Bearer $GATEWAY_TOKEN" -H "content-type: application/json" \
  -d '{"amount":120,"currency":"CHF","counterparty":"ACME AG"}' -i
# allow → X-Mandact-Decision: allow, X-Mandact-Receipt: rcp_…
# deny  → HTTP 403 { error: "mandact_deny", reasons, receipt_id }

Der Beispiel-Agent

Eine Datei, nur Node ≥ 20, keine Abhängigkeiten. Er liest die Grenzen Ihres Mandats und spielt alle drei Wege durch: pruefen, schluessel, allow, ablehnungen, gateway. Konfiguration über MANDACT_API_KEY, MANDATE_ID und optional AGENT_KEY_FILE bzw. GATEWAY_TOKEN. Den Dossier-Prüfer neben den Agenten legen, dann prüft er jedes Dossier offline.

Ehrlicher Stand

Die Identität des Mandanten ist in Stufe 1 selbst deklariert und steht so im Credential. Der Zeitstempel stammt aus der eigenen Datenbank; ein qualifizierter Anker ist in Vorbereitung. Entscheidungen trifft ausschliesslich POST /v1/verify — der Beispiel-Agent und das SDK entscheiden nichts.