Blind-Signed Vouchers and Anonymous Access Credentials
How AeroNyx VPN vouchers let a node verify payment without learning the paying account, what the reject_invalid rollout still allows, what the node and backend can still see, and why Blind Vault admission is implemented but not deployed.
AeroNyx uses blind-signed vouchers so that a VPN node can check that a connection is paid for without learning which account paid. This is live for the VPN today, in a compatibility mode that still accepts connections without a voucher. A second credential path, Blind Vault admission, exists in the node software but is not deployed or used by the official app.
Two credential paths
| Credential path | State | Redemption model |
|---|---|---|
| VPN handshake voucher | Live. Runs in reject_invalid compatibility mode | The node checks the signature. It does not track one-time spending |
| Blind Vault V2 admission | Implemented in the node. Not deployed, and not used by the official app | One-time spend recorded atomically with lease creation |
| Blind Vault V1 admission | Compatibility only, in the same disabled component | One-time spend, but issuance can be linked to redemption |
How a VPN voucher is issued
- The app generates a random 32-byte token and blinds it locally, using RSA blind signatures (RSABSSA-SHA384-PSS-Randomized, RFC 9474).
- The app sends only the blinded message to the AeroNyx backend at
/api/voucher/issue/. The backend checks that the signed-in account is entitled, signs the blinded message and returns the signature. It never sees the token. - The app finalizes the signature locally. The finished voucher (token, signature, message randomizer and key epoch) is a bearer credential that is not linked to the issuing request.
Public issuer keys, grouped by epoch, are published at:
GET https://api.aeronyx.network/api/voucher/issuer/keys/
How a node checks a voucher
The app appends a voucher extension to the VPN ClientHello:
ClientHello fixed frame
+ magic: AVCH
+ voucher_length: u16 little-endian
+ voucher JSON (maximum 2048 bytes)
{
"token": "base64-32-byte-token",
"signature": "base64-finalized-blind-signature",
"msg_randomizer": "base64-32-byte-randomizer",
"epoch": "issuer-key-epoch"
}
The node parses only these fields. It fetches the issuer's public keys for the epoch from the endpoint above, caches them for one hour and verifies the randomized SHA-384 RSA-PSS signature. It needs no wallet or account identifier.
Rollout mode: reject_invalid
- Malformed and cryptographically invalid vouchers are rejected before the handshake is accepted.
- A connection with no voucher at all is still accepted, so that older clients keep working. Voucher use is not yet mandatory.
- The node does not record spent vouchers. Nodes accept a valid voucher as often as it is presented, for as long as its issuer key epoch is still published. Sharing, replay and quota limits are enforced by the backend, not by the node.
Nodes report only aggregate outcomes:
mode = reject_invalid
valid | invalid | missing | malformed | total
valid_ratio | invalid_ratio | missing_ratio | malformed_ratio
last_observation | last_error
What the node learns about you
The guarantee that "the node never learns your wallet identity" holds only for voucher connections.
- Voucher connections (the official app): the app connects with a voucher and a fresh, temporary handshake key. The node can verify payment but cannot link the session to your wallet or P2P identity.
- Legacy connections: a client that authenticates with its identity key instead of a voucher sends that key in the handshake.
In both cases the node reports the session's handshake public key to the AeroNyx backend in a field named client_wallet, together with session times and byte counts. For a voucher connection, that value is the temporary key. For a legacy connection, it is the client's identity key. Node operators can see per-session traffic and these keys in Nodeboard.
Vouchers also do not hide everything else. The node still sees your IP address and, as the exit, your destinations and DNS, like any VPN. When the app reserves a daily connection, the backend also records that the account connected at that time, but not which node it used. See the VPN comparison and the Trust Center.
Blind Vault admission (not deployed)
Blind Vault is a node component for storing client-encrypted objects under anonymous leases. It is described in MemChain and Blind Vault. Its admission design:
- V2: the client blinds an RFC 9474 admission message. An entitlement service authorizes issuance, and a separate signer process (
aeronyx-blind-issuer) signs only the blinded bytes. That process has no account database, storage or redemption visibility. The node verifies the finalized credential against a pinned public key epoch and, in one SQLite transaction, records a spend marker and creates a random, self-authenticating lease. A spent credential cannot create a second lease. Retrying the exact same request returns the same lease. - V1: a bearer ticket with the same one-time spend table. The node stores the ticket's identity, so redemption can be linked to issuance. It is kept only for compatibility.
The node exposes these routes only when Blind Vault and its public API are both enabled. Both are off by default.
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
Current status: Blind Vault is not deployed on production nodes, the official app does not call these routes, and the AeroNyx backend has no Blind Vault entitlement endpoint. Blind Vault is not a backup, archive or storage product, and none is offered.
Observability
Operator surfaces show only aggregate credential health:
- VPN
valid,invalid,missingandmalformedtotals and ratios, and the rollout mode - issuer key availability and coarse failure buckets
They never show voucher tokens, signatures, randomizers, blinded messages or spend IDs. Session-level traffic and handshake keys are a separate operator view, described above.
Threat model and limits
Blind signatures break the link between the issuing request and the voucher. They do not remove these risks:
- timing correlation between the backend's issuance or connection-reservation records and a node's session records, especially when one party can see both
- the node seeing your IP address, destinations and DNS
- voucher theft, sharing or resale while its key epoch is published, because nodes do not enforce one-time spending
- connections without a voucher, which are still accepted in
reject_invalidmode - issuer key rotation errors or compromised clients
Source map
| Layer | Path in the node repository | Role |
|---|---|---|
| VPN verifier | crates/aeronyx-server/src/voucher_verifier.rs | Parses AVCH, fetches epoch keys, verifies vouchers and records aggregate outcomes |
| Blind signer | crates/aeronyx-blind-issuer/src/signer.rs, api.rs | Identity-free RSA blind signing for Blind Vault V2 |
| Wire contracts | crates/aeronyx-core/src/protocol/blind_vault.rs | RFC 9474 admission messages, key epochs and spend IDs |
| Blind Vault service and API | crates/aeronyx-server/src/services/blind_vault.rs, api/blind_vault.rs | Admission, atomic spend and lease, object routes |
| Blind Vault config | crates/aeronyx-server/src/config_blind_vault.rs | Off by default; issuer pinning and rotation rules |
The node software is open source under AGPL-3.0 at github.com/AeroNyxNetwork/AeroNyx. The app is not open source.
<!-- faq:start -->Frequently asked questions
Does an AeroNyx VPN node know which wallet I paid with?
Not for voucher connections, which the official app uses. The node verifies a blind-signed voucher and a temporary handshake key, neither of which is linked to your wallet. A legacy client that connects with its identity key does reveal that key to the node.
Can a voucher be used more than once?
Yes. Nodes verify the signature against the published key for the voucher's epoch but do not keep a list of spent vouchers. Quotas are enforced by the backend.
Is a voucher required to connect?
Not yet. Nodes reject malformed or invalid vouchers but still accept connections without any voucher, so that older clients keep working.
Where are the voucher issuer keys published?
They are published at https://api.aeronyx.network/api/voucher/issuer/keys/, grouped by epoch. Nodes cache these keys for one hour.
Is Blind Vault available in the app?
No. Blind Vault admission is implemented in the node software but is disabled by default, is not deployed, and is not used by the official app. AeroNyx offers no backup or storage product.
<!-- faq:end -->