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:
| Scope | Erlaubt dem Schlüssel | Abläufe |
|---|---|---|
read | Modelle, Einheiten, Werte, Pässe, Exporte und den Änderungsfeed lesen | Pass-Links zurück ins ERP, Produktänderung, Abfragen in den übrigen Abläufen |
condition | Gemessene Zustandsdaten und Lebenszyklus-Ereignisse melden | Zustandsdaten, Rücksendungen und Reparaturen |
import | Tabellenimporte von Einheiten hochladen, zuordnen, prüfen lassen und lesen | Einheiten 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
Authorizationin 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:
| Operation | Wiederholbar | Warum, oder was Sie tun |
|---|---|---|
Jedes GET (Lesen, Änderungsfeed, getImport) | Ja | Sie ändern nichts. |
updateCondition | Ja, mit demselben measured_at | Eine gleich alte oder ältere Messung als die gespeicherte wird übersprungen. |
createImport | Ja, mit Bedacht | Ein 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. |
updateImportMapping | Ja | Mit demselben If-Match wird die Wiederholung als veraltet abgelehnt (409); lesen Sie den Import, sehen Sie die Zuordnung bereits angewandt. |
validateImport | Ja | Ein zweiter Start, während die erste Prüfung läuft, wird abgelehnt (409); fragen Sie stattdessen den Import ab. |
createLifecycleEvent | Nein | Jeder 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_keyund 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_updatean, 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:
| Risiko | In BatteryPass | Ihr Teil |
|---|---|---|
| API1:2023 Broken Object Level Authorization | Jede 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 Consumption | 600 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 Authorization | Jede 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 Forgery | BatteryPass 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 APIs | BatteryPass 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. |
Überblick
Wie ein ERP, seine Middleware und BatteryPass zusammenarbeiten, wer was tut und was Ihre Systeme nie verlässt.
Einheiten aus der Fertigung
Seriennummern fertiger Batterien mit einem Schlüssel mit Scope import als Import bereitstellen; Mitglieder prüfen, übernehmen, geben frei und veröffentlichen im Portal.