## Das Problem, vor dem die meisten Bauherren stehen

Wenn Sie einen Agenten gegen ein Geschäft betreiben, ist die Zuordnung trivial. Sie wissen, wer jede Zeile geschrieben hat. Sie haben dem Agenten geschrieben.

In dem Moment, in dem Sie zwei, drei, fünf Agenten gegen dieselbe Neotoma-Instanz ausführen, [ändert sich das Bild](/posts/when-agents-share-state-everything-breaks). Jeder Agent schreibt Beobachtungen, Beziehungen, Quellen und Interpretationen. Der Speicher sammelt den Status von allen. Wenn einer dieser Agenten anfängt, fehlerhafte Daten, subtil falsche Zusammenfassungen, veraltete Daten oder falsch zugeordnete Beziehungen zu schreiben, besteht die einzige Möglichkeit, herauszufinden, welchen Datensätzen man vertrauen sollte, darin, herauszufinden, welcher Agent sie geschrieben hat.

Ohne Zuordnung pro Zeile stehen Ihnen im Falle eines Fehlers kaum Optionen zur Verfügung: Löschen Sie den Speicher und nehmen Sie ihn erneut auf, oder lassen Sie die fehlerhaften Zeilen drin und leben Sie mit der Abweichung. Beides wird schlimmer, wenn der Laden wächst.

Dieses Problem verschärft sich für jeden, der ein agentengesteuertes Produkt versendet. Die Datensätze Ihrer Kunden werden von einer Flotte geschrieben: Ihren eigenen Agenten, über MCP integrierten Drittanbieter-Agenten, vielleicht einem Plugin, das jemand letzte Woche installiert hat. Wenn ein Kunde fragt: „Wer hat das auf mein Konto geschrieben und in wessen Auftrag?“, muss diese Frage anhand der Daten beantwortet werden können, nicht anhand einer Korrelationsübung über Serverprotokolle und Konversationsprotokolle.

Ich führe Agenten für Cursor, Claude Code, Codex und ChatGPT aus, die alle in eine Neotoma-Instanz schreiben. Ich habe darüber geschrieben, [was dieser Stack eigentlich macht](/posts/what-my-agentic-stack-actually-does). Die AAuth-Integration von Neotoma schließt die Lücke für meinen Stack und für jeden, der darauf aufbaut: Jeder Agent bringt seinen eigenen Schlüssel mit und der Shop kann vertrauenswürdig bleiben, auch wenn die Flotte wächst.

## Warum AAuth

Die Attributionsschicht basiert auf [AAuth](https://www.aauth.dev/), einem offenen Protokoll, das jedem HTTP-Client seine eigene kryptografische Identität verleiht. Keine Voranmeldung. Keine gemeinsamen Geheimnisse. Keine Inhabertoken. Jede Anfrage wird mit [RFC 9421](https://datatracker.ietf.org/doc/html/rfc9421) HTTP-Nachrichtensignaturen signiert, sodass ein gestohlenes Token ohne den Signaturschlüssel wertlos ist.

Ich habe mich für AAuth entschieden, weil die Person dahinter, Dick Hardt, ein Freund und einer der tiefsten Identitätsexperten ist, die ich kenne. Er hat OAuth 2.0 ([RFC 6749](https://www.rfc-editor.org/rfc/rfc6749)) herausgegeben, war Co-Autor von OpenID Authentication 2.0 und war Gründungsmitglied der [OpenID Foundation](https://openid.net/foundation/members/). Dies ist die gleiche Linie, die die meisten Entwickler durch Autorisierungscodeflüsse und föderierte Anmeldung erreichen. Wenn jemand mit dieser Vergangenheit ein neues Protokoll speziell für Agenten startet, lohnt es sich, darauf aufzubauen.

## Was jetzt jeder Schreibvorgang trägt

[v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0) liefert die Agentenzuordnung pro Zeile auf jeder Schreiboberfläche: „/store“, „/observations/create“, „/create_relationship“, „/correct“, „/entities/split“, die MCP-Speichertools und CLI-Schreibvorgänge über MCP und HTTP. Jede Beobachtung, Beziehung, Quelle und Interpretation prägt:

– Eine verifizierte Agenten-ID (Fingerabdruck des öffentlichen Schlüssels für signierte Autoren, JWT-Betreff und Aussteller für Agenten-Tokens, clientInfo-Name und -Version als Fallback).
– Eine Vertrauensstufe, die klassifiziert, wie stark die Identität nachgewiesen ist.
– Der Transport, auf dem der Schreibvorgang angekommen ist.

Fünf Stufen decken das Spektrum ab:

- „Hardware“: Der Agent stellte einen „cnf.attestation“-Umschlag (Apple Secure Enclave, WebAuthn-gepackt oder TPM2) bereit, den der Server anhand vertrauenswürdiger Roots überprüfte.
- „operator_attested“: Die Signatur wurde überprüft und der Betreiber hat den Aussteller oder das Aussteller-Subjekt-Paar auf die Zulassungsliste gesetzt. Der Betreiber bürgt für den Prozess des Agenten, ohne dass eine Hardware-Bescheinigung erforderlich ist.
- „Software“: Der Agent hat die Anfrage mit einem gültigen Schlüssel signiert, der vom Server überprüft wurde. Hier landen heute die meisten Agenten, einschließlich meiner eigenen Cursor-Proxy-Signierung mit einem dateigestützten ES256-JWK.
- „unverified_client“: Der Agent hat sich selbst mit einer erkennbaren clientInfo deklariert, aber nicht signiert.
- „anonym“: überhaupt keine Identität.

Das Ergebnis: Sie können sich jede Zeile in Ihrem Geschäft ansehen und als Lesezugriff auf erstklassige Daten antworten: „Welcher Agent hat das geschrieben?“.

## Gewährt statt Konfigurationsdateien

Zu Beginn des v0.6.0-Zyklus wurden Funktionen aus umgebungsvariablen JSON-Dateien geladen. Das funktionierte für eine statische Gruppe von Agenten, scheiterte jedoch in dem Moment, in dem Sie einen Agenten anhalten wollten, ohne den Server neu zu starten.

Nun: Jeder „agent_grant“ ist eine erstklassige Neotoma-Entität. Es entspricht einer AAuth-Identität (nach Betreff, Aussteller, Fingerabdruck oder einer Kombination), enthält Fähigkeitseinträge, die pro Vorgang und Entitätstyp gelten, und hat einen Lebenszyklus: „aktiv“, „suspendiert“, „widerrufen“. Die Zulassungs-Middleware löst bei jeder Anfrage eine verifizierte AAuth-Identität in die entsprechende Bewilligung auf, stempelt den Benutzer und die Fähigkeiten der Bewilligung in den Anforderungskontext und die nachgelagerte Durchsetzung prüft jeden Vorgang anhand der Bewilligung.

Zuschüsse werden über die Inspector-Benutzeroberfläche, die REST-API („POST /agents/grants“, „PATCH“, Suspend, Revoke, Restore) verwaltet oder einmalig aus der alten Env-Konfiguration über „Neotoma Agents Grants Import“ migriert. Die alten Umgebungsvariablen („NEOTOMA_AGENT_CAPABILITIES_*“) verursachen einen Startfehler, wenn sie noch festgelegt sind, mit einem strukturierten Fehler, der auf den Migrationsbefehl verweist.

Die Aussetzung eines Zuschusses erfolgt sofort. Bei der nächsten Anfrage des Agenten schlägt die Zulassung fehl. Die Wiederherstellung erfolgt ebenso sofort. Kein Serverneustart, kein Neuladen der Konfiguration.

Für jeden, der ein Produkt mit kundenorientierten Agenten betreibt, bedeutet dies, dass sich die Reaktion auf Vorfälle von „Neustart des Dienstes mit einer neuen Konfiguration“ zu „Eine Gewährung aussetzen und untersuchen“ verschiebt. Der Explosionsradius eines sich schlecht benehmenden Agenten ist auf die Vorgänge beschränkt, die eine Genehmigung gewähren.

## Identitäts-Preflight

Jeder Agent kann Neotoma nun vor der Erstellung von Daten fragen, ob er als vertrauenswürdiger Autor erkannt wird.

Drei gleichwertige Einstiegspunkte:

- `GET /session` über HTTP.
- „get_session_identity“ als MCP-Tool.
- „Neotoma-Authentifizierungssitzung“ auf der CLI.

Jeder gibt die aufgelöste Vertrauensstufe, den Gewährungsstatus (zugelassen oder nicht, mit Begründung), die Richtlinie für anonymes Schreiben und einen booleschen Wert „eligible_for_trusted_writes“ zurück. Die Antwort enthält einen Diagnoseblock, der erklärt, wie die Ebene aufgelöst wurde. Ein neuer Agent schlägt zu Beginn der Sitzung lautstark fehl, anstatt anonyme Zeilen zu schreiben, bis es jemand bemerkt.

Die mitgelieferten MCP-Anweisungen weisen jeden verbundenen Agenten an, diese Prüfung durchzuführen, bevor er Schreibvorgänge aktiviert.

## Wo ich das ausführe

Drei verschiedene Servicemitarbeiter in meinem Stapel schreiben heute unter AAuth an Neotoma.

**Cursor MCP-Proxy.** Jede MCP-Anfrage von Cursor durchläuft einen Signatur-Proxy („mcp_identity_proxy.py“), der eine RFC 9421-Signatur mit einem „aa-agent+jwt“-Agenten-Token einfügt. Neotoma überprüft die Signatur, löst die Identität auf (`sub=cursor@markmhendrickson.com`, `iss=https://markmhendrickson.com`), gleicht den `agent_grant` ab und lässt den Schreibvorgang bei `tier=software` zu. Der Proxy führt beim Start auch einen Sitzungs-Preflight durch und kann beim Schließen fehlschlagen, wenn der Server eine anonyme Ebene meldet.

**Feedback-Pipeline.** Ein Netlify-Relay unter „agent.neotoma.io“ leitet Agent-Fehlerberichte über einen AAuth-signierten [Cloudflare Access](https://www.cloudflare.com/zero-trust/)-Tunnel an Neotoma weiter. Die Gewährung ist nur auf „neotoma_feedback“-Operationen beschränkt.

**[Darkmesh](https://github.com/markmhendrickson/darkmesh) Warm-Intro-Writeback.** Mein [Darkmesh-Fork](https://github.com/markmhendrickson/darkmesh/blob/main/docs/neotoma_integration.md) ([context](/posts/the-substrate-plancast-needed)) zeichnet Warm-Intro-Enthüllungen zurück in Neotoma auf RFC 9421-Signaturen und ein „aa-agent+jwt“-Token. Jede Enthüllung landet mit dem „agent_sub“, „agent_iss“ und dem Schlüsselfingerabdruck des Knotens, der durch eine Gewährung pro Knoten begrenzt wird.

Die gemeinsamen Darkmesh-Tests bewiesen die Durchsetzung in kontroverser Form. Ein zweiter simulierter Agent von einem Peer-Knoten versuchte, ein „warm_intro_reveal“ zu schreiben, ohne dass dieser Entitätstyp in seiner Bewilligung enthalten war. Neotoma lehnte das Schreiben ab. Die Schreibvorgänge des autorisierten Knotens wurden unverändert durchgeführt.

Als nächstes auf der Roadmap: Der [öffentliche Agent auf markmhendrickson.com](https://markmhendrickson.com/agent/) verpackt eine Neotoma-Instanz als seinen Speicher und bedient heute nur Entitäten, die ich explizit als öffentlich markiert habe. Ich plane, AAuth-gesteuerte Lesevorgänge hinzuzufügen, damit autorisierte Besucher bestimmte nicht öffentliche Entitätstypen abfragen können. Dieselbe signierte Identität plus Gewährungsmaschinerie, angewendet auf den Lesepfad.

## Flottenweites Upgrade

Neotoma sendet seine kanonischen MCP-Anweisungen bei jedem Handshake vom Server an jeden verbundenen Client. In Version 0.6.0 kodifizieren diese Anweisungen nun den Attributions-Preflight, das „observation_source“-Tagging, Antwort-zitierte Herkunftskanten, eine „Ambiguous (N)“-Anzeigegruppe für heuristische Zusammenführungswarnungen und eine strukturierte Feedback-Übermittlungsschleife.

Als ich meinen Server aktualisiert habe, haben alle meine Cursor-, Claude Code-, Codex- und OpenCode-Hooks die neuen Verhaltensweisen übernommen. Keine clientseitigen Releases. Keine Migration pro Tool. Ein Server-Bump, fünf Agenten aktualisiert. Für jeden, der Kundenflotten betreibt, gilt das gleiche Muster: Aktualisieren Sie die Neotoma-Instanz und jeder verbundene Agent übernimmt die neuen Standardeinstellungen, ohne dass eine Client-Bereitstellung erforderlich ist.

## Die Prüfoberfläche

Für Produktentwickler in regulierten Märkten lautet die Folgefrage eines Kunden selten: „Hat sich Ihr System daran erinnert?“ Es gehe darum, „wer es geschrieben hat, und können Sie nachweisen, dass sie autorisiert waren.“

Nach v0.6.0 handelt es sich um einen Lesevorgang anhand erstklassiger Daten:

- „GET /agents“ zählt jede Agentenidentität auf, die der Server gesehen hat.
- „GET /agents/{key}“ gibt die Detailansicht pro Agent zurück.
- „GET /agents/{key}/records“-Audits, die die Autorisierung eines bestimmten Agenten aufzeichnen.
- „GET /agents/grants“ listet alle Zuschüsse, ihre Fähigkeiten und ihren Lebenszyklusstatus auf.

Wenn Sie Agentenfunktionen an Kunden aus den Branchen Gesundheitswesen, Finanzen, Recht oder Unternehmen liefern, ist dies die Oberfläche, die Ihre Kunden letztendlich nachfragen werden.

## So schalten Sie es ein

„Bash
neotoma auth keygen --alg ES256
neotoma Auth Sign-Beispiel
Neotoma-Authentifizierungssitzung
„

Erstellen Sie über den Inspector oder die REST-API eine Gewährung für die neue Identität und richten Sie dabei die Funktionen auf die Vorgänge aus, die Ihr Agent benötigt. Wenn Sie ein Upgrade vom alten env-config-Modell durchführen, führen Sie „neotoma Agents Grants Import --owner-user-id <your_user_id>“ einmal aus und deaktivieren Sie dann die Legacy-Variablen.

Für die programmgesteuerte Signatur signiert [`@aauth/local-keys`](https://www.aauth.dev/) oder eine entsprechende AAuth-Bibliothek Anfragen mit RFC 9421 HTTP Message Signatures plus einem „aa-agent+jwt“-Token. Neotoma überprüft die Signatur der vom Client signierten Rohbytes.

Schreibvorgänge ohne AAuth funktionieren weiterhin. Sie landen in der „anonymen“ Stufe. Bauherren, die harte Fehler wünschen, können „NEOTOMA_AAUTH_STRICT=1“ umdrehen und bestimmte Themen zu „NEOTOMA_STRICT_AAUTH_SUBS“ hinzufügen.

## Auch versendet

v0.6.0 ist nicht nur AAuth. Die gleiche Version führt zu einer Entitätsaufteilung für übermäßig zusammengeführte Datensätze, Flotten-Snapshot-Export plus Drift-Tooling, erstklassigen Multi-Agent-Konversationen über „conversation_message“ und „sender_kind“ sowie einem verschärften API-Perimeter. Die vollständige Ergänzung finden Sie in [den Versionshinweisen zu v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0).

## Installieren und aktualisieren

„Bash
npm install -g neotoma@[0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0)
Neotom init
Neotoma-Authentifizierungsschlüssel
Neotoma-Authentifizierungssitzung
„

Durch ein Upgrade des Servers erhalten Sie den neuen Attributionsstempel und die MCP-Anweisungsaktualisierung beim nächsten Client-Handshake. Für Agenten, die bereits über MCP verbunden sind, ist keine clientseitige Installation erforderlich.

Vollständige Installation: [neotoma.io/install](https://neotoma.io/install). Repo: [github.com/markmhendrickson/neotoma](https://github.com/markmhendrickson/neotoma). Versionshinweise: [v0.6.0](https://github.com/markmhendrickson/neotoma/releases/tag/v0.6.0).