-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Simplify World v2 Access Control #462
Comments
If the names are of a fixed/predetermined length, is the separator all that necessary? We could just use a full |
Agreed! Especially since for passing the full selector from user code we actually can't just do |
I like simple namespaces, and they align better with store too. Just disallowing long (>16) route names seems fine to me. |
@alvrs and I had a quick call to help me better understand the two alternative approaches and trade-offs and I'm all for the first one! |
Another thought that came from the call with @holic: we can combine the advantages of approach 1 with approach 2 by adding an optional entry point that accepts a role as an additional parameter and first checks whether the caller has this role, and then if the role has access to the namespace. This requires two sloads, but we couldn't find a way to make approach 2 work with tables with less than two sloads anyway. |
I like approach 1 a lot, and it allows us to leverage the standard Solidity dispatcher to not require libraries in order to call system if have an extension of this with a single function per system (and thus namespace + system name is enough to identity a routine being called). world.Namespace_System(arg); |
Current Situation / Recap
/
and doesn’t include further/
./skystrife/combat/AttackSystem
)./skystrife
, it automatically has access to/skystrife/combat/AttackSystem
.accessRoute
, and asubRoute
. Access control checks are done on theaccessRoute
, and if the access control passes thesubRoute
is appended to theaccessRoute
to form the full route of the resource to access. (Eg.accessRoute = /skystrife
,subRoute = /combat/AttackSystem
)accessRoute
) for a nested route of arbitrary depth.accessRoute
.accessRoute
andsubRoute
and thereby inheriting access is relatively hard to onboard / wrap your head around.Alternative approach 1: Simple Namespaces
/namespace/file
.namespace
by default (= an address with access to the namespace has access to every resource in the namespace), but could also be granted for individual files.bytes16
, and the size of a file selector tobytes15
, so they can fit into a singlebytes32
word when concatenated with a separator character (eg/
).bytes32
for dynamic length strings plus ~1 byte per character in each string, we only require a single 32 byte word for the full concatenatednamespace/file
selector.namespace
andfile
are strings with max length ~16/15 characters respectively. If longer names are required, we could still fall back to hashing them to the required length.namespace/file
selector. This means the caller doesn’t need to know if their access is based on the namespace of the individual file - the contract would figure it out. In the worst case it would mean two storage accesses (if access is based on the file). As an optimization, we could add a second entry point that can be called with a singlebytes32 namespace_file
selector, if the caller already knows their access is based on the full file selector, to skip the separatenamespace
check.Code exploration
Here is a simple code exploration of what this change would look like in the World contract: 4c4c6e2
Here is a little exploration of what calling systems via the World would look like (without wrapper libraries / types)
Not too relevant for this proposal, but still mentioning here for context:
abi.encode
.Alternative Approach 2: Roles
This came up when discussing the idea with @holic
namespace
, we implement access control based onroles
?namespace
approach (see above), but instead offiles
being part of exactly one namespace, they could be accessible by different roles. By default all resources by single developer would have access to all the other resources (equivalent to a namespace). But in addition, access to different subsets of the resources could be shared with other roles.namespace
approach, we could store access for each role in a separate entry (instead of eg. an array). As an example: if we want to giverole1
androle2
access tosystemA
, we’d storetrue
in theAccessTable
at keyrole1
and atrole2
, and also store the file data (eg address of a system) in theSystemTable
atrole1/systemA
androle2/systemA
. We’d also need to store all roles having access tosystemA
in an array somewhere, to be able to update all references when updating the system. This would increase gas cost for registering new files (one time), but keep the gas cost low for accessing files.bytes32 namespace_table
key that can be used to refer to the table in Store, while with roles we’d need another concept of the table id (becauserole1/table
androle2/table
can’t refer to the same table), and therefore an additional storage access for writing/reading from/to tables.I’m curious for your thoughts on the general idea of simplifying access control to resources in the World contract, as well as thoughts on the two alternative approaches (or any other alternative approaches that come to mind)
The text was updated successfully, but these errors were encountered: