Safe 2FA/MFA Brainstorming, Key Management and Self Authentication

Password and Passphrase are supplied by the user.

These are then used to ‘derive location and keypair’:

Within that derivation, there’s an additional ‘derive secrets’ (duplicated by sn_api and sn_client but will be consolidated soon hopefully to use only the sn_client version - sn_api/issues/714):

These secrets are then used to ‘generate network address’:

and also the keypair:

So no BLS, only ed25519.
CRDT has not changed the derivation of account details.
This can be done any way the client chooses, the sn_api / sn_client way is just one way of doing it.

The user needs to supply a location and a keypair. We currently happen to be deriving these from password / passphrase. I can easily see this changing in the future.


Thanks @mav for the push in the right direction. Correct me if I’m wrong here:

  1. The account password and passphrase will never leave the client device. They are used in a deterministic way to define the account location on the network and encryption keys.
  2. The derived ed25519 key-pair will be used to secure communication between the client and the rest of the network using asymmetric cryptography.
  3. All that really matters is the account locator and ed25519 key-pair. If desired, these could be supplied independently to the network without the use of a password/passphrase for deriving these deterministically.
  4. The password/passphrase combination in its current form is analogous to a typical blockchain wallet seed that is used to deterministically derive a variety of blockchain addresses.

Yes the client retrieves the blob at the address and then decodes it in the client


1, 3, 4 are quite right. Number 2, depends a bit what you mean by ‘communication’…

Keypair is used to decide which section the client will connect to:

Also for signing requests to the section elders:

And is the basis of the client wallet for performing write operations:

The only place I could find communications being secured was in qp2p, which does not use the client keypair:

Maybe I’ve missed somewhere else that does more encryption to/fro client/elders, but to my understanding it’s only encrypted by qp2p, not the client keypair.

Safe Network routing is quite different to TOR ‘onion’ style routing. In Safe Network the client doesn’t know the full route so they can’t pre-compute the layers for an onion-style route. The privacy in Safe Network is because the route knows the client xorname but not the client ip. Every hop of the route knows the client xorname and the data xorname, but not their IPs. Whereas in TOR the first hop knows the client but not the url, the last hop knows the url but not the client, and middle hops know nothing at all. This may change in the future.

This has gone fairly off topic but anyway, hope this helps show the purposes for the data that 2FA/MFA will be securing.

Happy to be corrected on any of this. I know some parts of the code very well but others not so well and I may have missed something.


This is a useful summary, I think.

Given that once the key-pair has been retrieved, access is assured, I feel any 2FA check must be integrated into step 1. Doing anything after this fact would be like closing the gate after the horse has bolted.

I suppose the client itself could store the 2FA logic directly. This would essentially ‘unlock’ the client, but any key logger could then install a client without this check and just use the subsequently entered password and passphrase directly. So, this seems unsatisfactory.

Therefore, it seems like a mechanism to take input of (from keyboard) something predictable (but different) and transform it into the same result (location) is required.

Food for thought!

Thinking about this some more, a hardware device would offer a good solution here. Given you want to either type something different each time (stop key logger) or type something in which is useless to the key logger owner, this could work.

If the location of key-pair was encrypted and stored on a personal security device, the safe network client could request the passphrase for the device instead. The client would then retrieve and decrypt the location of the key-pair. A wired connection to the device would provide maximum safety, but a secure wireless protocol would add convenience.

If a key logger was present, this passphrase would be useless without the device holding the encrypted location. The passphrase on the device could also be rotated easily, without causing a change in location.

I’m sure some of those hardware dongles do something like this. At a primitive level, a mobile phone or USB stick could would fine though. A mobile phone could even have a UI to easily change the passphrase. A dedicated dongle may just have a PIN to reset instead.

Edit: Actually, couldn’t the private key just be stored on the security device? If the private key was never stored on the network, once you were logged out (i.e. client closed) and the security device was removed, no one could derive your private key. That would prevent anyone reading your data or signing other data without your security device being present.


Thank you for helping everyone see the mechanisms at work and for pulling in quicp2p @mav. I think this is very on-topic since everyone now has a good basis for where the keys are and how they are used. Now we can have a proper brainstorm about MFA key management details and strategy.

The final clarification I think we need to establish is that the password and passphrase are analogous to the 24 word mnemonic seed often used by blockchain wallet software like electrum. Is this a bad analogy? Is there a better way to think about these? Passphrase/password length is not currently enforced, why?

Edit: Is this more appropropriate/clear for item 2 above?

  1. The derived ed25519 key-pair will be used to secure communication between the client and the rest of the network using asymmetric cryptography. (The ed25519 key is used for wallet transactions, section membership dynamics, puts, and gets… TLS 1.3 via quicp2p used for raw node to node UDP .)

I think this post from neo in another topic is also relevant for this discussion.

1 Like

Feels like we have come full circle! :sweat_smile:

1 Like

I think it’s a great analogy. The mnemonic encodes a certain strength within it (32 bits of entropy per word). Likewise the passphrase+password is acting as an entropy source, and the weaker it is the easier it is to break.

When authenticator was in use the passphrase/password strength was checked with zxcvbn. But now, no, there’s no check. We are basically using brainwallets for all account auth, which I’m not such a fan of (but 2FA/MFA could help improve). The cli has a --config flag when logging in which specifies a file for passphrase/password, and I’ll be using that to locally store very secure values (in the near future there will be a PR that will ensure this file is encrypted, like how bitcoin wallets are).

It’s also worth noting that not all private data stored on the network is currently encrypted, for example the account permissions map is not encrypted, but will be in the future:

Likewise, private sequence data is not encrypted with the client keypair (but may be in the future, it’s a little complex because if permissions change then does it affect the encrypted data too?). I’m sure many other data types are not currently encrypted in the way we expect in the final network (it’s no problem for testnets). So for now I have assumed in my mind that all data on any testnet is stored unencrypted and I think it wise for everyone else to do the same. Don’t ever use real secrets with testnets!

The client keypair is used to pay for puts (but not anywhere for encrypting or decrypting the put data itself). And it’s used to sign the get request to the first hop elders, but not for encrypting or decrypting any data for the get request. I just want to make sure the current usage of the client keypair is clear with respect to encryption vs signing. The client keypair is not currently used at all for encrypting. It’s only used for signing. I expect this will change in the future.

Also keep in mind self_encryption is used for blobs (self_encryption does not rely on any keypair so there’s no chance of using the client keypair for security inside self_encryption, only outside it).

The easiest way to think of the current use of the client keypair is for proving ownership (signatures), not for privacy (no encryption). I expect this will change in the future though.


Yes, we will create a x25519 key from a source, probably the hash of the ed25519 secret key. There is a way to convert ed->x (in fact Signal does this) but it can be dangerous. So best to not use the same key for sign and encrypt.

When we get there I imagine it will be encrypted with an x25519 key for individuals and we would use BLS for group encryption.

A question folk have sometimes is permissions, what if permissions change and we remove a person from an encrypted data share. Do we re-encrypt all data ? The answer is no, we assume if you have access to data you will have access forever. So on perms change you would not see any new data (see == be able to read) but you will still have the data you did have access to.

Reason for this is 2 fold, re-encrypt is really a lot of work and secondly it’s probably useless as the person removed probably has copies anyway. We consider worst case, they did copy the data. So removal and re-encrypt is costly and probably deceiving.


So, does this mean that the client key-pair doesn’t need to (necessarily) live on the network? It sounds like there is an option to keep these offline and use them to ‘login’ when you start the client.

Presumably, people would be advised to keep the permission groups small and only give access to trusted parties when needed? I can see this being an area where people will have a harder time adapting, but it obviously makes sense from an immutable/encrypted data perspective.

I suspect there is also a good argument for frequent key rotation (and therefore permissions) with this in mind. This way, new data can be encrypted with new keys. People who did have permission to older data wouldn’t then automatically have access to newer data.

We should also bear in mind that corporations often restrict access of data from company devices. So, someone leaving a company wouldn’t necessarily retain access and/or be able to download and keep data. If client key management is done via external devices, I could imagine corporations not providing a login that could be used directly too (i.e. they won’t know how to derive their client key-pair).

Yes, it can be in a hardware device or piece of paper etc. So plenty of options, use a keyphrase/passphrase (brainwallet like, but needs security of weak passwords handled) or have the keys random generated with a crypto random num generator and store offline.

Yes, I would hope so.


Thanks for confirmations.

Given hardware devices could hold key-pairs, the devices themselves could be used to manage permissions too. So, the device holder could access whatever group(s) the device permits. Maybe the device could even be managed remotely to make this more seamless.

Anyway, I’m just thinking aloud really. Corporations can be obsessive about removing access when no longer needed, but it sounds like there are ways and means to manage this outside of the network too. This opens up a number of options that could work well.


Ok, I’ve done some digging around the source code and I think I’m starting to get a better understanding of this. Excuse my mind dump, but maybe it will help someone else too! :slight_smile:

So, ‘key-pair’ on its own is confusing, as there are 2 main types (as I understand it) - the client key-pair (used to connect the client to the network) and the application key-pairs (used by your apps).

When you login with a passphrase and password, the location and the client key-pair are derived (through various hashing routines).

The client key-pair is used by the client to connect. I haven’t explored far beyond that, but I can see this client key-pair is being passed to the client when it connects to the network. Said client is also used to retrieve a balance, so they client key-pair presumably must be used here.

The location is used for storing/retrieving application key-pairs. These are stored in a permissions map.

When you create a safe, the client derives the client key-pair and location, then connects using the client key-pair, then prepares the permissions map to store your application key-pairs.

When you unlock a safe, the client derives the client key-pair and location, then connects using the client key-pair, then retrieves the permissions map containing your application key-pairs.

So, my chatter above about storing the key-pair to retrieve the location is full of holes. Of course your client key-pair and can be kept offline as it isn’t stored on the network. Only your application key-pairs are stored on the network. Likewise, the location of the application key-pairs isn’t stored on the network (that bit is obvious!).

Both the client key-pair and the location can either be derived via passphrase/passwords or by any other means. They can be created/generated externally, stored on an external device or whatever is ideal. However, you need a safe to exist at the location in order to store application key-pairs.

I want to explore how the coins relate to the above, but things seem much clearer in my mind after reading through the code a bit. I hope the above may help others who are grappling with the terminology/explanations without a complete understanding of the code! :slight_smile:


This reminds me ISO-27000 Information Security Management System is huge but has some really useful stuff.

1 Like

Something to throw out here for those looking at the code, which I think you’re seeing but perhaps this helps as a clarification. What you’re looking at there (@traktion) re: location/keypair generation is for the authenticator app.

The authenticator could be one of many ways to simplify key management (your app keys eg). Which we’ve also chatted about doing this via tokens for apps eg. But the data for those apps / their keys does not have to live on the network. That’s just one ‘log in from anywhere without a device’ type strategy.

But it is not needed in terms of network access. All you actually need is the ability to sign requests (aka, a keypair); somewhere. Currently at sn_client you have to provide the keys at instantiation. And it manages signing of the various requests. but we already have some code waiting in the wings to basically wrap the sn_client, which would produce messages to be signed however you want (outwith).

But aye, my main point I guess is don’t confuse ‘authenticator’ code with sn_client, the former is an app for key management, the latter is the code needed to sign messages on the network (which in the end is all you really need).


Some info on BLS hardware wallets on the chia subreddit:

Not sure what they need from us when our understanding is that Ledger needed to do work on their side to support BLS, which was the biggest hang up. I’ll look into it.

Edit - yeah definitely sounds like there is some communication mix-up internally on the Ledger side, we’ll make a gentle reminder to them that the BLS ball is in their court.


I keep going back to the fact that while Ledgers are nice and ‘crypto’ etc., there are enterprise grade cryptography keys e.g. Yubikey that are already owned by people outside the cryptosystem and which have e.g. Rust libraries ( Some sort of industry standard off-the-shelf method of signing and 2fa that doesn’t require writing a ledger app seems like an appropriate first step. And if something like U2F can be made to work in tandem with a password, then ledger will support that too.

Glad to see that SAFE is on it via a generic abstraction of the authenticator.