Zum Inhalt springen

Das Sicherheitsmodell einer ERP-Integration

Schlüssel und Scopes, Geheimnisse und Rotation, Transport, sichere Wiederholungen, Outbox, dünne Ereignisse, veraltete Schreibvorgänge, Datenminimierung, Audit-Trail und die OWASP API Top 10.

Eine Integration zwischen Ihrem ERP und BatteryPass bewegt Daten, die in signierten, öffentlichen Batteriepässen landen. Diese Seite sammelt die Regeln, die diesen Weg sicher machen. Die meisten liegen auf Ihrer Seite der Verbindung; wo BatteryPass etwas selbst durchsetzt, steht es dabei. Den Umgang mit Schlüsseln im Alltag beschreibt Schlüssel sicher verwalten.

Schlüssel und Scopes

Ein Schlüssel je Integration und je Umgebung. Eine Test-Middleware und die produktive Middleware bekommen verschiedene Schlüssel, ebenso zwei Integrationen in derselben Middleware. So können Sie einen widerrufen, ohne die anderen anzuhalten, und die Spalte Zuletzt verwendet im Portal zeigt, welcher aktiv ist.

So wenig Scope wie möglich. Ein Schlüssel hat einen oder mehrere von drei Scopes:

ScopeErlaubt dem SchlüsselAbläufe
readModelle, Einheiten, Werte, Pässe, Exporte und den Änderungsfeed lesenPass-Links zurück ins ERP, Produktänderung, Abfragen in den übrigen Abläufen
conditionGemessene Zustandsdaten und Lebenszyklus-Ereignisse meldenZustandsdaten, Rücksendungen und Reparaturen
importTabellenimporte von Einheiten hochladen, zuordnen, prüfen lassen und lesenEinheiten aus der Fertigung

Kein Scope erlaubt es, einen Import zu übernehmen, einen Wert freizugeben, zu veröffentlichen, zurückzuziehen, Mitglieder oder Schlüssel zu verwalten oder deklarierte Daten zu ändern. Das bleibt bei Mitgliedern Ihrer Organisation im Portal. Ein Schlüssel handelt mit den Rechten eines Betrachters plus seinen Scopes und ist nie auf einzelne Einheiten beschränkt: Ein condition-Schlüssel kann für jede Einheit Ihrer Organisation melden.

Geheimnisse

  • Bewahren Sie jeden Schlüssel in einem Secrets-Manager oder Vault auf (HashiCorp Vault, Azure Key Vault, AWS Secrets Manager, der Anmeldedatenspeicher der iPaaS) und übergeben Sie ihn dem Prozess beim Start. Nie in Code, versionierte Konfiguration, Container-Images, URLs, Logs oder Tickets. Das OWASP Secrets Management Cheat Sheet beschreibt die Praxis im Detail.
  • Senden Sie den Schlüssel nur im Header Authorization: Bearer bp_live_…. Eine Anfrage, die zusätzlich ein Sitzungs-Cookie des Portals trägt, wird abgelehnt; so ist nie unklar, wer handelt.
  • Maskieren Sie den Header Authorization in jedem Log Ihrer Middleware und Ihres HTTP-Clients.

Rotation. Schlüssel laufen nicht ab. Rotieren Sie nach eigenem Plan und immer dann, wenn jemand ausscheidet, der einen Schlüssel kannte: neuen Schlüssel mit denselben Scopes anlegen, die Middleware darauf umstellen, prüfen, dass der neue Schlüssel eine aktuelle Zeit unter Zuletzt verwendet zeigt, dann den alten widerrufen. Während der Umstellung funktionieren beide, es fällt also nichts aus. Der Widerruf wirkt sofort und endgültig.

Transport

  • Rufen Sie BatteryPass nur über HTTPS (TLS) auf und prüfen Sie das Serverzertifikat. Schalten Sie die Prüfung auch in Testumgebungen nicht ab: Middleware-Konfigurationen wandern gern von Test nach Produktion.
  • Egress-Allowlisting als zweite Linie: Erlauben Sie der Middleware nur die Adresse von BatteryPass und das ERP. Das ersetzt weder Schlüssel noch TLS, begrenzt aber, mit wem eine kompromittierte Middleware sprechen kann.
  • Umgekehrt genauso: Machen Sie die APIs des ERP nur der Middleware zugänglich, nie direkt aus dem Internet.

Wiederholungen ohne Duplikate

Netze fallen aus. Eine Anfrage mit Zeitüberschreitung wurde vielleicht ausgeführt, vielleicht nicht; Wiederholungen müssen also sicher sein.

Zurückhaltend wiederholen. Wiederholen Sie Netzfehler und 5xx-Antworten mit exponentiellem Backoff und Jitter (etwa 1, 2, 4, 8 Sekunden plus ein Zufallsanteil, höchstens fünf Versuche). Auf 429 rate_limited warten Sie die Sekunden aus dem Header Retry-After ab; alle Schlüssel Ihrer Organisation teilen sich 600 Anfragen pro Minute. Andere 4xx-Antworten wiederholen Sie nicht: Die Anfrage wurde als Ganzes abgelehnt, korrigieren Sie sie. Einzelheiten stehen in Fehler und Wiederholungen behandeln und Ratenlimits.

Jede Wiederholung sicher machen. Einen Header Idempotency-Key nimmt BatteryPass nur bei Sammel- und Veröffentlichungsoperationen des Portals an, die Schlüssel nicht aufrufen können. Bei den Operationen eines Schlüssels kommt die Sicherheit aus den Operationen selbst und aus Ihrer Middleware:

OperationWiederholbarWarum, oder was Sie tun
Jedes GET (Lesen, Änderungsfeed, getImport)JaSie ändern nichts.
updateConditionJa, mit demselben measured_atEine gleich alte oder ältere Messung als die gespeicherte wird übersprungen.
createImportJa, mit BedachtEin wiederholter Upload legt einen zweiten Import an. Seine Zeilen werden zu Duplikaten, sobald der erste übernommen ist, sodass keine Einheit doppelt entsteht; Mitglieder übernehmen den überzähligen Import einfach nicht.
updateImportMappingJaMit demselben If-Match wird die Wiederholung als veraltet abgelehnt (409); lesen Sie den Import, sehen Sie die Zuordnung bereits angewandt.
validateImportJaEin zweiter Start, während die erste Prüfung läuft, wird abgelehnt (409); fragen Sie stattdessen den Import ab.
createLifecycleEventNeinJeder Aufruf legt ein neues Ereignis an. Merken Sie sich, welchen Quellsatz (etwa den Serviceauftrag) Sie schon gemeldet haben, und sehen Sie nach einer Zeitüberschreitung in listLifecycleEvents nach, bevor Sie erneut senden.

Die IETF arbeitet an einem allgemeinen Header Idempotency-Key (draft-ietf-httpapi-idempotency-key-header, Entwurf 08, noch kein RFC). Für Ihre eigenen APIs ist das ein nützlicher Hintergrund; BatteryPass nimmt ihn bei den Operationen oben nicht an.

Die Outbox auf ERP-Seite

Das ERP darf keine Änderung verlieren, während die Middleware oder BatteryPass nicht erreichbar ist, und es darf BatteryPass nicht innerhalb seiner eigenen Geschäftstransaktion aufrufen. Die transaktionale Outbox löst beides: In derselben Datenbanktransaktion, die den Wareneingang bucht, schreibt das ERP (oder eine Erweiterung) eine Zeile in eine Ausgangstabelle. Die Middleware liest die Outbox, ruft BatteryPass auf und markiert die Zeile erst nach einer erfolgreichen Antwort als erledigt.

Das ergibt Zustellung mindestens einmal: Eine Zeile kann zweimal gesendet werden (bei einem Absturz zwischen Aufruf und Markierung), nie keinmal. Kombinieren Sie das mit den Regeln oben und führen Sie eine kleine Tabelle dessen, was Sie schon gesendet haben (Quellsatz, BatteryPass-ID, Zeitpunkt), damit Sie auf Ihrer Seite Duplikate erkennen.

Dünne Ereignisse, dann abholen

Bewegen Sie keine Daten in Benachrichtigungen. Beide Richtungen funktionieren gleich:

  • Vom ERP: Viele ERP-Systeme senden dünne Ereignisse (eine Produktnummer und die Art der Änderung). Die Middleware liest danach den aktuellen Satz über die API des ERP, prüft Signatur, Handshake oder geheime URL des Herstellers und verwirft Ereignisse, die sie nicht prüfen kann.
  • Von BatteryPass: Der Änderungsfeed nennt nur {id, occurred_at, entity_type, entity_id, action}, nie Werte, Handelnde oder personenbezogene Daten. Die Middleware liest die Entität danach mit demselben Schlüssel; der Feed verrät für sich allein also nichts und ist immer aktuell.

Der Feed liefert eine Änderung erst, wenn jede ältere Transaktion in BatteryPass beendet ist; ein gespeicherter Cursor überspringt also nie eine Änderung, die spät festgeschrieben wurde. Speichern Sie den Cursor erst, wenn Ihre Seite die Seite verarbeitet hat. Ausgehende Webhooks sendet BatteryPass noch nicht; sie sind geplant und brauchen eine eigene Entscheidung (Signatur, Verwaltung der Abonnements, Schutz der Zieladressen). Bis dahin fragen Sie ab.

Veraltete Schreibvorgänge

Änderbare Ressourcen tragen eine row_version. updateImportMapping verlangt If-Match: "<row_version>"; hat jemand anderes den Import inzwischen geändert, lautet die Antwort 409 conflict, und nichts wird überschrieben. Lesen Sie den Import neu und entscheiden Sie. Zustandsdaten haben eine eigene Regel: Eine ältere Messung ersetzt nie eine neuere.

Datenminimierung

Die DSGVO verlangt Daten, die „dem Zweck angemessen und erheblich sowie auf das notwendige Maß beschränkt“ sind (Art. 5 Abs. 1 lit. c). Für einen Batteriepass heißt das: Daten über die Batterie, also Seriennummer, Modell, Daten, Messwerte, Ereignisse. Namen und Adressen von Kundinnen und Kunden, Auftragsnummern, Namen von Beschäftigten, Preise, Fahrzeug- und Standortdaten bleiben im ERP. Jeder Ablauf nennt, was er sendet und was er weglässt; der Überblick nennt, was nie fließt.

Freitext ist die Stelle, an der personenbezogene Daten hineinrutschen: Eine Ereignisbeschreibung wie „repariert für Herrn X in Y“ landet in der Historie Ihrer Batterie. Füllen Sie Beschreibungen aus festen Codes oder Vorlagen, nicht aus dem Freitext eines Serviceauftrags.

Der Audit-Trail

  • Jeder Schreibvorgang mit einem Schlüssel steht im Audit-Log Ihrer Organisation, mit dem Handelnden-Typ api_key und dem Namen des Schlüssels: Bereitstellen und Prüfen eines Imports, eine Zustandsmeldung, ein Lebenszyklus-Ereignis.
  • Importe, die ein Schlüssel bereitgestellt hat, nennen den Schlüssel statt eines Mitglieds (created_by_api_key), in der API und im Portal.
  • Werte, die ein Schlüssel schreibt, tragen den Schlüssel nicht selbst. Eine Zustandsmeldung legt ein Lebenszyklus-Ereignis condition_update an, und dieses Ereignis nennt den Schlüssel (api_key).
  • Zustandsdaten werden als freigegebene Messungen ohne Prüfer gespeichert. Deklarierte Daten nehmen den geprüften Weg: Importierte Werte gibt ein Prüfer frei, und ob eine zweite Person freigeben muss, legt die Vier-Augen-Einstellung Ihrer Organisation fest.
  • Lesezugriffe werden nicht festgehalten. Gehen Sie davon aus, dass die Daten eines abhandengekommenen Schlüssels gelesen wurden.

OWASP API Security Top 10

Wie die Risiken der OWASP API Security Top 10 (2023), die für eine ERP-Integration am meisten zählen, behandelt werden, und was Ihr Teil bleibt:

RisikoIn BatteryPassIhr Teil
API1:2023 Broken Object Level AuthorizationJede Abfrage ist auf die Organisation des Schlüssels gefiltert; die ID einer anderen Organisation ergibt 404.Ein Schlüssel je angebundener Organisation; nie Mandanten in einem Middleware-Ablauf mischen.
API4:2023 Unrestricted Resource Consumption600 Anfragen pro Minute für alle Schlüssel einer Organisation, 30 Versuche je 15 Minuten für unbekannte Schlüssel, Request-Bodys bis 1 MiB, Uploads bis 10 MB und 10 000 Zeilen, Listen mit höchstens 200 Einträgen.Bei 429 zurückhalten, mit limit und cursor blättern, Dateien in Stapeln senden.
API5:2023 Broken Function Level AuthorizationJede Operation nennt ihren Scope (x-api-key-scope); ein Schlüssel ohne ihn erhält 403, Operationen des Portals nehmen gar keine Schlüssel an (401).Jedem Schlüssel nur die Scopes geben, die sein Ablauf nennt.
API7:2023 Server Side Request ForgeryBatteryPass ruft keine Adressen auf, die eine Integration liefert; Webhooks gibt es noch nicht.Holt die Middleware URLs aus ERP-Ereignissen ab, die Ziele per Allowlist begrenzen.
API10:2023 Unsafe Consumption of APIsBatteryPass prüft jeden Wert nach den Regeln des Registers, gleich aus welcher Quelle.ERP-Ereignisse und Antworten von BatteryPass als nicht vertrauenswürdige Eingaben behandeln: prüfen, Signaturen kontrollieren, wo der Hersteller sie anbietet, und empfangene Inhalte nie ausführen.

Auf dieser Seite