Bons signés à l'aveugle et identifiants d'accès anonymes
Guide vérifié du voucher VPN et de l'admission Blind Vault RFC 9474, avec limites de rollout, replay, issuer et confidentialité.
AeroNyx utilise la signature aveugle dans deux voies d'autorisation distinctes. Elles réduisent toutes deux la corrélation d'identité, mais leurs garanties de rollout et de replay diffèrent. Cette page décrit Rust main, les fonctions contrôlées par déploiement et les inférences interdites.
Deux voies de credentials
VPN autorise ClientHello avec une credential blind-signature finalisée. Blind Vault V2 crée un lease aléatoire auto-authentifié via RFC 9474. V1 reste un bearer one-time de compatibilité, corrélable, pas une émission aveugle.
| Voie | État actuel | Modèle replay/redemption |
|---|---|---|
| VPN ClientHello voucher | Implémenté ; rollout reject_invalid compatible | Pas de one-time spend dans VoucherVerifier |
| Blind Vault V2 admission | Implémenté en Rust ; contrôlé par déploiement | Spend atomique et retry exact idempotent |
| Blind Vault V1 admission | Compatibilité uniquement ; V2 recommandé | Spend atomique mais émission corrélable |
Invariant de confidentialité
Le but est d'autoriser sans livrer l'identité d'émission au nœud. Signer, entitlement backend, storage node et console restent des frontières séparées ; joindre leurs records request-level détruit l'unlinkability.
- Le nœud valide sans wallet/account identity.
- Le signer reçoit blinded bytes et key ID, pas l'identité entitlement.
- Secrets, tokens, randomizers, spend/lease IDs et private keys ne sont jamais loggés.
- Les counters agrégés ne sont pas joints au trafic utilisateur.
- Rien à voir avec l'approbation aveugle d'une transaction wallet.
Voucher du handshake VPN
Le client envoie une extension AVCH bornée. Rust ne parse que les champs, obtient la clé par epoch, la cache une heure et vérifie RSA-PSS SHA-384 randomized sans wallet/account ID.
ClientHello fixed frame
+ magic: AVCH
+ voucher_length: u16 little-endian
+ voucher JSON (maximum 2048 bytes)
{
"token": "base64-final-credential-message",
"signature": "base64-finalized-blind-signature",
"msg_randomizer": "base64-32-byte-randomizer",
"epoch": "issuer-key-epoch"
}
Le flux n'est aveugle que si le client blinde avant la signature. Une signature normale d'un token lié à l'identité n'est pas équivalente. Token, signature, randomizer et epoch sont des secrets bearer, jamais loggés.
Limite actuelle du rollout VPN
VPN est en compatibilité reject_invalid : malformed/invalid sont rejetés, missing reste accepté pour retirer les anciens clients. Ce n'est pas une enforcement obligatoire.
mode = reject_invalid
valid | invalid | missing | malformed | total
valid_ratio | invalid_ratio | missing_ratio | malformed_ratio
last_observation | last_error
VoucherVerifier vérifie et compte mais ne dépense pas le token dans une table atomique. Il ne fournit pas one-time redemption ; sharing, replay, quota et expiry nécessitent un contrat versionné.
Admission Blind Vault V2
Blind Vault V2 découvre des epochs signés, blinde le message RFC 9474, reçoit la signature de l'issuer isolé, finalise localement et appelle /api/vault/v1/lease. Public API et issuers pinned doivent être actifs.
GET /api/vault/v1/issuers
POST /api/vault/v1/lease
POST /api/vault/v1/put
POST /api/vault/v1/pull
POST /api/vault/v1/delete
Content-Type: application/vnd.aeronyx.blind-vault-v1
client blinds RFC 9474 admission message
-> entitlement backend authorizes issuance
-> isolated blind issuer signs blinded bytes only
-> client finalizes signature
-> node verifies active public epoch
-> atomic spend marker + random self-authenticating lease
-> ciphertext storage operations use lease-scoped keys/capabilities
Isolation issuer et rotation des clés
L'opération privée vit dans aeronyx-blind-issuer et ne reçoit que version, fingerprint public et bytes RSA blindés. Aucun account model, storage DB ou redemption visibility ; même interface pour software et futur HSM/KMS.
Les epochs portent DER canonique, key ID SHA-256, validité et max lease TTL. Les updates exigent une autorité pinned distincte, generation monotone, continuité et persistance atomique ; rollback échoue fermé.
Spend atomique, idempotence et replay
V2 vérifie credential et commit spend ID plus lease dans une transaction SQLite immédiate. Un credential dépensé ne crée pas de second lease ; le retry exact est idempotent.
V1/V2 partagent la table de spend mais restent séparés : V1 raw ticket est corrélable, V2 spend ID ne l'est pas. Cette protection appartient à Blind Vault, pas au VPN verifier.
Observabilité et Nodeboard
Nodeboard n'affiche que validity, capacity, signer health et buckets agrégés. last_observation et last_error n'autorisent aucune dimension token, wallet, lease, request ou per-user.
Preuve agrégée autorisée:
- totaux/ratios VPN
valid,invalid,missing,malformed - compteurs issuer key, reload, capacity, rate, timeout, circuit
- santé agrégée Blind Vault leases, objets, bytes, expiry, cleanup
- mode, epochs, dernière observation et privacy boundary
Ne jamais exposer:
- tokens, signatures, randomizers, blinded messages ou spend IDs
- wallet, account, payment, membership ou identité sociale
- historique per-user, lease/object/capability/request IDs
- IP client, destination, DNS, route, message ou browsing metadata
- private keys, provider errors, ciphertext, plaintext ou wallet traffic
Menaces et limites
La signature aveugle réduit la corrélation, pas tous les side channels. Timing, region, capacity, client compromise, issuer collection, theft, collusion et traffic correlation exigent relay aveugle, chiffrement, logs bornés et séparation.
- corrélation issuer collection et redemption timing
- theft, sharing, resale ou client compromise
- replay VPN avant politique versionnée
- collusion issuer/backend/node/operator
- timing, region, capacity et traffic correlation
- rollback ou continuité de clés cassée
- télémétrie agrégée devenue historique per-user
Carte du code source
Le code sépare VPN verification, signing, wire contracts, Blind Vault admission/API/config et reporting. Ces ownership boundaries sont intentionnelles.
| Couche | Chemin dépôt | Rôle |
|---|---|---|
| VPN verifier | crates/aeronyx-server/src/voucher_verifier.rs | Parse AVCH, découvre epochs, vérifie voucher et compte rollout. |
| Blind signer | crates/aeronyx-blind-issuer/src/signer.rs | Politique RSA identity-free et abstraction custody. |
| Issuer API | crates/aeronyx-blind-issuer/src/api.rs | Signing borné authentifié, epochs, pressure et health. |
| Wire contracts | crates/aeronyx-core/src/protocol/blind_vault.rs | Contrats RFC 9474, epochs, spend IDs, frames, signatures. |
| Blind Vault service | crates/aeronyx-server/src/services/blind_vault.rs | Admission V1/V2 et commit atomique spend+lease. |
| Blind Vault API | crates/aeronyx-server/src/api/blind_vault.rs | Routes issuers/lease/put/pull/delete et erreurs grossières. |
| Blind Vault config | crates/aeronyx-server/src/config_blind_vault.rs | Pin issuers/authority, TTL et rotation monotone. |
| Health/reporting | crates/aeronyx-server/src/api/vpn_health.rs and management/reporter.rs | Statut agrégé sans secrets ni wallet traffic. |
Règles de développement
Le changement est complet quand crypto semantics, rollout, spend, observability, tests et langues concordent. Préférer une affirmation étroite et exacte.
- Séparer VPN et Blind Vault dans noms, code, télémétrie et docs.
- Ne pas dire mandatory VPN tant que missing est accepté.
- Ne pas dire one-time VPN sans atomic spend.
- Garder signer sans account, wallet, lease, node ou redemption context.
- Préserver continuité, authority fail-closed et atomicité.
- Seulement health agrégé, jamais dimensions identity/credential.
- Mettre à jour tests, Nodeboard et traductions avec la sémantique.