Unlinked Access: reducing cross-service account linkage with HSM-backed token derivation

Under the Hood By Juraj Hilje | Posted on June 10, 2026

IVPN subscriptions now include access to additional services such as Mailx for email aliasing, modDNS for DNS filtering, and Portmaster for application firewall control.

The standard way to handle multi-service access is account federation: one identity propagated to every service. For a privacy company, a shared identity layer is a problem, not the solution, so we chose a different approach.

Our account system is intentionally minimal. Users do not need an email address to create an IVPN account. The primary identifier is a random account ID. When we needed a way for an IVPN subscription to unlock access to Mailx, modDNS, and Portmaster, we did not want to solve that by propagating the IVPN account identifier into every downstream application.

In a conventional federated design, each downstream service ends up with a durable link back to the same user identity. Over time, that makes it easy to build an internal picture of which service accounts belong to which subscriber. Even if that linkage is only used operationally, it tends to spread into databases, logs, backups, and admin tooling.

We built Unlinked Access to avoid that. Unlinked Access authorises access based on entitlement, without distributing the IVPN account ID. We accepted more architectural complexity in exchange for stronger data-minimisation properties, and that is the right trade-off when adding services to a shared subscription.

What Unlinked Access does

Unlinked Access works like this:

The privacy claim here is not perfect unlinkability, that would be an overclaim. The claim is narrower: the routine authorisation and subscription-sync path does not require sharing the IVPN account ID with downstream services. The published manifest contains token hashes and subscription data, not IVPN account identifiers. Synchronisation works through a pseudonymous token-derived layer rather than a direct IVPN-account foreign key in each downstream database.

How the current implementation works

The production implementation is built around five services. The codebase is open source.

1. Token generation

The token service accepts an input string and derives a token by:

The SHA-512 prehash step means Fortanix receives blinded deterministic inputs rather than raw IVPN account IDs. That does not eliminate all metadata visibility at the provider level, but it does avoid sending raw account identifiers directly into the HSM operation.

IVPN account IDs follow the format i-XXXX-XXXX-XXXX (alphanumeric), which provides sufficient entropy for this property to hold. The key material never leaves Fortanix-backed cryptographic operations. The application handles inputs and outputs, but not the secret itself.

This mechanism is deterministic for the same input and key. The same account ID always produces the same token, which allows the system to regenerate it for manifest synchronisation without storing a mapping. Downstream services hash this token with SHA-256; that hash is the stable identifier they use for ongoing synchronisation.

The token service exposes this function over gRPC. Both the generator and preauth services call it as clients.

2. Preauthorisation for immediate signup

The preauth service exists so a user does not need to wait for the next manifest refresh before using a linked service.

When IVPN initiates signup:

The preauthorisation record itself stores only the token hash plus subscription metadata.

Once the downstream service has stored the token-derived data it needs locally, ongoing subscription state is maintained through manifest synchronisation.

3. Manifest generation

The generator service runs hourly.

It reads account and subscription data from the IVPN database, regenerates the deterministic token for each account, hashes each token with SHA-256, and builds a manifest containing:

The current implementation sets manifest validity to three hours and shuffles the subscription list before writing it. The shuffling is deliberate: ordering in one manifest cannot be correlated with the ordering in the next.

Subscription expiry times are rounded to 12:00 UTC on their respective dates rather than preserving the original timestamp. This is a countermeasure against timestamp-based correlation.

The resulting manifest is then cryptographically authenticated: the JSON payload is hashed with SHA-256, that digest is base64-encoded, and the token service is used again to generate a Fortanix-backed MAC over it.

4. Manifest distribution

The distributor service serves the current manifest from disk.

Access is protected by IP filtering and a bearer pre-shared key.

In this implementation, the distributor serves a shared manifest containing token hashes and subscription state, not IVPN account identifiers.

5. Manifest verification and local sync

The verifier service fetches the manifest regularly, checks that it is still within the validity window, recomputes the manifest digest, and asks Fortanix to verify the MAC via its own Fortanix SDK client, separate from the token service.

If that check succeeds, it updates the downstream subscription table by matching local token_hash values against the token hashes in the manifest.

Each downstream service ends up with local subscription state keyed by token-derived hashes. It knows which local accounts are active, at what tier, and until when. It does not need the user’s IVPN account ID to keep that authorisation state current.

What Unlinked Access does not do

Unlinked Access solves one problem: multi-service access that does not require multi-service identity propagation.

It does not claim:

In the current implementation, Fortanix receives deterministic blinded inputs rather than raw IVPN account IDs, which is better than sending the raw identifiers directly. But a provider can still observe cryptographic operations and blinded inputs over time.

The system also relies on operational controls beyond cryptography: bearer PSKs and IP-based filtering for service-to-service authentication, Redis TTLs on preauthorisation records, and authenticated webhooks for preauthorisation completion.

Compromise scenarios

Unlinked Access is a reduction in direct cross-service identity coupling, not a universal unlinkability guarantee.

Unlinked Access reduces the amount of direct identity linkage built into the routine authorisation path. It changes what data has to exist in downstream service databases.

Closing

Unlinked Access reduces cross-service identity coupling, and it does so without requiring downstream services to receive the user’s IVPN account ID during routine authorisation and subscription synchronisation.

Mailx, modDNS, and Portmaster can maintain local entitlement state using token-derived data and manifest synchronisation. None of that requires a conventional shared identity layer.

We decided how much cross-service correlation we were willing to create, and the architecture follows from that.

Resources

Open Source Privacy Security
We invite you to discuss this post in our Reddit community or on Twitter. You can also send your feedback to blog@ivpn.net.
IVPN News

Independent security audit concluded

By Nick Pestell

IVPN News

IVPN applications are now open source

By Viktor Vecsei

Releases

Beta IVPN Linux app released

By Viktor Vecsei

App-based VPN using SOCKS5
Under the Hood

App-based VPN using SOCKS5

Posted on July 13, 2022 by Nick Pestell

Today we’re launching our new SOCKS5 proxy service, available on all IVPN servers. This enables multiple new features but I feel the most exciting is the ability to configure individual apps (or browser tabs!) to route their traffic through a different VPN server than the one you are connected to.
In support of Ukraine: distributing free IVPN accounts
IVPN News

In support of Ukraine: distributing free IVPN accounts

Posted on February 28, 2022 by IVPN Staff

March 16 Update: Visit our dedicated Support Ukraine page to request a free IVPN account. This offer is open to anyone in Ukraine, Russia and Belarus. IVPN has multiple team members hailing from Ukraine. Their reality has shifted from living and working in a peaceful environment to fleeing the country and hiding in bomb shelters in a matter of days.
Spotted a mistake or have an idea on how to improve this page?
Suggest an edit on GitHub.