Je lisais la documentation relative à la politique d’identité de @NewtonProtocol et une ligne m’a stoppé net : toute erreur dans une règle Rego signifie que la règle évalue à « indéfini ». Et « indéfini » est traité comme un refus.

Ça sonne sûr. En réalité, c’est toute l’histoire ici.

L’affirmation

Les fonctions internes d’identité de Newton (newton.identity.kyc.*) sont conçues pour être « fail-closed ». Si une date ne peut pas être analysée, si un code pays est mal formé ou si un tableau est vide, la politique ne génère pas d’erreur bruyamment. Elle refuse simplement, discrètement. Aucune exception, aucun crash, aucun message « veuillez vérifier vos données ». Juste : non autorisé.

C’est une posture de conformité délibérée. Mais cela signifie aussi que des données d’entrée mauvaises et une violation réelle de politique se ressemblent à l’extérieur, au même niveau d’abstraction.

Ce que la documentation montre réellement

age_gte(min_age) compare la date de naissance à une date de référence. Si la chaîne de date de naissance ne peut pas être analysée, ou si le nombre fourni est négatif, la fonction échoue et la règle entière s'effondre en indéfini.

address_in_countries(), address_in_subdivision() et address_not_in_subdivision() échouent de la même façon si vous passez des noms de pays complets au lieu de codes ISO, ou par erreur un tableau vide.

not_expired() et valid_for(min_days) dépendent toutes deux du fait que expiration_date soit présente et analysable. L’absence de ce champ n’est pas un « on passe ce contrôle » : c’est un non catégorique.

address_not_in_subdivision() est intéressant en soi. Il est conçu pour exclure quelques États (par exemple, US-NY, US-HI) plutôt que d’en autoriser explicitement 48 autres. Efficace. Mais cela signifie qu’un seul code ISO erroné bloque silencieusement des utilisateurs qui remplissent pourtant techniquement les conditions.

Rien de tout cela n’est un bug. Newton choisit le refus par défaut (« denial-by-default ») plutôt que l’autorisation par défaut (« permissive-by-default »). Pour le KYC, c’est sans doute le bon instinct. La plupart des systèmes de conformité préféreraient refuser un bon utilisateur plutôt qu’approuver un mauvais.

La tension

Voici la partie qui me gêne un peu.

Si votre intégration envoie #Newt une issue_date légèrement mal formée, ou si votre fournisseur KYC renvoie une subdivision vide, la personne est refusée, comme si elle était mineure ou provenait d’une région bloquée. Il n’y a aucun message d’erreur au niveau du champ renvoyé à la couche applicative, du moins d’après ce document que je vois. Juste un booléen false, indiscernable d’un échec réel de politique.

Pour un développeur qui débogue « pourquoi cet utilisateur a été rejeté », c’est un point de départ vraiment pénible. On ne peut pas le savoir uniquement à partir du résultat de la politique, notamment :

l’utilisateur a réellement échoué au contrôle, ou

votre pipeline de données a envoyé du n’importe quoi dans Newton

Même sortie. Correctif très différent.

Ce que je vérifierais avant de m’y fier

Pas une critique, juste la liste que j’exécuterais vraiment si j’intégrais Newton :

Où les données d’identité sont-elles validées avant d’arriver au moteur de politique ? Existe-t-il une vérification de schéma en amont, ou Newton reçoit-il directement le format brut fourni par le prestataire KYC ?

Les appels intégrés qui échouent sont-ils consignés quelque part de façon distincte des refus légitimes, ou tout apparaît-il simplement comme « non autorisé » dans la trace d’audit ?

Les formats de codes ISO (pays, subdivision) sont-ils imposés au moment de l’ingestion des données, ou uniquement vérifiés paresseusement quand une règle de politique s’exécute ?

Que se passe-t-il pour age_gte si la date de naissance est présente, mais dans un format de date légèrement différent de celui attendu, avec un échec silencieux de l’analyse, ou une erreur explicite ?

Y a-t-il un moyen de distinguer « refusé parce que mineur » de « refusé parce que le champ de date était mal formé » dans le tableau de bord ou les journaux que Newton expose ?

Pour address_not_in_subdivision, y a-t-il une limite de taille sur le tableau d’exclusion, et un tableau vide se comporte-t-il par défaut comme « autoriser tout » ou « refuser tout » ?

Si la réponse à la plupart de ces questions est « pas de visibilité », ce n’est pas rédhibitoire : le « fail-closed » reste le bon défaut pour l’identité. Mais cela signifie que le travail d’intégration ne consiste en réalité pas à écrire des règles Rego. Il s’agit de s’assurer que des données propres parviennent à Newton avant même que la politique ne s’exécute. La couche de politique n’est fiable que dans la mesure de ce qui l’alimente.

Notes sur le risque, clairement

Le principe du « fail-closed » masque les bugs liés à la qualité des données. Un refus ne vous dit pas quel mode de défaillance vous avez rencontré. Ce n’est pas un risque de sécurité, mais c’est un risque opérationnel : cela vous fera perdre du temps en tickets support.

Pas de mécanisme visible de nouvelle tentative ou de contournement dans la documentation. Si un utilisateur légitime est refusé à cause d’un problème de format en amont, rien ici ne décrit comment cela est corrigé sans une re-soumission manuelle.

Les listes d’exclusion déplacent le risque en aval. address_not_in_subdivision est pratique, mais cela signifie que la charge de maintenir cette liste d’exclusion à jour repose entièrement sur la personne qui a écrit la politique, et non sur Newton.

Fait vs opinion, puisque c’est important ici

Fait : la documentation indique qu’une erreur intégrée fait que la règle englobante s’évalue à indéfini, et Newton traite l’indéfini comme un refus.

Opinion : cela crée un angle mort de débogage pour les intégrateurs, parce que le même booléen s’affiche que l’utilisateur ait échoué au contrôle ou que les données soient simplement mauvaises.

Je ne pense pas que ce soit un défaut dans la conception de Newton. Le « fail-closed » est le bon choix pour une politique d’identité. Je pense juste que la documentation sous-estime à quel point une grande partie du travail d’intégration réel va être de l’hygiène des données avant même que Rego ne s’exécute, plutôt que Rego lui-même.

Bref. Je continue quand même à lire la référence du SDK pour voir s’il y a des erreurs remontées que je n’aurais pas vues.

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