ProofedMesh/docs/architecture/v1.1.md

29 KiB

Technische Zielarchitektur: Vertrauenswürdige Kommunikation zwischen Menschen, KI-Agenten und SAP

Status: Architekturvorschlag V1.1 (aktive Diskussionsgrundlage) Vorgänger: v1.0.md — ursprünglicher Entwurf (unverändert archiviert) Änderungen gegenüber V1.0: siehe Abschnitt 0 „Änderungen seit V1.0"

Diese Lösung wird als Identity-Aware Agent Messaging Platform konzipiert: eine Plattform, die Benutzerfreigaben, delegierte Berechtigungen und sämtliche Verarbeitungsschritte kryptografisch nachvollziehbar macht.

Die zentrale Designentscheidung lautet:

Der Benutzer autorisiert den ursprünglichen Geschäftsinhalt. Jeder Agent attestiert anschließend seine eigene Verarbeitung. Der empfangende Agent überprüft die vollständige Kette, bevor er eine Aktion ausführt.

Dabei werden Identität, Berechtigung, Verarbeitung und Nachrichtentransport strikt getrennt.

0. Änderungen seit V1.0

Diese Revision setzt die Richtungsentscheidungen aus der ersten Review-Runde um:

  • Scope Evidence Store (A.1/A.2): kein rechtssicherer, kein WORM-/GoBD-Anspruch. Ziel ist der kryptografische Nachweis einer unverfälschten Kommunikation während eines begrenzten Zeitraums (Default: 1 Jahr). Danach dürfen Nachweise verworfen werden.
  • PII-Trennung (A.1): verbindlich eingezogen. Attestierungen enthalten nur Hashes und Referenzen; personenbezogene Inhalte liegen in einem separaten, redaktionierbaren PII-Store.
  • IdP (A.3, A.5): Pocket ID wird einziger IdP — für Menschen und Agenten. Begründung und Mechanik in Abschnitt 3a. Keycloak wird nicht eingeführt.
  • Content Binding (A.4): eigener Abschnitt 4.0 als verbindliches UX-/Signatur-Protokoll.
  • Workload-Identität (A.5): Agenten authentifizieren sich doppelt — Pocket-ID-client_credentials-Token plus projiziertes Kubernetes-ServiceAccount-Token. Signing Service verifiziert beide.
  • Schlüsselbund-Scope (A.6): Historische Schlüssel werden nur für die aktive Nachweis-Retention vorgehalten (Default 1 Jahr). Rotation Default 90 Tage → max. ~5 Schlüssel pro Agent gleichzeitig gültig für die Verifikation.
  • Transparency Log (A.7, B.2): PostgreSQL + Trillian-Merkle-Log statt Cassandra. Begründung in Abschnitt 8.
  • Replay-Schutz (A.8) und Fachliche Integritätsprüfung (A.9): jetzt verbindliche Abschnitte 5.1 und 6.1.
  • ABAP-Token (A.10): manuell im SAP-System hinterlegt (bestätigt). Rotationsprozess siehe Abschnitt 7.
  • Matrix (B.1): verschoben in optionale Phase 5, nur für Mensch↔Agent-Chat. Agent↔Agent-Transport ist HTTPS/mTLS + NATS JetStream.
  • Signing Service (B.3): eigenes Deployment von Tag 1.
  • Phase 1 (B.4): End-to-End-Pfad mit einem Agenten als Abschluss.
  • predicateType-Namespace (B.5): https://basicstack.de/attestations/<domain>/<version>.

1. Zielarchitektur

Logische Komponentenübersicht, keine direkte Netzwerktopologie. Freigabe- und Attestierungsnachweise werden über eigene APIs erstellt und geprüft; der Transport (HTTPS/mTLS + NATS, optional Matrix) überträgt nur Referenzen und Nachrichten — nie die Vertrauensentscheidung.

2. Die fünf Architekturprinzipien

  1. Unveränderliche Benutzerfreigabe — ein vertrauenswürdiger Dienst bestätigt den konkret autorisierten Geschäftsinhalt.
  2. Eigene Identität jedes Agenten — jeder Agent besitzt eine separate kryptografische Identität und signiert seine eigenen Verarbeitungsschritte.
  3. Verkettete Attestierungen — jeder Verarbeitungsschritt referenziert exakte Eingabe- und Ausgabe-Hashes.
  4. Unabhängige Autorisierung — eine Signatur allein erteilt keine Berechtigung; eine Policy Engine kontrolliert erlaubte Transformationen und ERP-Aktionen.
  5. Transportneutralität — Nachweise funktionieren über HTTP, NATS, Queue oder Matrix, ohne dass die kryptografische Vertrauenskette verloren geht.

3. Konkrete technische Komponenten

Dienst Technologie Verantwortung
Identity Provider Pocket ID Benutzeranmeldung (Passkey) und Agent-Clients (OIDC)
Approval Service Go, REST API Inhaltsgebundene Benutzerfreigabe
Agent Registry PostgreSQL Agentenidentitäten, Schlüsselhistorie, Berechtigungen
Signing Service Go + OpenBao (Transit) DSSE-Signaturen, verifiziert Agenten-Identität doppelt
Attestation Service Go + in-toto Verarbeitungsschritte dokumentieren
Policy Decision Point Open Policy Agent (OPA) Berechtigungen und Transformationsregeln
Verification Service Go Gesamte Vertrauenskette überprüfen
Transparency Log Trillian + PostgreSQL Append-only Merkle-Log mit Inclusion Proofs
Message Transport HTTPS/mTLS + NATS JetStream Agent↔Agent-Kommunikation
Chat Transport (opt.) Matrix/Synapse Mensch↔Agent-Chat (nur Phase 5)
SAP Connector ABAP REST API / OData Validierte Buchungsaufträge
Evidence Store PostgreSQL (Metadaten) + S3 DSSE-Envelopes und Attestate (Retention: 1 Jahr)
PII-Store Verschlüsselt in S3 Belege und Geschäftsdaten, redaktionierbar

Approval, Attestation, Registry und Verification bleiben in einem modularen Go-Dienst zusammengefasst. Separate APIs und Module bleiben erhalten, aber der Betrieb vieler kleiner Microservices wird vermieden. Signing Service läuft als eigenes Deployment mit separater Trust-Boundary.

3a. Identity Provider: warum Pocket ID reicht

Pocket ID unterstützt neben dem Authorization-Code-Flow auch den OIDC client_credentials-Grant (Endpunkt POST /api/oidc/token) und bietet eine Standard-OIDC-Discovery inkl. JWKS unter https://auth.basicstack.de/.well-known/openid-configuration. Damit decken wir beide Welten:

  • Menschen melden sich per Passkey (WebAuthn) über den normalen Authorization-Code-Flow an.
  • Agenten werden in Pocket ID als eigene OIDC-Clients registriert (ein Client pro Agent, z.B. agent-travel, agent-sap-mapping, agent-sap-posting). Jeder Client erhält eine client_id + ein client_secret, das im zugehörigen Kubernetes-Namespace als Secret hinterlegt wird. Der Agent holt sich daraus ein kurzlebiges Access-Token per client_credentials.
  • SAP (bzw. die ABAP-Validierungs-Webservice-Logik aus Abschnitt 7) kann denselben Pocket-ID-JWKS-Endpunkt nutzen, um ein von Agent C präsentiertes Token zu verifizieren — ohne Federation, ohne weiteren IdP.

Keycloak wird nicht eingeführt. Das spart einen betriebskritischen Dienst.

4. Datenmodell der Vertrauenskette

Jeder Vorgang (z.B. Reisekostenabrechnung) erhält eine unveränderliche workflow_id. Jede Fassung der Daten wird als eigenes Artefakt mit SHA-256-Hash gespeichert. Der Hash liegt im Evidence Store; der Inhalt (PII) liegt im separaten PII-Store.

Vertrauens- und Verarbeitungskette

  1. Benutzerfreigabe — Approval Service bindet die Signatur an den Hash des Inhalts, den der Benutzer tatsächlich im Browser gesehen und per Content Binding bestätigt hat (siehe 4.0), und an die OIDC-Identität des Mitarbeiters.
  2. Agent A: Vorbereitung — Agent A signiert eine Attestierung über Eingabe-Hash, Ausgabe-Hash, Transformationsart und die ursprüngliche Freigabe.
  3. Agent B: SAP-Mapping — Agent B signiert seine eigene Attestierung und referenziert die Ausgabe von Agent A.
  4. Agent C: SAP-Buchung — Agent C überprüft die komplette Kette und erzeugt nach erfolgreicher Buchung einen signierten Buchungsnachweis.

Attestierungen sind keine Chatnachrichten, sondern eigenständige, überprüfbare Datensätze.

4.0 Content Binding bei der Benutzerfreigabe

Das Risiko: der Browser könnte dem Benutzer etwas anderes zeigen als dem Approval Service.

Verbindlicher Ablauf:

  1. Approval Service rendert den Freigabe-Inhalt serverseitig, berechnet dessen SHA-256-Hash H_content und speichert (session_id, H_content, salt) zusammen mit einem einmaligen challenge_nonce.
  2. Browser zeigt den Inhalt und eine aus H_content + challenge_nonce abgeleitete, menschenlesbare Prüfziffer (z.B. 6 Zeichen Base32) als visuelles Fingerprinting an.
  3. Benutzer bestätigt per Passkey (WebAuthn-Signatur über challenge_nonce || H_content). Die WebAuthn-Challenge enthält H_content als Teil der Assertion-Daten — der Hardware-Authenticator signiert damit explizit das, was der Server und (per Prüfziffer) der Benutzer gesehen haben.
  4. Approval Service verifiziert die WebAuthn-Assertion gegen den registrierten Passkey, prüft, dass die Session-Daten unverändert sind, und erzeugt erst dann die DSSE-signierte Approval-Attestierung.

Damit scheitert ein kompromittierter Browser, der dem Benutzer eine andere Zahl zeigt, am visuellen Prüfziffer-Vergleich oder am WebAuthn-Signaturinhalt.

4.1 Benutzerfreigabe (DSSE-Statement)

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    {
      "name": "expense/EXP-2026-0042/v1",
      "digest": { "sha256": "<64 hex characters>" }
    }
  ],
  "predicateType": "https://basicstack.de/attestations/approval/v1",
  "predicate": {
    "workflow_id": "WF-0042",
    "approval_id": "APR-0042",
    "schema": {
      "name": "expense.canonical",
      "version": "1.0.0"
    },
    "issuer": "approval-service",
    "user": {
      "iss": "https://auth.basicstack.de",
      "sub": "user-12345"
    },
    "content_binding": {
      "method": "webauthn-content-hash-v1",
      "assertion_hash": "sha256:<webauthn assertion hash>",
      "verification_code": "F3K-9MQ"
    },
    "action": "expense.submit",
    "audience": "sap-expense-workflow",
    "allowed_transformations": ["expense.normalize", "expense.map_to_sap"],
    "nonce": "<base64 nonce for replay protection>",
    "issued_at": "2026-10-25T10:30:00Z",
    "expires_at": "2026-11-01T00:00:00Z"
  }
}

Der Approval Service darf dieses Dokument nur erzeugen, wenn die WebAuthn-Signatur über dem Content-Hash gültig ist. Ein Agent darf diesen Endpunkt nicht mit einer frei angegebenen Benutzer-ID aufrufen.

4.2 Signatur mit DSSE

{
  "payloadType": "application/vnd.in-toto+json",
  "payload": "<base64-encoded statement>",
  "signatures": [
    { "keyid": "approval-service-key-2026-q4", "sig": "<base64-encoded signature>" }
  ]
}

DSSE's Pre-Authentication Encoding (PAE) signiert Nutzlast und Inhaltstyp gemeinsam. keyid ist nur Hinweis — die Identität ergibt sich aus der verifizierten Signatur gegen das in der Agent Registry zum issued_at gültige öffentliche Schlüsselmaterial.

4.3 Transformations-Attestierung (Beispiel Agent B)

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    {
      "name": "expense/EXP-2026-0042/sap-payload",
      "digest": { "sha256": "<output hash>" }
    }
  ],
  "predicateType": "https://basicstack.de/attestations/transform/v1",
  "predicate": {
    "workflow_id": "WF-0042",
    "actor": "agent-sap-mapping",
    "operation": "expense.map_to_sap",
    "materials": [
      { "name": "expense/EXP-2026-0042/normalized", "sha256": "<input hash>" }
    ],
    "parent_attestation": "sha256:<previous proof hash>",
    "approval_ref": "APR-0042",
    "schema": {
      "input":  { "name": "expense.canonical",     "version": "1.0.0" },
      "output": { "name": "sap.expense.payload",   "version": "1.2.0" }
    },
    "transform_version": "1.3.0",
    "issued_at": "2026-10-25T10:31:15Z"
  }
}

Agent B signiert diese Attestierung mit seinem eigenen Schlüssel.

4.4 Agentenregistrierung und Schlüsselhistorie

Jeder Agent ist in zwei Systemen eingetragen:

  • Pocket ID: als OIDC-Client (client_id, client_secret im K8s-Secret).
  • Agent Registry (unsere Postgres-Tabelle): die Identität plus Signatur-Schlüsselhistorie.

Schema (vereinfacht):

CREATE TABLE agents (
  agent_id          TEXT PRIMARY KEY,
  pocket_id_client  TEXT UNIQUE NOT NULL,
  k8s_namespace     TEXT NOT NULL,
  k8s_service_account TEXT NOT NULL,
  display_name      TEXT NOT NULL,
  allowed_actions   TEXT[] NOT NULL,
  created_at        TIMESTAMPTZ NOT NULL
);

CREATE TABLE agent_keys (
  key_id            TEXT PRIMARY KEY,          -- z.B. "agent-travel-2026-q4"
  agent_id          TEXT NOT NULL REFERENCES agents(agent_id),
  public_key_pem    TEXT NOT NULL,             -- Ed25519
  valid_from        TIMESTAMPTZ NOT NULL,
  valid_to          TIMESTAMPTZ NOT NULL,
  revoked_at        TIMESTAMPTZ,
  revocation_reason TEXT,
  archived_at       TIMESTAMPTZ                -- gesetzt wenn außerhalb Retention
);

CREATE INDEX idx_agent_keys_lookup
  ON agent_keys (agent_id, archived_at)
  WHERE archived_at IS NULL;

Validierung alter Attestierungen nutzt den Schlüssel, der zum issued_at der Attestierung galt (valid_from ≤ issued_at < valid_to, nicht revoked_at vor issued_at). Das ist das TUF-Pattern.

Retention und Performance. Default-Rotation 90 Tage, Nachweis-Retention 1 Jahr → pro Agent max. ~5 nicht-archivierte Schlüssel. Beim Überschreiten der Retention wird der Schlüssel auf archived_at gesetzt; alte Attestierungen, die noch im Evidence Store liegen, aber über diese Grenze hinaus zu validieren wären, werden explizit abgelehnt (decision: expired_retention). Damit bleibt der aktive Keyring klein und die Validierung konstant schnell — auch bei 100+ Agenten.

5. Verifikation beim empfangenden Agenten

Der SAP-Agent darf sich nicht auf die mitgesendeten IDs verlassen. Er muss die gesamte Nachweiskette prüfen.

POST /api/v1/attestations/verify
Authorization: Bearer <service-token>
Content-Type: application/json
{
  "workflow_id": "WF-0042",
  "artifact_digest": "sha256:<final hash>",
  "requested_action": "expense.post_to_sap",
  "target": "sap-s4hana-prod"
}
Prüfung Fehlerfall
Signatur der Benutzerfreigabe gültig (Schlüssel zum issued_at gültig)? Ablehnen
Content-Binding-Assertion in der Approval-Attestierung vorhanden? Ablehnen
Benutzeridentität im Pocket-ID-JWKS auflösbar? Ablehnen
Freigabe gültig, nicht widerrufen, nicht abgelaufen? Ablehnen
Alle Agentensignaturen gültig gegen agent_keys zur issued_at? Ablehnen
Agenten zum Signaturzeitpunkt registriert und berechtigt? Ablehnen
Input-/Output-Hashes der Materialien-Kette konsistent? Ablehnen
Transformationen laut Freigabe zulässig? Ablehnen
Schema-Version der kanonischen Daten mit Approval kompatibel? Ablehnen
SAP-Nutzlast entspricht freigegebener Geschäftssemantik (OPA)? Ablehnen
payload_hash bereits für target gebucht? Keine erneute Buchung

Erfolgsantwort:

{
  "valid": true,
  "workflow_id": "WF-0042",
  "original_user": { "issuer": "https://auth.basicstack.de", "subject": "user-12345" },
  "actors": ["agent-travel", "agent-sap-mapping"],
  "authorized_action": "expense.post_to_sap",
  "artifact_digest": "sha256:<final hash>",
  "decision_id": "DEC-2026-0042",
  "decision_nonce": "<base64>",
  "bound_to_agent": "agent-sap-posting",
  "bound_to_target": "sap-s4hana-prod",
  "expires_at": "2026-10-25T10:36:00Z"
}

Diese Decision ist eine kurzlebige, an Agent C + Payload-Hash + Target gebundene Ausführungsberechtigung.

5.1 Replay-Schutz (verbindlich)

  • decision_id enthält einen eigenen decision_nonce, Lebensdauer 5 Minuten.
  • Decision ist gebunden an (agent_id, payload_hash, target) — Zieländerung oder Agent-Wechsel invalidiert sie.
  • Verification Service hält eine Postgres-Tabelle decisions mit UNIQUE (payload_hash, target) für den Doppelbuchungs-Check.
  • SAP-Connector führt eine eigene Replay-Tabelle (sap_decision_log) mit UNIQUE (decision_id). Beide Prüfungen sind unabhängig voneinander — Defence in Depth.
  • Doppelbuchung wird gegen payload_hash (nicht nur workflow_id) geprüft, damit minimal veränderte Nutzlasten nicht durchrutschen.

6. Berechtigungssteuerung mit Open Policy Agent

Beispiel-Regeln:

  • Agent A darf Belege extrahieren und Reisekosten strukturieren.
  • Agent B darf Kontierungsinformationen ergänzen und SAP-Felder zuordnen.
  • Agent B darf keine Beträge oder Währungen ohne zusätzliche Freigabe ändern.
  • Agent C darf ausschließlich vollständig validierte Reisekostenabrechnungen buchen.

Rego-Policies werden zentral verwaltet und versioniert; die zum Entscheidungszeitpunkt verwendete Policy-Version wird im Evidence Store mit abgelegt.

6.1 Fachliche Integritätsprüfung — Schema-Versionierung (verbindlich)

Ein Hashvergleich allein reicht nicht, weil sich beim Mapping das technische Format verändert. Deshalb binden wir die Freigabe an ein versioniertes kanonisches Schema:

{
  "schema": { "name": "expense.canonical", "version": "1.0.0" },
  "employee_id": "EMP-12345",
  "currency": "EUR",
  "total_amount": "428.50",
  "expense_items": [
    { "type": "HOTEL", "amount": "328.50" },
    { "type": "MEALS", "amount": "100.00" }
  ]
}

Verbindlich:

  • Schemas werden als JSON Schema in schemas/ im Repo versioniert.
  • Jede Approval-Attestierung signiert schema.name und schema.version mit.
  • Jede Transform-Attestierung signiert Input- und Output-Schema.
  • OPA-Policies arbeiten gegen das kanonische Schema; sie prüfen z.B. „Agent B darf total_amount nicht verändern" oder „Agent B darf expense_items[].amount höchstens kaufmännisch runden".
  • Schema-Änderungen sind Breaking Changes und erfordern eine neue Hauptversion.

7. SAP S/4HANA Integration

Für die S/4HANA-2023-Umgebung ist eine ABAP-Integrationsschicht vorgesehen, statt Agent C direkten Zugriff auf Buchungsfunktionen zu geben.

Fluss: Agent C → ABAP REST Endpoint (Authentifizierung · Freigabenachweis · Idempotenz) → SAP-Anwendungslogik (Mitarbeiterzuordnung · fachliche Prüfungen · Buchung).

POST /sap/bc/zexpense/v1/submit
Authorization: Bearer <sap-agent-token>
Idempotency-Key: WF-0042
Content-Type: application/json
{
  "workflow_id": "WF-0042",
  "approval_id": "APR-0042",
  "verification_ref": "DEC-2026-0042",
  "expense_ref": "EXP-2026-0042",
  "payload_hash": "sha256:<final hash>"
}

Zusätzlich stellt ProofedMesh einen Validierungs-Webservice bereit, den das ABAP vor der Buchung aufruft:

POST /api/v1/decisions/{decision_id}/replay-check

Rückgabe: ob die Decision noch gültig, nicht verbraucht, an Agent C gebunden und für dieses target autorisiert ist. Damit braucht SAP keine eigene Krypto-Logik.

Zwei unabhängige Prüfungen in SAP:

  • Technische Identität: Der Aufruf kommt vom autorisierten SAP-Agenten (Bearer-Token-Prüfung).
  • Fachliche Identität: Der freigebende Benutzer wird über eine serverseitig gepflegte Zuordnung der korrekten SAP-Personalnummer zugeordnet. Eine vom Agenten gelieferte Personalnummer darf diese Zuordnung nicht überschreiben.

sap-agent-token wird manuell im SAP-System hinterlegt. Rotationsprozess:

  1. Signing Service oder Operator generiert neues Token (JWT, 90-Tage-Gültigkeit) und signiert es mit dem Service-Schlüssel von Agent C.
  2. Operator trägt neues Token in SAP ein (Transaktion SM59 oder äquivalent, abhängig von der konkreten SAP-Konfiguration).
  3. Agent C erhält das neue Token über ein K8s-Secret; alte Secrets werden nach einer Übergangszeit entfernt.
  4. SAP-Validierung akzeptiert alte und neue Token, solange sie signiert sind — die Agent-Identität wird aus dem Token-sub gelesen, nicht aus dem Token-Material selbst.

Welche SAP-Buchungsschnittstelle verwendet wird (SAP Travel Management, Concur, kundeneigener FI-Prozess), bleibt in einem späteren ADR offen — architektonisch ist das austauschbar.

SAP-Auditdaten

Zusätzlich zum ERP-Beleg: Tabelle ZAGENT_AUDIT.

Feld Inhalt
WORKFLOW_ID Eindeutige Prozess-ID
APPROVAL_ID Benutzerfreigabe
USER_SUB Externe Benutzeridentität
PERNR Zugeordnete Personalnummer
AGENT_ID Buchender Agent
PAYLOAD_HASH SHA-256 der Buchungsdaten
VERIFICATION_ID Verifikationsentscheidung
DECISION_ID Replay-Check-Referenz
BUKRS / BELNR / GJAHR FI-Belegreferenz
CREATED_AT Buchungszeitpunkt

Idempotenz: UNIQUE (WORKFLOW_ID) und UNIQUE (DECISION_ID). Bei N fehlgeschlagenen Buchungsversuchen landet der Vorgang in einer SAP-Operator-Queue zur manuellen Prüfung — kein stiller Datenverlust.

8. Nachweisablage und Transparency Log

8.1 Scope und Retention

Ziel: kryptografisch belegen, dass die Agent-Kommunikation unverfälscht gelaufen ist, und diese Prüfung auch nachträglich zulassen. Kein rechtssicheres GoBD-Archiv.

Retention Default: 1 Jahr. Nach Ablauf werden Attestierungen, Decisions und zugehörige Schlüsselhistorie automatisiert gelöscht (archived_at + Cron-Job). Konfigurierbar pro Prozess-Typ.

8.2 Datenklassen

Daten Speicherung
Prozessstatus, Identitäten, Referenzen PostgreSQL (trust-postgres)
Signierte Attestierungen (DSSE) S3 Object Storage
Transparency-Log-Einträge + Proofs Trillian + PostgreSQL
Reisekostenbelege und Geschäftsdaten Verschlüsselt in S3 (separater Bucket, PII-Store)
Signatur- und Schlüsselhistorie Agent Registry (Postgres), max 1 Jahr
Policy-Versionen Git-versioniert, Hash im Evidence Store

Strikte Trennung PII vs. Nachweis: Der PII-Store (Belege, Namen, Kostenstellen) ist unabhängig vom Evidence Store löschbar. Löscht ein Benutzer per DSGVO-Antrag seine Daten, verschwinden die Belege; die Hashes und Signaturen in Evidence Store und Transparency Log bleiben erhalten, verifizieren aber dann nur noch „diese Kette existierte", nicht mehr „ihr Inhalt war X".

8.3 Warum Trillian + PostgreSQL (nicht Cassandra)

Ein Transparency Log ist ein append-only Merkle-Tree mit Inclusion Proofs und periodisch signiertem Tree-Root (Signed Tree Head). Entscheidend sind:

  • Strikte Reihenfolge aller Einträge (eine lineare Sequenznummer).
  • Starke Konsistenz zwischen Logeintrag und Merkle-Root — der Root muss nach jedem Append reproduzierbar berechnet werden können.
  • Inclusion Proofs auf Anfrage, idealerweise in ms.

Cassandra ist für diese Zugriffsmuster architektonisch ungeeignet: eventual consistency, ordering nur per Partition, keine serialisierbare globale Sequenz. Es wäre technisch möglich, aber mit erheblichem Over-Engineering (externer Sequencer, Lock-Dienst) — und würde sigstore's Entscheidung widersprechen.

Empfehlung: Google Trillian als Transparency-Log-Engine (ist die Grundlage von sigstore rekor), gestützt auf PostgreSQL — das ist unsere ohnehin vorhandene Infrastruktur. Für unser erwartetes Volumen (< 1 Mio. Einträge/Jahr, Single-Tenant) läuft das auf einer kleinen Instanz. Der Log-Root wird täglich signiert und ins Backup-System gespiegelt — damit ist eine nachträgliche Manipulation durch den DB-Admin erkennbar.

Falls Trillian als Dependency zu schwer wirkt, Alternative: eine eigene minimale Append-Only-Postgres-Tabelle mit stündlich berechnetem Merkle-Root und Export des Roots als signiertes JSON — deutlich weniger Funktionalität (keine Inclusion Proofs auf Anfrage), aber ausreichend für unseren Scope.

9. Deployment in Kubernetes

Namespaces und Dienste:

identity/
  pocket-id             (bestehend)

agent-trust/
  trust-api             (Approval + Attestation + Registry + Verification)
  signing-service       (eigenes Deployment, enge Trust-Boundary)
  policy-engine         (OPA)
  trust-postgres
  trillian-log          (Transparency Log)

transport/
  nats                  (JetStream für Agent↔Agent)

paperclip/
  paperclip
  agent-travel
  agent-sap-mapping
  agent-sap-posting

openbao/
  openbao               (Transit Engine für Signaturschlüssel)

matrix/                 (optional, Phase 5)
  synapse
  element-web
  agent-matrix-gateway

Signing Service: eigenes Deployment, dediziertes Pocket-ID-Client-Secret, eigener ServiceAccount, NetworkPolicy erlaubt eingehend nur die Agent-Namespaces. Agenten rufen den Signing-Endpunkt auf; private Schlüssel verlassen OpenBao nie.

9.1 Workload-Identitäts-Prüfung (doppelt)

Der Signing Service verifiziert für jeden eingehenden Request beide Credentials:

  1. Pocket-ID-Access-Token (Header Authorization: Bearer <token>) — gegen Pocket-ID-JWKS validiert; sub = agent-<name> muss zu einem registrierten Agent in der Agent Registry gehören.
  2. Projected ServiceAccount-Token (Header X-Workload-Token: <token>, Audience signing-service.agent-trust) — gegen Kubernetes-TokenReview-API validiert; Namespace + ServiceAccount müssen zum Agent in der Agent Registry passen.

Nur wenn beide Prüfungen zum selben agent_id auflösen, wird signiert. Damit ist weder ein geleaktes Pocket-ID-Secret allein noch ein kompromittierter Pod außerhalb des erwarteten Namespaces ausreichend.

OpenBao's Transit Engine signiert mit Ed25519. Caveat: Transit kennt kein DSSE — der Signing Service berechnet die DSSE-Pre-Authentication-Encoding (PAE) selbst und übergibt nur den Hash an Transit. Backup via Transit-Export-Policy und Snapshot der OpenBao-Instanz.

10. Implementierungsreihenfolge

Phase 1 — End-to-End-Skelett (3 bis 5 Wochen) Pocket ID als IdP (Mensch und Agent-Client), Approval Service mit Content Binding, ein Testagent mit Ed25519-Schlüssel in der Agent Registry, Signing Service mit doppelter Identitätsprüfung, Verification Service für die zweistufige Kette (Approval → Agent → Simulierte Senke). Deliverable: ein signierter Durchlauf vom Login bis zur simulierten SAP-Senke.

Phase 2 — Agent Attestations in Breite Weitere Agenten, Schlüsselrotation, in-toto-Transformationsnachweise, Materialien-Hash-Kette, OPA-Policies in Rego, Policy-Versionierung.

Phase 3 — Replay-Schutz, Transparency Log, Retention Trillian-Deployment, Decision-Nonce-Mechanik, Decision-Replay-Tabelle, Retention-Cron-Job, PII-Store-Trennung.

Phase 4 — SAP-Integration ABAP-Endpunkt, serverseitige Mitarbeiterzuordnung, SAP-seitige Replay-Prüfung über Validierungs-Webservice, Operator-Queue.

Phase 5 — Matrix für Mensch-Chat (optional) Nur Mensch↔Agent-Chat, E2EE. Agent↔Agent läuft weiterhin über NATS/HTTPS.

11. Was bewusst anders ist als in V1.0

  • Matrix ist nicht Standard-Transport — nur optionale Mensch-Chat-Schicht in Phase 5. Intern NATS JetStream + HTTPS/mTLS.
  • Transparency Log ist eine eigene Komponente, nicht nur „Postgres-Tabelle".
  • Signing Service ist eigenes Deployment ab Tag 1.
  • PII-Store ist strikt getrennt vom Evidence Store.
  • Keine Unveränderbarkeits-/GoBD-Garantien — Retention 1 Jahr, dann Löschung.
  • Pocket ID ist alleiniger IdP — Keycloak entfällt.

12. Empfohlener Kernstack (Zielbild)

Identität Pocket ID (Menschen + Agent-Clients)
Workload-ID K8s projected ServiceAccount Token + TokenReview
Signaturen Ed25519 / DSSE, OpenBao Transit
Provenienz in-toto v1, predicate-Namespace basicstack.de/attestations/*/*
Autorisierung OPA (Rego) + Approval Service
Transparency Trillian + PostgreSQL
Transport HTTPS/mTLS + NATS JetStream (Agent↔Agent); Matrix optional (Mensch)
Agenten Paperclip
ERP SAP S/4HANA / ABAP REST + Validierungs-Webservice
Evidence PostgreSQL + S3 (Retention 1 Jahr)
PII Separater verschlüsselter S3-Bucket, redaktionierbar

Wichtigste Empfehlung bleibt: Zuerst in Phase 1 ein vollständiger signierter Testprozess von der Benutzerfreigabe bis zur simulierten SAP-Senke, mit genau einem Agenten. Matrix und ADRs für Schema/OPA-Deep-Dive folgen danach.