OpenSigner: Open-Source Self-Hostable Wallet Key Management - Jaume

EthPrague 2026 · May 2026 · 29:05

Openfort CTO Jaume Alavedra presents OpenSigner, Openfort's open-source, self-hostable wallet key management solution for developers building on Ethereum. The talk covers how OpenSigner provides secure, transparent and customizable infrastructure for managing wallet keys without vendor lock-in, along with its architecture and deployment options. Drawing on lessons from building it, Alavedra discusses real-world use cases, deployment scenarios and security best practices for teams that want sovereignty over their key management infrastructure.

Speakers

Topics

From EthPrague 2026, hosted by ETHPrague.

Transcript

Hey guys, everyone. So this is uh J and today I want to talk about uh selfhostable key management. Um this works for EVM chains, Solana chains and other um you know just any other curves that you'd want to implement. And um my desired outcome for the talk is that you learn that uh in browsers and in applications hosting your own key management infrastructure comes with different trade-offs. And um if you uh will see us uh with Open Signer, we've tried to make one abstraction that works uh for both.

Um so yeah, so as it is right now, I'm sure you're all aware with key management infrastructure, you either make ital to begin with, it has a super strong lock in. So once you uh choose one of the vendors, you're basically never change because they host uh the keys of your users and you're locked usually per life of your project. Um and of course you have to trust that the security boundaries and implementations of your um vendor are strong. So that's why we decided to create um Open Signer. Um it's an open-source MIT licensed uh

self-hostable key management. Um the key uh advantage that it has is that you can audit and it comes with a security boundary that works both for browsers and applications. Um, another key um, part of Open Signer is that it doesn't lock you in with one specific uh, authentication provider. And that is really really important because well, I'm sure as I'm sure you all know many vendors usually lock you in with uh, one first you do the authentication and then you do the key management. So one user is one key in their in their uh database. In open ser

you bring your own authentication provider and uh as we've seen in some hacks for instance the contigo app hack the authentication token that is issued from the o provider if it's not treated carefully can become a backd dooror into recovering the keys of uh your users. So, open Signer as I will explain takes care of that edge case. These are the main um properties of Open Signer. Um the most important here as I already mentioned self-hostable is that it's based on Shamir secret sharing. So it takes a private key doesn't really

matter the kind of curve that this private key was derived from and it splits it in three different shares and each of the shares um is exposed in a specific security boundary and the whole key is reconstructed only in one place once you use it and then it's flashed. I will go over this um uh in more detail now. So um in order to sign a specific message you must reconstruct the key. So as I mentioned the private key is always um split in three different shares and it needs a quorum of two in order to be reconstructed.

Um an important property here is that two different derivations of the same key cannot be combined. So every time that you do a new split of the private key, you get a new set of shares that cannot be um used in previous uh derivations of the shares. So these are the three shares that we have with open signer. There is the device share. This is the one that lives and can be stored in the local storage or whatever uh permanent storage that you have in the user's device. it can be uh deleted and that doesn't inclare.

This share is uh used in combination. I will go over this uh in the next slide but just for you to have like an overall idea. Hot share is fetched every time the user needs to use this um their their wallet and the cold share is only used uh when the user logs in into a new device to derive a new set of uh shares for their wallet. So this is the the whole flow. Um I will go over it um from uh the right from your right side to the left. Uh so I just presented that you have the three different shares. You have the cache which is the device share. Then you have the hot share and the cold share. So for a completely new

user, what you do is that you spin out a um a security boundary that is limited by an iframe that is um locked to a specific domain that you trust. So in this specific frame that you trust um you generate this new private key and you split it in three different shares. Then you take two of these shares and one you send it into the cold storage and the other one you send it into the hot storage. One key insight here is that um and I will explain this in the next slide but you cannot simply just share the the the what is the recovery share the cold

share um and send it onto the browser because then you um you have to be careful on who controls the servers where each of the shares are stored because if it's the same entity uh controls the hot share and the cold share they could in theory reconstruct your and then it's uhal setup. So let me go over what are some of the methodologies that we created in order to secure the uh call share to make sure that um you know the operator of the service can never reconstruct the full key without the user um being in the loop. meaning that the user either has

to provide some sort of entropy that they provide by um a password or by uh using the uh PRF extension in Basis. So to derive a key that encrypts the cold share or another methodology that we created which is what we call automatic recovery which doesn't include any any user input. So if you guys are interested we can deep dive a bit more on that but it's a bit more um complex. So um as I mentioned there are three ways of um encrypting the code share that is stored in the recovery service.

So you have the password straightforward the user gives you a like a password during the onboarding and that password is used to encrypt the this cold share and this is only then used if the user needs to log in into a new device. Once they are locked in into a into a device, you only need the local share and the hot share. So you can combine those two to reconstruct the private key and use it every time. Um, this is a key inside, right? Because you don't want like a new user that comes into your application every time asking for what is the password and so on. So you only ask for it once per new device that gets logged in.

Then the pass key uh I will explain it u just like in a few seconds. But the um the the the the key inside here is we use an extension uh called PRF to uh pass keys where that allows for deriving a deterministic encryption key um uh and we use that to encrypt um the recovery share. And the last method, the one that I mentioned is a bit more complex is one that doesn't require any user intervention. Um and in this method um it only works in in very uh specific scenario which is when you have open signer hosted by a provider and this

provider is offering this service to another app developer and this app developer is offering the service to a to a to a user. So you see there like a bit like there's an extra step here because this uh app developer has to basically host an encryption key and this encryption key is the one that is used then to um encrypt the recovery shares whenever the user wants to uh login into a new device. Um so you basically introduce a new party into um into what is required to create the wallet but you get the improvement where the user doesn't need to recover a password or worry about like losing the

pass key because they I don't know they uh deleted their bit warden account or you know any of those things. So this is the what I mentioned just now about um pass keys. Um in theory it sounds awesome and everyone should use it like Jack Dorse is like endorsing it for um you know to create like a file sharing system that where everything is encrypted in the cloud and like you can create in theory you know applications where the user only has a private key that they control and then you can encrypt everything with it. In practice, we've seen it's a bit more complex. Um, for one, because the UIs from most

devices we use do not give the flexibility of changing what the UI says whenever you're using Apaski. So, they think you're logging into something when you're actually doing something pretty important, which is decrypting and encrypting. And sometimes users do factory resets and they don't know what they are deleting. they're deleting all their uh you know some of the pass keys from their you know password manager and so on and then they lose the pass key and then it's catastrophic right because this is basically holding the encryption key that has access to their account um so we've seen that as well so it's not jack of all trades it's has some advantages but um yeah

so this is the setup of uh how it looks like uh to host open designer. Um, so you have your application, which as I mentioned can be a browser, but we've made it work as well in in uh mobile applications, React Native, Swift, it doesn't really matter. Um, and then you basically spin out an iframe service. This iframe is the security boundary um where the private key is generated, where the keys are are split and and reconstruct and the wallet is reconstructed every time. Um and so then the app communicates so the app let's say it's a website communicates with the iframe service through a post messages

um and then the iframe service given that you can reconstruct the key will um you know respond with the signature and inside the iframe service um you're communicating with the three um with the three key services here which are yeah the hot storage where you only interact when you want to recover cold storage um sorry hot storage when you want to interact every time you want to sign cold storage when you want to recover and the o service which is another security boundary that you only expose any like the hot storage and cold storage whenever the user is authenticated so you can bring your own o service here you can bring betroth you can bring oct o zero doesn't really matter uh the only important thing here

is that open signer um you know will have an endpoint uh that you will be able to configure and then you basically will send the tokens and it will verify them and answer back with basically a boolean yes no and then um it will allow for doing the next action which is re you know returning the the the share. So this is a very quick um you know comparison. It's super broad like the rest. What does it really mean? There are so many options out there, but the it's it can serve as a as a as a summary of all the things that we accomplish with Open Signer. So, um most importantly MIT licensed. Um you can

self-host it. Uh it's non-custoal. We are big picky here. We've seen some providers like for instance preview in the beginning was mentioning their self-custodial. Our opinion only self-custodial when the user has the key. In this case, the keys is split between multiple providers. So, non-custodial um o provider as we mentioned to the agnostic chain support. It's only key management. It doesn't do anything else. So, you can we have support for Solana and EVM chains, but you could in theory expand to to some other uh as well. And signing signing speed super important as well because you only need to do a fetch of the hot storage once the user is

authenticated. the uh only limiting factor is how fast can you get the hot the hot share. So what is the ping speed between um you know the iframe where the user is and where the server is uh where you're hosting the hot shares. So this can be 100 milliseconds, could be less, could be more depending on where you have your your servers or if you're distributed or not. So um the key thing yeah this is just like a just like a summary thing on the on the whole steps and uh yeah that's that's basically it. Uh as you guys can see go check the GitHub uh repository. We have

some documentation explaining more in depth what are some of the um you know setups that are possible with it and and and and some pitfalls that we've seen and and and how to add it into your system. So check it out if you're interested and uh yeah that's it. from all talk if you have guys have any questions. >> Okay. So um does anyone have? >> Yeah, thank you. I wanted to ask about the the advantages of using the fiat shamir secret sharing versus using a simple two out of three smart contract wallet

>> setup like what is the advantage or for it? It seems like an extra hassle to manage all this crap like I can just have the same thing. Yeah. So, um we built open Signer and we uh starting from the smart account perspective. So, um I co-ounded Open for which where we started only with smart accounts uh for EVM chains. So we started only with smart contract wallets uh you know with hosting the bundler creating the pay master service and and giving everything bundled together to make it work. And what we quickly realized is uh one you still need the key management if you are not using pass keys directly in the

wallet and two how do you make it multi-chain there when most of the providers that we see out there um at least with a pure smart contract accounts if you want to use it multi-chain then it comes with a huge hassle because when well to use it into a new chain you need you need to deploy the wallet uh it's counterfactual. What does that what does that even mean? How do I import it into MetaMask if I want to like leave your app? Huge amount of issues like those um that you cannot really get away with a pure smart contract accounts. What we saw with with 772 and the Pectra fork is that that

changed the game a bit. uh you can you know smart contract wallets you can kind of merge them with EOAs in in their properties you can now kind of import a smart contract wallet let's say into Metamas you can simply import the private key and use the wallet normally and that's a huge win u but you still need the key that's there's no escaping of the on the key part um and pass keys well usually they're per chain and how do you see this state I mean I've been think since um Bangkok. It was what two years ago, three years ago maybe. They were already like speaking about synchronizing state between chains.

Coinbase team was working on it. Some other teams were working on it. I haven't heard anything about it like since yeah like two years. Um so how do you see the state of like what are the recovery uh guardians of a specific smart contract wallet? How do you sync the Basi wallet between different chains? Is in my opinion those are still like unresolved questions. Um so that's why you always get back to the key and that's the gateway from it. People create like more complex applications but the complex applications then always become gated at the end. So yeah >> yeah uh I have question uh if you focus on the initial part when we are creating

the p private key it's strictly created uh in frame as you said if I could you repeat the beginning of the question if you >> if you focus on creating the private key part so you set is created in the iframe right so if we consider the situation your device is compromised but you don't know about that. >> How can you trust you know um this it's it sounds like there is this initial issue.

>> So the the key properties that you get with uh with iframes is that in modern browsers they are isolated services from the hosting machine. So the key uh question here would be what happens if the iframe is compromised. So like the the one that is hosting the iframe is compromised uh then you're cooked like they could you basically the iframe is like the security boundary and they basically are inside the security boundary and so then is really really problematic. Um, but for a hosting machine, like if the like um a user's browser is compromised, I guess for instance, you could um modify the UI of the user to trick them

into clicking uh a specific part of the UI that does the reconstruction. That would be that would be an issue, right? But uh the iframe and the uh host browser are isolated services. So in that sense like there maybe there are some ways that I'm not aware but there are faster ways and so there would be like faster ways on like modifying the UI for example into signing something else sending the message uh like uh like the wrong message I mean there there are some other ways right I know but we also didn't know about the speech attack and then it happened right and it would it would be the case uh that we consider it secure But until it

isn't because we don't know about all it vulnerable it is. So there are also >> usually we generate the private keys in servers where are isolated or separated in some external devices like signers and so on. So yeah, just no, I mean it's a good point and so it's all about like the for example like if you try if you believe that um there will be an exploit that will um break the security boundaries of browsers that will make iframes exploitable um that you know iframes are not hosted in your

machine exploitable. I mean maybe but like I think like this is more like on on more on um speculation territory. I mean I don't know if AI will be able to figure out like new attacks on this kind of stuff but maybe there are also attacks on the on the server side of things. It's it's hard to say. I know like you get some advantages and you leave some uh it's just like another proposal that you get um and here where everything would happen on device. So um yeah that's my answer. So adding to that like uh so story right now the uh code is storing the uh the device share into the iframe right?

>> Yes. >> So that's very insecure and from an XSS point of view as well right because the the browser implementation of the local storage is tab based or like domain based. Oh well I mean here it's at local storage but like in production you would not host it in local storage right so >> where would be the ideal place then? >> So for example at open for we run open signer as a service and so uh you would have um you know a domain from a third party hosting the iframe and that would be loaded whenever you want to interact with your with your wallet. So it's an invisible iframe that is loaded in your in your browser and then you communicate with this uh iframe through a post

message and event listeners. So it's not it's it's never like in local storage here. It was set as in if you start opener locally today that's how it would look like but in production you never serve stuff in local storage. But couldn't the malicious uh service worker be able to be installed to this domain third party domain? And there are vulnerabilities. I mean the browser implementation of local storage varies from one provider to another. It varies from uh Firefox to uh let's just say Chrome. But again there is always that vulnerability that extensions can listen to it as well as uh service workers primarily.

>> Right? So I think the the key part here as well is that most of the vulnerabilities that you referred to would not be independent to would would be affect as well any um would affect differently if you had your wallet for example hosted in a server because if you have a Chrome extension that is malicious, it can for example intercept your network uh messages with the with a back end and then you can change the payload and change whatever you So the key thing here is that your in local storage even if your iframe is um you know your machine is compromised and they can get your local share local

share alone is useless and so um the key is only fully reconstructed uh at uh use time. So whenever the user wants to sign something the hot share is fetched uh the key is reconstructed is used and then it's flushed. So you you it only leaves on the user's device uh by a very few uh milliseconds. >> So if your browser is compromised because you're doing something else in a different page or you install a Chrome extension and you're not using your wallet that doesn't affect anything. And even if they get the uh device share by itself, it's not useful.

>> Well, all it all it takes for me is a single transaction. I just need to sign a single malicious transaction to extract all the funds out of the user's wallet. So still, even if I don't need access to the p private key of the user or the complete key, I just need to execute a single transaction. That's possible if the device share is compromised. >> No. So if the device share is compromised and let's say you have a chrome extension that can uh you know infiltrate and and and get in between your post message and event listener it doesn't matter the setup that you have.

Uh so for example if you are sending like a payload like just a payload into a backend server the backend server signs the message and you get it back >> you'll be compromised as well. So the the the issue here is like your server is like your browser is compromised not that you have like a local share because this local share is isolated in in the iframe and uh you know even like when you try to use it you it would have the same security guarantees as if you're trying to communicate with a backend service. So >> okay so uh again adding to that uh since you talked about the AI IP for 7702 right so why not if it's possible to delegate the entire contract uh the

address to a smart contract wouldn't be safer with coupling that contract to let's just say a pass key instead of uh this vulnerability a potential vulnerability via storing uh local like you in the storage device share can we just bin the private key altogether. >> So yeah. Yeah. We've seen some approaches where you create an an ephemereral private key, you do the delegation and you completely forget the initial private key. >> Yes. >> And during this initial setup, you see, you know, you you set up a pass key and then you use that as your as your wallet. That's >> And it works against all chains too.

Then if you're able to obtain a request with chain ID get minus one, then it works against all chains. Yeah, you could you could in theory then uh take that initial transaction that you used in the origin chain and repeat it into all destination chains and then you'd have the same setup. You will have though um an issue in if you change the origin setup into a new pass key that doesn't translate into the new chains. So you can have um you know smart accounts that are out of sync between each other and then it gets uh it can get really complex but yeah I mean it's another >> well you can always add more pass keys that control can still be granted.

>> Yeah. Yeah. So yeah but like you have to keep the state synchronized manually. So there's no service uh that I know of that would uh keep the state synchronized between blockchains. So you change the pass key in one chain, it doesn't automatically change in all the other chains where you have your wallet uh deployed. So you have to go like in all the other chains and basically deploy it as well. Same for guardians. If you have some or any other GK email doesn't matter. >> Yeah. But we all always have the transaction that transaction the request is public. So if it's the chain ID minus one, anyone could actually relay it.

Even you could execute that transaction of my account like you added a pass key but it's getting added >> to all accounts so anyone know the rice can actually sync the transaction a relay a simple relay would do >> I think um for the initial chain uh like for the initial setup that's possible because during the delegation you're putting chain ID zero so it applies to all the chains for subsequent transactions you are >> you still have chain ID zero there too what's the problem with that if you do a normal transaction, you don't have chain ID zero, right? It's a regular transaction and chain ID is not zero.

>> No, it depends on how you how you write the smart contract to actually accept a pass key hash. Yeah, >> I guess then yeah, I mean I think you can have problems then with nons for example. I think like there's an edge like a sea of edge cases where then you need to have like a what if the original transaction has nons one and the another chain has >> nons should be synchronized unknowns >> you see like there's like an edge of like 20 edge cases that actual products and users would never have >> yeah ideally proto I have you heard of protosh they actually figured it out like they maintain a separate nouns for these kind of changes like a master nons then the problem is solved >> nons and so Yeah.

>> Yeah. >> Yeah. >> Thank you. >> So, any other questions? >> No. >> Awesome. >> Okay. >> Thanks. >> Thank you. Uh, so that was the last session for today. We hope to see you tomorrow as well. Thank you.