Deployment Scenarios
Due to the modular nature of the system, users can run or implement their own components. Hybrid scenarios are possible where Openfort hosts some components while others are self-hosted.
Scenario Overview
This section evaluates the following scenarios, where the components are hosted by a third party such as Openfort (TP) or self-hosted (SH):
| Scenario | Cold Storage | Auth Service | Hot Storage | iFrame |
|---|---|---|---|---|
| Scenario 1 | SH | SH | SH | SH |
| Scenario 2 | SH | SH | TP | TP |
| Scenario 3 | TP | TP | SH | TP |
| Scenario 4 | SH | TP | TP | TP |
| Scenario 5 | TP | SH | TP | TP |
| Scenario 6 | TP | TP | TP | TP |
Scenario 1: Fully Self-Hosted
| Cold Storage | Auth Service | Hot Storage | iFrame |
|---|---|---|---|
| SH | SH | SH | SH |
Fully self-hosted.
This scenario relies on the hosting party implementing both the Authentication Service and the Hot Storage.
Developers can know they're running unaltered builds of the Openfort components by checking the attestations, as explained in the attestation section. On that note, developers can enforce execution of this image by requiring attestations in their policies, as in this Google Cloud example that requires attestation.
Developers may also opt to go one step further and make some of their configuration public to show that attestation requirements are in place in their infrastructure.
Noteworthy Risks
-
Execution environment: The hardware and the OS running the storage services (and the DBs they rely on) have access to the processes' memory and could extract sensitive data such as key shares from the programs' memory. It is essential to run them in trusted, secure environments. For instance, when running the components in GKE make sure to use confidential GKE nodes. The underlying storage used by the DBs should also be protected, to prevent extraction and brute-forcing of stored keys. If using Cloud Hosts, encrypt storages with self-managed keys, such as GC's CMEK.
-
Communication: Enforce and validate TLS encryption in every communication happening between two components. If services are running on the same machine, handle TLS certificates appropriately, use some proxy that supports TLS such as Envoy, or use Unix Domain Sockets. The latter are still vulnerable to eavesdropping from the same machine, but have a reduced attack surface compared to TCP sockets.
-
Total Asset Ownership: Since the hosting party controls all the Keys components, they can also decrypt cold shares if those belong to a project they created. The hosting party has access to both encryption shares and to the encrypted cold shares stored in the cold storage. Thus, projects must be registered and handled by third parties unrelated to the hosting party.
All of the next scenarios load their iframe from a third party, which could have been tampered with. This is not an issue in Scenario 1, as the iframe is loaded from the same origin as the rest of the components and served by the hosting party.
Scenario 2: Self-Hosted Auth + Cold Storage
| Cold Storage | Auth Service | Hot Storage | iFrame |
|---|---|---|---|
| SH | SH | TP | TP |
Developers rely on a third party to host their hot storage and their iframe. The main risk here is the iframe being tampered with, allowing attackers to capture passwords and secrets on the client's side.
As mentioned before, iframe builds are attested and those feature derived checksums of the static assets it provides.
The iframe is meant to be called via RPC methods from another app, so it is possible for both developers and end users to verify if the obtained static assets' checksums match those provided by the official build logs.
Scenario 3: Self-Hosted Hot Storage
| Cold Storage | Auth Service | Hot Storage | iFrame |
|---|---|---|---|
| TP | TP | SH | TP |
The greatest security concerns in this scenario are:
- Access token forgery: the third party (TP) could forge access tokens in the name of the user, and use them to access the cold storage.
Shares are still encrypted with user entropy, which brings us to the next point. - Share or encryption key bruteforcing: either by forging tokens or accessing cold storage directly, the third party could try to decrypt the encrypted keys through brute-forcing.
Scenarios in which the party controlling the cold storage is also responsible for automatic recovery share keeping, password-based recovery provides more protection than automatic recovery since the Host has access to all the required entropy to decrypt the cold storage share.
Scenario 4: Self-Hosted Cold Storage
| Cold Storage | Auth Service | Hot Storage | iFrame |
|---|---|---|---|
| SH | TP | TP | TP |
This is a common scenario: the implementations provided by Openfort are self-hosted, while the ones defined as unimplemented APIs are hosted by a third party such as Openfort.
The biggest risk in this scenario is the third party forging access tokens in the name of the user, and accepting them from the hot storage; as they implement and control both. Unlike in Scenario 3, the hot shares are not encrypted with user entropy which makes them vulnerable to access token forgery.
Scenario 5: Self-Hosted Auth Service
| Cold Storage | Auth Service | Hot Storage | iFrame |
|---|---|---|---|
| TP | SH | TP | TP |
In this scenario, the third party controls the cold and hot storages. Combined with the brute-force risk mentioned in Scenario 3, this can be enough to reconstruct the users' private keys.
Scenario 6: Fully Hosted
Fully hosted by a third party, such as Openfort.
| Cold Storage | Auth Service | Hot Storage | iFrame |
|---|---|---|---|
| TP | TP | TP | TP |
In this scenario, a single third party entity (Openfort) is responsible for all components. Because it hosts both the hot and cold storage, it is necessary to encrypt at least one of those two shares to prevent the host from accessing the full key. There are two safe approaches:
- User entropy: only the user knows a password that is required to decrypt the cold storage share.
- Automatic recovery with OTP: there is an encryption key; split between the user and the cold storage, that is used to encrypt and decrypt the cold storage share. The cold storage is temporarily granted access to the user's encryption share through a one-time access method, invoked by the user.
The point of both approaches is the same: make user action a requirement to access the key.
Making encryption key shares a one-time access thing in the cold storage, as well as the final key a one-time access thing in the iframe, has the objective of preventing key usage without user action.
OTP Recommendation for Automatic Recovery
Third party Hosts that manage users' automatic recovery and the authentication service could, in theory, forge access tokens representing users and gain access to the recovery shares of those who have automatic recovery configured. Users should be made aware of this risk when configuring automatic recovery. Using OTP is strongly recommended to protect user accounts in this scenario.
Another important aspect to take into account when using automatic recovery is who owns what resources. If the organization in charge of the cold storage starts a project within it, the organization can reconstruct the project-wide encryption key on their own. Projects must be managed by someone who doesn't directly control the cold storage to avoid this scenario.
Frequently Asked Questions
Does the backend ever have access to enough shares to reconstruct a private key?
In automatic recovery mode without OTP: It depends on Hosting.-
Scenario 6 (Fully Hosted by a Host such as Openfort): No. The Host (such as Openfort) holds the Shield Encryption Part. You (Developer) hold the Developer Encryption Part. As long as the Developer does not expose their part to the Host, the Host cannot decrypt the Cold Share. The Host has 1 share (Hot) + 0 usable shares (Encrypted Cold) = 1 share. Insufficient.
-
Scenario 1 (Fully Self-Hosted): Yes. If you host everything yourself, you hold the Hot Share + Shield Encryption Part + Developer Encryption Part. You (the Host/Developer) have full custody.
- Password recovery: Cold share is encrypted with user's password (client-side); backend never has the plaintext
- Passkey recovery: Cold share encryption key is derived client-side via PRF extension; backend never has access
- Automatic + OTP: OTP verification is required, which requires active user participation that cannot be forged
What prevents backend-side reconstruction in non-custodial deployments?
| Protection Mechanism | How It Works | Backend Access Blocked? |
|---|---|---|
| Password Recovery | User-provided password encrypts cold share client-side | ✅ Yes |
| Passkey Recovery | PRF extension derives encryption key on user device | ✅ Yes |
| Automatic (Cloud) | Encryption key split between Host (such as Openfort) and Developer (You) | ✅ Yes (if Developer Part is secure) |
| OTP/OTP for Automatic | OTP sent to user's email/phone required for decryption | ✅ Yes |
| Split Hosting | Hot and cold storage hosted by different, mutually-untrusting parties | ✅ Yes |
Is the open-source configuration custodial by default?
Yes, if you host everything yourself. In a fully self-hosted setup (Scenario 1):
- You control Hot Storage.
- You control Shield (Cold Storage).
- You control the Developer Encryption Part.
- = You can decrypt everything.
- Use password-based recovery (recommended for maximum security), OR
- Use passkey-based recovery, OR
- Enable OTP/OTP verification for automatic recovery, OR
- Run Shield in a TEE (Trusted Execution Environment) where the encryption keys are not extractable even by you.