a guest Jan 18th, 2019 72 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Access control
  2. There are a number of concepts that are currently loosely related to access control.
  4. 1. Authorizations
  5. 2. Sessions
  6. 3. User Resource Mapping
  8. The way that a request is currently authorized takes place in one of two ways
  10. ### Case 1. a token (part of an authorization) is provided
  11. 1. We look up the authorization by the token provided, this authorization contains the set of all permissions that an authorization has.
  12. 2. We put the authorization on context, and pass it down the chain of functions.
  13. 3. Somewhere along that chain, we construct a permission and ask if the if the authorization allows the action.
  15. ### Case 2. a session key is provided
  16. 1. We look up the session by the key provided
  17. 2. We grab the user off of the session and use the user resource mapping and resolve that to a set of permissions
  18. 2. We put the session on context, and pass it down the chain of functions.
  19. 3. Somewhere along that chain, we construct a permission and ask if the if the session allows the action.
  21. While this sounds relatively straight forward, it has been relatively hard to express the model to others and in practice
  22. has lead to a bit of awkwardness in the implementation.
  24. This awkwardness is the result of needing to look at the resource in order to authorize access. There are two main ways this manifests itself.
  26. 1. when we are the `member` of an organization and we are only provided the `id` of the resource, we have to retrieve the resource to see if it belongs to the organization to authorize the action
  27. 1. when attempting to authorize `find many`, we have to fetch all and construct a permission for each resource (filtering out results that aren't authorized)
  29. Ideally, we should have an efficient way doing the following
  31. 1. find all resources a user, or token, is authorized to see
  32. 2. given an user, or token, and the ID of a resource determine if I'm authorized to access the resource.
  34. ## Proposition
  35. I propose that we move to a system that is based on Access Control Lists (ACL). That is, instead of having a set of permissions that we move around and use for each request,
  36. each resource in the system has an associated list that contains the IDs of each of entity that has access to the resource (where an entity is a `user`, `org`, or `token`).
  37. This way, given a user, or token, and the resource id, we could check to see if the user was authorized to perform the action without ever needing to explicitly access
  38. the resource.
  40. In addition to the ACL, I propose we store an Inverse ACL (IACL), so that given a user, or token, we can look up all resources that it is authorized to see.
  42. I belive this would roughly look like two indexes, similar to what User resource mappings look like today. Those two indexes would be
  44. **ACL index**
  45. `(resource type)/id -> [(user || org || token)/id]`
  47. This would be used to detemine authorization of a resource given a resource type, resource id and user, or token, id.
  49. Let `rt = resource type` and `rid = resource id`.
  52. 1. For tokens, you simple check the existence of the key `rt/rid/tt/tid` (where `tt = token type` and `tid = token id`)
  53. 1. For users, you simple check the existence of the key `rt/rid/ut/uid` (where `ut = user type` and `uid = user id`). If that key does not exist
  54. then you scan across `rt/rid/ot/*` and for each `oid` you check to see if `ot/oid/ut/uid` exists. If no such key exists, the action will fail. This
  55. has worst case peformance of log linear (there are the initial log lookup + the log lookups for each org scan value) in the number of org entries.
  57. *Note*: it's possible that there is only one case here, the specific implementation would depend a bit on requirements.
  59. **IACL index**
  60. `(user || org || token)/id -> [(resource type)/id]`
  62. This would be used to find all resources of a particular type. Given `rt = resource type` the process would be as follows
  64. 1. For tokens, you scan across `tt/tid/rt/*`. This should produce the entire list of available resources.
  65. 2. For users, you scan across `ut/uid/ot/*` for each `oid` and union together the list of `ot/oid/rt/*`, and join that with all of the values
  66. for `ut/uid/rt/*`. This will likely require a bit of deduping during the scan, but the operation should be efficient.
  68. One thing that this would change is that tokens would now have an associated operation that takes place, where the token id is added to the list
  69. of each resource that the token grants permission to.
  71. Additionally, we'd need a system that could resolve names to IDs (since this design works exclusively with IDs).
  73. ## The benefit
  75. The benefits would be the following
  77. 1. A simple authorization model that is easy to explain to other
  78. 2. No need to access a resource in order to know if the user is authorized to see it
  79. 3. Worst case log linear, in the number of org owners a resource has, authorization time (which should be fairly small since things currently only have a single org owner)
  80. 3. Returning list of authorized resources should be log lookup + linear in the number of resources
  81. 3. If performance becomes an issue, there is an obvious partitioning scheme we can do (by resource type)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand