Aller au contenu
AyiID

Introduction

Concepts

Les primitives d’AYIiD : une identité pseudonyme, un consentement signé, des preuves vérifiables. Aucune donnée personnelle brute au centre.

Identité pseudonyme (did:ayi)

Chaque détenteur est représenté par un identifiant décentralisé de méthode did:ayi. C’est une référence pseudonyme : le moteur ne stocke aucune donnée personnelle brute (PII). Les vérifications KYC passent par un fournisseur ; seul un résultat normalisé (booléens, score, attributs dérivés) est conservé, jamais les photos ni le document source.

Vie privée
Le sujet d’une demande (subjectRef) est toujours un DID. La charge utile transmise au fournisseur KYC (payload) est opaque et non stockée.

Consentement signé (EIP-712)

Rien n’est partagé sans l’accord explicite du détenteur. Sa décision (approuver ou refuser) est signée avec son portefeuille selon le standard EIP-712 (données typées). Le domaine de signature est AyiID Consent, distinct de celui des attestations.

1// Domaine : { name: 'AyiID Consent', version: '1', chainId }
2const CONSENT_TYPES = {
3 Consent: [
4 { name: 'requestId', type: 'string' },
5 { name: 'subject', type: 'string' },
6 { name: 'verifier', type: 'string' },
7 { name: 'decision', type: 'string' },
8 { name: 'disclosedScopeHash', type: 'bytes32' },
9 { name: 'nonce', type: 'bytes32' },
10 { name: 'expiresAt', type: 'uint256' }
11 ]
12};

Le moteur revérifie la signature côté serveur : elle doit provenir de l’adresse liée au détenteur. Le consentement lie le requestId, le sujet, le vérificateur, la décision et l’empreinte du périmètre divulgué.

Divulgation sélective

Deux modes de partage, choisis au niveau de la demande et honorés selon le choix du détenteur :

  • PROOF_ONLY (défaut) : un simple booléen signé, aucune donnée. Par exemple « majeur : vrai ».
  • SELECTIVE : le détenteur choisit d’exposer des attributs précis (disclosedScope). Seuls ceux-là sont partagés.

Preuve de personne vivante (PoLP)

La Preuve de Personne Vivante (Proof of Live Person) atteste qu’un humain vivant, et non un artefact (photo, masque, deepfake, flux virtuel), est présent. Elle existe à trois niveaux, L1, L2 et L3, et un vérificateur peut l’exiger avec une fraîcheur maximale (par défaut 30 jours).

Le pipeline agrège des signaux (défi coloré et latence, parallaxe et corrélation capteur/IMU, source caméra physique ou virtuelle, gigue temporelle) et exige une attestation d’intégrité de l’appareil (Play Integrity, Key Attestation, App Attest). Seuls des scores et des condensats sont soumis au serveur.

Vie privée
Aucune image ni donnée biométrique n’est acceptée par l’API de liveness : uniquement des scores normalisés et des empreintes. Le calcul se fait sur l’appareil.

Liaison puce passeport (Passive Authentication eMRTD)

AYIiD peut lier une personne vivante à la puce de son document d’identité électronique (eMRTD, norme ICAO 9303). L’appareil lit la puce en NFC et transmet le SOD (Document Security Object, CMS/ICAO en DER) et les groupes de données. Le moteur exécute la Passive Authentication réelle : validation de la chaîne CSCA → DSC → SOD et concordance des condensats des groupes.

Deux modes de liaison

  • PA_ONLY : Passive Authentication seule, sans comparaison de visage.
  • PA_FACE : liaison complète visage-vivant, quand les gabarits de visage (embeddings opaques calculés sur l’appareil, jamais d’image) sont fournis pour le face-match avec le groupe DG2.

Attestations vérifiables

Le résultat d’une vérification est une attestation signée par l’émetteur selon EIP-712 (domaine AyiID Attestation), et ancrée on-chain au mieux. Elle peut être vérifiée hors ligne à l’aide de la clé publique de l’émetteur, et révoquée. Son statut public est VALID ou REVOKED.

1// Domaine : { name: 'AyiID Attestation', version: '1', chainId }
2const ATTESTATION_TYPES = {
3 Attestation: [
4 { name: 'attestationId', type: 'string' },
5 { name: 'subject', type: 'string' },
6 { name: 'verifier', type: 'string' },
7 { name: 'identity', type: 'bool' },
8 { name: 'scopeHash', type: 'bytes32' },
9 { name: 'nonce', type: 'bytes32' },
10 { name: 'issuedAt', type: 'uint256' },
11 { name: 'expiresAt', type: 'uint256' }
12 ]
13};