Ich habe die Identitätsrichtlinien-Dokumente von @NewtonProtocol gelesen, und eine Zeile hat mich aufgehalten: Ein beliebiger Fehler in einer Rego-Regel bedeutet, dass die Regel als undefiniert ausgewertet wird. Und undefiniert wird als eine Verweigerung behandelt.

Das klingt sicher. Tatsächlich ist das die ganze Geschichte hier.

Die Behauptung

Newtons Identitäts-Built-ins (newton.identity.kyc.*) sind per Design fail-closed. Wenn ein Datum nicht geparst werden kann oder ein Ländercode ungültig ist oder ein Array leer ist, produziert die Richtlinie keinen lauten Fehler. Sie verweigert einfach still und leise. Keine Ausnahme, kein Absturz, keine Meldung „bitte überprüfe deine Daten“. Nur: nicht autorisiert.

Das ist eine bewusste Compliance-Haltung. Aber es bedeutet auch, dass schlechte Eingabedaten und eine echte Policy-Verletzung von außen identisch aussehen.

Was die Doku tatsächlich zeigt

age_gte(min_age) vergleicht das Geburtsdatum mit einem Referenzdatum. Wenn der Geburtsdatums-String nicht geparst werden kann oder die angegebene Zahl negativ ist, schlägt die Funktion fehl und die gesamte Regel fällt auf undefiniert.

address_in_countries(), address_in_subdivision() und address_not_in_subdivision() schlagen alle auf die gleiche Weise fehl, wenn du vollständige Ländernamen statt ISO-Codes übergibst oder aus Versehen ein leeres Array.

not_expired() und valid_for(min_days) hängen beide davon ab, dass expiration_date vorhanden und parsebar ist. Fehlt dieses Feld, ist das kein „diesen Check überspringen“, sondern ein klares Nein.

address_not_in_subdivision() ist für sich genommen interessant. Es ist dafür gebaut, eine Handvoll Bundesstaaten auszuschließen (z. B. US-NY, US-HI) statt 48 andere zu erlauben. Effizient. Aber es bedeutet auch, dass ein einzelner falscher ISO-Code Nutzer still und leise blockiert, die technisch gesehen qualifiziert wären.

Nichts davon ist ein Bug. Newton entscheidet sich für Ablehnung als Standard (deny-by-default) statt für Erlaubnis als Standard (allow-by-default). Bei KYC ist das – zumindest argumentierbar – der richtige Instinkt. Die meisten Compliance-Systeme würden lieber einen guten Nutzer ablehnen als einen schlechten freizugeben.

Die Spannung

Der Teil, der mich ein wenig stört.

Wenn deine Integration etwas mit einem leicht falsch formatierten issue_date liefert, oder dein KYC-Anbieter eine leere address_subdivision zurückgibt, wird die Person abgelehnt – genauso, als wäre sie minderjährig oder käme aus einer blockierten Region. Es wird kein feldbezogener Fehler zurück an die App-Schicht gespiegelt, zumindest nicht, was ich in dieser Doku sehe. Nur ein boolean false, nicht unterscheidbar von einem echten Policy-Fail.

Für jemanden, der als Entwickler „warum wurde dieser Nutzer abgelehnt?“ debuggt, ist das ein wirklich nerviger Startpunkt. Man kann es allein aus dem Policy-Ergebnis nicht erkennen, ob:

der Nutzer den Check tatsächlich nicht bestanden hat oder

deine Daten-Pipeline hat Müll in Newton geschickt

Gleiches Ergebnis. Sehr andere Lösung.

Was ich verifizieren würde, bevor ich mich darauf verlasse

Keine Kritik, sondern die Liste, die ich tatsächlich durchgehen würde, wenn ich Newton integrieren würde:

Wo werden die Identity-Daten validiert, bevor sie die Policy-Engine erreichen? Gibt es eine Schema-Prüfung vorgelagert oder sieht Newton direkt die Rohausgabe des KYC-Providers?

Werden fehlgeschlagene eingebaute Aufrufe irgendwo protokolliert, die sich von legitimen Verweigerungen unterscheiden? Oder taucht dann einfach alles als „nicht autorisiert“ in der Audit-Übersicht auf?

Werden ISO-Code-Formate (Land, Subdivision) beim Einlesen der Daten erzwungen oder erst träge überprüft, wenn eine Policy-Regel läuft?

Was passiert mit age_gte, wenn das Geburtsdatum vorhanden ist, aber in einem leicht anderen Datumsformat als erwartet übergeben wird: stiller Parse-Fehler oder expliziter Fehler?

Gibt es eine Möglichkeit, „abgelehnt, weil unterjährig“ von „abgelehnt, weil das Datumsfeld falsch formatiert war“ zu unterscheiden – in welchem Dashboard oder in welchen Logs Newton auch immer bereitstellt?

Bei address_not_in_subdivision: Gibt es eine Größenbeschränkung für das Ausschluss-Array, und wird ein leeres Array standardmäßig als „alles erlauben“ oder „alles verweigern“ behandelt?

Wenn die Antwort auf die meisten dieser Punkte „keine Sichtbarkeit“ ist, dann ist das nicht zwingend ausschlaggebend – fail-closed ist als Standard für Identity trotzdem richtig. Es heißt aber, dass die Integrationsarbeit eigentlich nicht darum geht, Rego-Regeln zu schreiben. Es geht darum sicherzustellen, dass saubere Daten Newton erreichen, bevor die Policy überhaupt läuft. Die Policy-Schicht ist nur so vertrauenswürdig wie das, was sie speist.

Risikohinweise, ganz offen

Fail-closed verdeckt Fehler in der Datenqualität. Eine Verweigerung sagt dir nicht, welchen Fehlmodus du getroffen hast. Das ist ein operatives Risiko, kein Sicherheitsrisiko – aber es wird dich Support-Tickets kosten.

Kein sichtbarer Retry- oder Override-Pfad in der Doku. Wenn ein legitimer Nutzer abgelehnt wird, weil upstream ein Format-Mismatch vorliegt, gibt es hier nichts, was beschreibt, wie das korrigiert wird, ohne eine manuelle erneute Übermittlung.

Ausschlusslisten verschieben das Risiko nachgelagert. address_not_in_subdivision ist praktisch, aber es heißt, dass die Verantwortung, diese Ausschlussliste aktuell zu halten, komplett bei der Person liegt, die die Policy geschrieben hat – nicht bei Newton.

Fakt vs. Meinung, weil das hier wichtig ist

Fakt: Die Doku sagt, dass ein eingebauter Fehler dazu führt, dass die enthaltene Regel als undefiniert ausgewertet wird, und Newton behandelt undefiniert als Verweigerung.

Meinung: Das schafft eine blinde Debugging-Stelle für Integratoren, weil derselbe Boolean auftaucht, egal ob der Nutzer den Check nicht bestanden hat oder die Daten einfach schlecht waren.

Ich glaube nicht, dass das ein Fehler im Newton-Design ist. Fail-closed ist die richtige Entscheidung für Identity Policy. Ich denke nur, dass die Doku zu wenig hervorhebt, wie viel vom realen Integrationsaufwand sich um Datenhygiene dreht, bevor überhaupt Rego ausgeführt wird – nicht um die Rego selbst.

Wie auch immer. Ich lese trotzdem noch durch die SDK-Referenz, um zu sehen, ob mir eine Fehler-Transparenz entgeht_

$NEWT #NewtonProtocol #NEWTtoken #NEWTUSDT $BEE $PALU