Si la plupart des idées crypto géolocalisées de 2020 sont mortes en silence, c’est qu’elles faisaient confiance au GPS. Le GPS est un signal diffusé que n’importe quel récepteur peut écouter, et on peut dire à un récepteur de mentir sur ce qu’il a entendu. Les outils pour le faire coûtent une trentaine de dollars sur Amazon, et c’est le cas depuis 2015. Tout protocole qui paie un portefeuille pour se tenir à une coordonnée, et qui vérifie cette présence uniquement par GPS, perd de l’argent au profit de faux portefeuilles installés sur des canapés. Ce n’est ni une attaque difficile ni une attaque astucieuse.

La preuve de localisation est la couche qui règle ce problème. L’expression est plus souvent employée que définie, alors commençons par une définition. Une preuve de localisation est une affirmation, vérifiable par quelqu’un qui n’était pas présent, qu’un appareil précis se trouvait à une coordonnée précise dans une fenêtre de temps précise. C’est une affirmation sur la présence, pas sur la coordonnée. C’est dans cette distinction que se trouve l’essentiel du travail d’ingénierie.

Le modèle de menace. Nous ne nous défendons pas contre un État ; ce cas extrême vient à la fin. Nous nous défendons contre l’attaquant moyen, avec un téléphone, un ordinateur portable et un après-midi. Cet attaquant peut falsifier le GPS avec un outil du commerce, faire tourner l’appli dans un émulateur et créer un portefeuille en une ligne de code. Chaque contrôle pris isolément peut être contourné par cet attaquant. L’objectif d’ingénierie est de rendre le coût de les contourner tous ensemble supérieur à la récompense du drop.

Cet article décrit ce que Seek fait aujourd’hui, en termes simples, et ce qui arrive. Il est volontairement plus court côté marketing et plus long côté mécanique.

Couche un, au moment de la capture : l’attestation de l’appareil. Chaque demande de capture porte une déclaration signée par le système d’exploitation. Sur iOS, c’est Apple App Attest ; sur Android, Google Play Integrity. Seek vérifie les deux côté serveur. L’attestation dit trois choses en une seule signature : c’est un vrai appareil, le binaire de l’appli n’a pas été modifié, et l’appelant détient une clé créée sur cet appareil pour notre application. Un téléphone rooté échoue. Un émulateur échoue. Une appli reconditionnée qui a sauté la vérification de position échoue. L’attestation ne prouve pas où se trouve le téléphone ; elle prouve que le téléphone ne ment pas sur le fait d’être un téléphone. C’est ce qui donne du poids aux autres signaux.

Couche deux, au moment de la capture : la distance avec une marge de tolérance. L’appli ne te laisse toucher le bouton de capture que si tu es dans le rayon de récupération du spawn. Le serveur compare de son côté les coordonnées que tu as envoyées à celles du spawn, et accepte jusqu’à soixante-quinze mètres d’écart. L’écart entre le rayon du bouton et le rayon du serveur est voulu. L’imprécision GPS d’un téléphone posé contre un mur peut dériver de quelques mètres sans que ce soit ta faute, et refuser des captures à l’intérieur de cette marge paraît arbitraire. Au-delà de soixante-quinze mètres, la demande est rejetée d’office, sans score et sans recours à ce niveau.

Couche deux, suite : limites de fréquence et plafonds par spawn. Deux demandes de récupération à moins de cinq secondes d’intervalle reçoivent un 429 d’une barrière adossée à Postgres, qui tient d’une instance serverless à l’autre. Un même spawn accepte au plus deux tentatives du même compte, la deuxième valant 65 pour cent de la première. Ces plafonds ne servent pas à détecter la fraude ; ils sont là pour qu’un bot qui aurait déjà passé les autres couches ne puisse pas exploiter l’endpoint plus vite qu’une personne ne peut jouer.

Couche trois, au moment de la capture : les signaux d’environnement, enregistrés mais pas imposés. Chaque capture porte aussi des indicateurs : si la demande vient d’un simulateur, si Android a signalé que la position venait d’un fournisseur de position fictive, et la précision GPS annoncée en mètres. Ils sont enregistrés et ne servent jamais à refuser la capture elle-même. Un client qui ment à leur sujet est justement le client à qui tu ne veux pas confier la décision, donc la décision se prend ailleurs. Ils comptent à la couche quatre.

Couche quatre, au moment du paiement : la barrière antifraude. Les retraits passent par une fonction serveur qui lit les quatre-vingt-dix derniers jours de captures du compte. Si l’une de ces captures vient d’un simulateur, ou si Android a signalé un fournisseur de position fictive, ou si le compte a réussi deux captures à moins de dix secondes d’intervalle, ou s’il s’est déplacé entre deux coordonnées de capture plus vite qu’une personne ne le peut, ou si un autre compte a déjà retiré depuis la même empreinte d’appareil, le retrait part en vérification humaine au lieu d’être approuvé automatiquement. L’utilisateur ne sait pas quel fil a été déclenché, et son compte continue de jouer normalement. La détection est une décision commerciale sur les paiements, pas une sanction.

Si nous séparons capture et paiement, c’est qu’ils protègent des choses différentes. La couche de capture protège le jeu. Si la capture était frauduleuse, elle devient une monnaie de jeu qui ne quitte jamais l’appli, ce qui ne coûte rien. La couche de paiement protège l’argent réel. Chaque dollar qui quitte le système passe par l’examen sur quatre-vingt-dix jours de ce qui a mené au solde, et un seul signal suspect dans cette fenêtre suffit à confier la décision à un humain. Ensemble, les deux couches font qu’un joueur honnête ne ressent aucune friction au moment de la capture, et qu’un attaquant qui a glissé une mauvaise capture ne voit jamais l’argent.

Couche cinq, au moment de la capture : la trace de mouvement. Chaque téléphone possède un accéléromètre et un gyroscope sur la même puce que le GPS. Seek enregistre désormais une courte fenêtre de mouvement pendant les secondes qui précèdent une capture, calcule un petit ensemble de statistiques (variance de magnitude, activité de rotation, nombre d’images immobiles) et envoie ce résumé avec la demande de récupération. Un téléphone qui a marché jusqu’à un spawn a une signature de mouvement différente de celle d’un téléphone posé sur un bureau avec un simulateur GPS actif. Cette signature n’est pas imposée à la couche de capture aujourd’hui, pour la même raison que les indicateurs d’environnement : un client modifié peut mentir. Elle entre dans la barrière antifraude sur quatre-vingt-dix jours, à côté des signaux de simulateur et de position fictive, et une trace de mouvement plate dans l’historique est un fil de plus qui envoie un retrait en vérification humaine.

Un exemple concret. Un testeur lance un falsificateur GPS, règle la coordonnée sur un drop Seek à l’autre bout de la ville, et touche Capturer. La vérification de distance passe, puisque la coordonnée falsifiée correspond. L’attestation passe, puisque l’appli n’est pas modifiée. La capture est enregistrée. Deux heures plus tard, le même testeur fait trois autres captures, dont une depuis une coordonnée située à dix kilomètres. La trace de mouvement des quatre est plate (le téléphone n’a jamais bougé), et le contrôle de déplacement impossible se déclenche sur les deux coordonnées impossibles à relier à pied en deux heures. Le compte continue de jouer, de récolter, et ne se doute de rien. Quand le testeur demande un paiement, la demande atterrit sur un bureau de vérification humaine, avec l’indicateur de déplacement impossible et la trace de mouvement plate en pièces jointes. Le vérificateur refuse. Les quarante dollars de solde accumulés par le testeur ne vaudront jamais rien hors de l’appli.

Le cadre économique. Ce qui compte, ce n’est pas que falsifier la capture elle-même soit impossible ; c’est que la barrière de paiement relit tout ce que le compte a fait pour arriver à son solde. Un drop de deux euros protégé par l’attestation et la distance est bon marché à attaquer une fois et inutile à attaquer en boucle, parce que la vérification au retrait repère le schéma avant qu’il ne devienne de l’argent. Un drop de dix mille euros exige un cadre plus solide à la couche de capture, et c’est l’objet de la feuille de route ci-dessous.

Ce qui est sur la feuille de route. Le prochain contrôle à arriver, c’est la balise de secours pour les drops en intérieur. Pour un spawn placé dans un bâtiment où le GPS ne veut rien dire, une petite balise Bluetooth enregistrée pour le drop permet à l’appli de prouver la présence sans dépendre du tout du positionnement satellite. Le second chantier, c’est l’application stricte de l’attestation : aujourd’hui, les demandes non attestées sont journalisées mais encore acceptées, pour que nous puissions mesurer le taux de faux rejets sur les appareils légitimes avant d’actionner l’interrupteur et de les refuser d’office. Les deux arriveront comme de petits ajouts, sobres et vérifiables, au même schéma capture et paiement déjà en place.

Ce qui ne marche toujours pas bien. Le GPS en intérieur se trompe de dix à quinze mètres dans un centre commercial, et aucune astuce côté serveur n’y change rien ; la vraie réponse est une balise, c’est pourquoi elle est sur la feuille de route. Une latence inférieure à la seconde n’est pas au rendez-vous et ne le sera probablement pas, parce que la barrière antifraude lit un historique plutôt qu’une demande isolée. Les objets portables ont moins de capteurs que les téléphones, donc une preuve de localisation calibrée pour les téléphones ne se transpose pas proprement aux lunettes. Et un État avec un camion d’équipement radio peut aujourd’hui déjouer n’importe quel vérificateur sur téléphone ; tout protocole qui prétend le contraire n’est pas honnête avec toi. Le nôtre ne le prétendra pas.

Le principe de conception qui mérite d’être dit tout haut. Un vérificateur doit être honnête sur ce qu’il peut et ne peut pas prouver. Présenter un score probabiliste comme un oui ou un non absolu est pire que présenter un oui ou un non absolu issu de règles strictes, parce qu’un score crée un curseur, et que tout curseur finit poussé vers l’acceptation de plus de demandes quand les objectifs d’engagement sont en retard. Notre couche de capture n’a pas de curseur. Soit elle passe les contrôles, soit non. La couche antifraude a un curseur, et ce curseur est entre les mains d’un humain, pas dans le code.

C’est cette brique, sous Seek, qui donne du sens aux assets ancrés et aux airdrops vérifiés par la localisation. Un éditeur place un token de vraie valeur à une coordonnée parce que la personne qui finit par l’avoir se trouvait à cette coordonnée avec un appareil attesté, et parce que la barrière de paiement relira l’historique du compte avant que l’argent ne bouge. Le livre blanc contient la spécification complète. Cet article en est la version en langage clair, pour ce qui se passe dans l’appli.

En bref. La présence n’est pas une coordonnée. Un seul signal ne prouve pas la présence. Seek vérifie la présence en deux temps : attestation, distance et trace de mouvement au moment de la capture, et une barrière antifraude sur quatre-vingt-dix jours au moment du paiement. Le seul chantier encore ouvert, la balise de secours pour les drops en intérieur, ferme le dernier cas de coordonnée que le GPS seul ne sait pas traiter. Voilà ce qu’est vraiment la preuve de localisation dans Seek aujourd’hui, et c’est pourquoi cette couche compte plus que toutes les choses plus spectaculaires qu’elle rend possibles.