How to protect Storage Engine Permissions / How to store critical read only client data

I am trying to understand the permission system better and am unsure how to store critical user data in a way that the client can not maliciously modify the data.

Example: I want to have a storage object that stores user rewards, but I don’t want the user to edit it (and add additional rewards).

Do I store that with the user as the owner and permission = read only?
Or do I store it with the system as the owner in a special collection / storage object for the user?

If I store it with the user as the owner, is it a race condition who creates the object first?
Can the user create the storage object before the system creates it and give him self write permission and can then in the future exploit that?
Does that mean I have to create all the critical storage objects for the user when the user creates the account in order the set the right permissions, or am I overthinking this? How to handle it if the system evolves and new critical storage objects get added later on?

How is this typically handled? Is there a way to limit the user to only create storage objects in a fixed set of collections? I guess it can be controlled with an rpc hook.

Hello @kiniber, welcome to our forum.

If these rewards are a currency, it would be best to use the wallet APIs.

Otherwise, the correct way to handle this is to have server runtime code using hooks that creates these storage objects on behalf of the user at account creation, you can see an example here. The server will reject client writes on existing storage objects with write permisson set to 0.

You can change this code server side to create more storage objects if they do not already exist, shall you need to.

Hope this helps.

Ok, thanks.
I wish there was a setting parameter that users/clients can only create new storage objects in certain collections or not at all. I really don’t need the users to create them, I prefer to have the control on the server. Once I created an object with write permissions the user can write into it, I don’t really see a lot of benefit to allow the users to create objects by themselves. That just causes lots of security issues and I always have to check that the objects already exist, so I can not just create them when I need them but must initialize them at account creation. There are some ways to work around this. I think I will just add some before hooks and prevent the users from creating new storage objects. It’s not my favorite solution but that allows me to not always have to think about security in the future and I can dynamically create the objects only when I need them.
I will also store some things in the wallet, but not everything is well suited for the wallet.
Thanks again and by the way I enjoy working with Nakama a lot!

Thank you for your kind words :).

You can absolutely use hooks to disable the storage APIs or even just disable the user from trying to set a specific set of permissions on some collection, this way you can create these objects ad-hoc when needed.

1 Like