Public / Private Mutable Data

Dear community,

I’m currently exploring the possibilities of the new data types Public / Private Mutable Data. During my tests I have found out that the current design might be problematic and would love to bring this to a broader audiance (previously discussed in the dev forum) to hear your thoughts. Also: Maybe I’m completely wrong with with my assumptions so any feedback is appreciated, especially from the core devs. :wink:

Assumption / Problem:
Public / Private give the misleading impression that Private MD is only acessible by the user who stored it. Actually I would love such a data type or at least behaviour, but from the comments above it seems that this is not the case.

If I understood it correctly Private MD is decryptable by anyone who has the encryption key. This is problematic for web apps as there is no way to store these keys permanently (only options I know for storage are the session or local storage of the browser which both are not permanent).

Suggestions:

  • Reduce Public/Private MD to just one data type “Mutable Data” and give the option to encrypt or leave unencrypted.
  • Add a flag / parameter during creation so only the user who created the data can access it. E.g.: “isPrivate”.
  • Add something like a getUserEncKey method to the API which retrieves a unique encryption key associated with the currently authenticated user. This would also allow storing data which is only accessible by the logged-in user by harnessing the private key provided by the network.

Link to the discussion in the dev forum:

3 Likes

Just like immutable data then

Anyone can read a immutable chunk, but only with the data map (encryption keys) can the chunk the understood (read)

Thus it seems a private MD is one owned by you and data encrypted by you

Then its worded like immutable chunk. Might be a reasonable idea.

Then maybe a private MD could be encrypted automatically with the public key of the owner (An APP could choose to be the owner or let the user be the owner)

That is an option, but also adds complexity since the core code has to determine allowing access (raw read).

But it might be a more usable method. Then again having the read api use the private key to automatically decode the MD when read. This requires the read code to know its private.

May I suggest that the API does all that for you so an APP cannot record the user’s keys and store in another MD for the APP developer to harvest.


Then an option could be to encode with the owner’s private key so that any reader can ensure the MD was written by the claimed owner. Just decode with the owner’s public key

3 Likes

Thanks @neo for your additions to which I fully agree!

Actually that’s what I meant with the “isPrivate” flag, where the network handles the encryption (secure storage and retrieval) of the data on behalf of the user. The “flag option” and the getUserEncKey option are actually somehow competing suggestions and have pros and cons on their own. But they can also co-exist I think. The key option gives more flexibility as where the flag option gives more convenience and reduces complexity on the user side.

It sure adds complexity on the network layer but drastically reduces complexity on the user side - which I think makes it more reliable and secure. In the end, this would allow automatic encryption / decryption managed by the network without having the need to store private keys. Wouldn’t this be amazing? Like I said above, I actually thought Private MD would already allow such thing but it looks like I was wrong. :confused:

5 Likes

Sorry for the bump but any feedback / thoughts from @maidsafe would be really appreciated. E.g.: As it would mean a huge change to MDs, is it even considerable? Does it make sense in your eyes? If yes, would it be worth drafting a RFC for it?

1 Like

@Mindphreaker:

I’m not sure i get these two points, but here’s what i think and you can correct me if you were asking something else:

Network (routing and vaults) has no concept of encryption/decryption of user data. As far as the network is concerned there no such thing as private or public Mutable/ImmutableData - there are just two types - Mutable (versioned) and Immutable data. Private and public are terms which make sense only on the app/user end (safe-client-libs and frontend code above and beyon it). When app/user specifies private Mutable data, every entry in the MutableData::data is encrypted using the following scheme:

  1. Generate a random MDataInfo - this will be the ptr to actual MData. One of the fields it has is called enc_info. For private that will be filled with a random key and nonce
  2. Every entry key is encrypted with symm-key + hash(nonce+plain-text) so that the hashmap of entries can be indexed if ppl know the MDataInfo and the entry-key they want to access. We hash nonce to the plain-texted-entry-key because while we want the nonce to be deterministic for indexing we want it to be non-repeated else it’s a security flaw.
  3. Every entry value is encrypted with symm-key + random-nonce and stored as a serialised cipher-text, plain-texted-random-nonce (the usual symm-key-encryption)
  4. MDataInfo then needs to be securely stored somewhere. Where this is stored depends - e.g. for access-container it’s in the login packet which is encrypted using transformation of user credentials.
  5. When you want to share some private MData with some other apps you need to share its MDataInfo which would help app securely access it. How this is done, the fine-grained permissions, how is it revoked and containers re-encrypted with fresh info put into MDataInfo is a separate biggish topic by itself, but you can go through the IPC codes between safe-authenticator and safe-app libraries to see it happening.

For public MData, that optional field in MDataInfo has nothing, so no encryption/decryption takes place hence anyone who knows about that MData can read all entries. Whether they can mutate it or not is a whole different story and involves permissions embedded into MData itself, enforced by DataManager vault-persona. There’s more detail here on only owner being able to change the ownership of MData etc that is enforced by both MaidManagers and DataManagers (in different ways for different objectives) but i’ll avoid that here as it’s not relevant.

Similarly an encrypted ImmutableData will have an encrypted DataMap stored somewhere secure and public ImmutableData will have plain texted DataMap.

As you can see, AFA the network is concerned, it’s all Vec<u8> for it - it doesn’t know if it’s encrypted/plain-texted. The more important point is it cannot and must not know. If the network knew your private keys in order to decrypt data for you, it will have to store it somewhere. Since this is decentralised there is no server where your private keys are stored in some company’s vault which can be hacked or the company itself can use it to get everything out. So it’ll store it as plain text and then anyone can access it. This however is more like client side encryption where the network has no idea of any of your secret keys.

11 Likes

Thank you very much @ustulation for this detailed explanation of the deeper levels. I know you guys are heads down in berserk mode right now! While I have pretty much experience with traditional web development I’m still trying to understand all the implications and concepts the decentralised approach brings with it. Such feedback helps a lot!

You are right, this sounds logical. So if I understand it right, the only option for the user/app is to store the encryption key locally? This is where my pain comes from, because as a web app, I don’t really have this option. Do you have thought about this?

Or maybe I’m just too confused already. ^^ My main goal which I want to achieve is a simple app where authentication is bound to the currently logged-in Authenticator user. Actually pretty similar to what the web hosting manager does but as I’m not familiar with node.js it’s too complex for me to understand / learn from it. In other words, if a user visits the app he should be automatically recognized (e.g. greeted with username) as the user he initially registered while authenticated.

My own idea was to create a Private MD named after some user identifying attribute e.g. user ID or key (which I learned does not exist, or is not provided by the current DOM API). This actually led me to the above questions / thoughts.

Could anyone with a better understanding point me into the right direction, how the above could be achieved? Once I get this all sorted out I’m looking forward to put all these learnings into a newbie friendly tutorial.

4 Likes

It seems what we need is a way for apps to store private keys as part of the account info, or perhaps in the app’s own_container but encrypted / decrypted using a key only available from the user account info.

@ustulation do you understand the issue I’m thinking about here: where to safely store a private key so that an app can ensure only the logged in user can access it, and allow an app to decrypt private MD?

If this is already catered for, can you elaborate, or if not spell out the current options? Thanks.

3 Likes

@Mindphreaker @happybeing sure - authenticator has all the info. Currently everytime an app is started it invokes (via OS primitives) a-ctor and asks it to authorise it. If a-ctor finds the app has previously been authorised it’ll give it the same primary keys and info it has abt it. It’ll contain app’s enc and signing asym keys, a symm key, MDataInfo (hence all the info) of all the containers it wants access to.
There’s an option in the a-ctor UI to ask user everytime a know app does this or silently (re)grant auth (1st time or 1st time after revocation a-ctor should always ask). A-ctor stores top level MDataInfo in login packet for a few MData, which in turn will store info about other MData/IData and so on. So that’s toally secure until user cred is secure.

Another, less secure, option for apps would be to store the a-ctor given fob locally so that it does not have to invoke a-ctor everytime, but then it depends on how secure the machine is etc. As MaidSafe (dont quote me 100% on this though) i think we say that ur data is secure once it leaves ur machine - that is MaidSafe’s reponsibility. If the machine (including OS, keylogger, malwares reading application memory etc) itself is compromised then there’s nothing much we can do. We have mechanisms so that things don’t accidentally get compromised (e.g. user dialogue pops up) but beyond a certain point it’s the job of the user/OS/Antispyware etc to keep the local machine safe.

11 Likes

What is a-ctor? Short for ‘a constructor’?

1 Like

Puzzled me too, but it’s Authenticator!

2 Likes

Aha! … :bulb: