Definitely going to be looking more into this. I am just about to start a project that needs ACLs, and I was surprised to find that I was going to have to write a solution myself.
In case I just missed them, are there some comparable projects to this? Is there an established library in the space?
I have been there many many times. This is the reason for writing that library, because there are no good solutions that cover 99% of your cases. RBAC is limited, ACL is a managing nightmare, DAC is also limited, and so on. What really hit me where those AWS IAM policies which are plain beautiful, hence this library.
However, usually major programming languages have some sort of ACL/RBAC module around.
I use a much smaller solution than this which just registers a list of permissions in memory of the form: role x can perform action y on resource z and then offers checks like can.Manage(resource,role). So it avoids the policy docs and just does registration in code, and is a bit simpler. This library offers a lot more obviously, and solves a broader set of access problems, but depending on your needs the solution can be really simple and you might be better to write it yourself in one file and avoid another dependency.
That's more or less the situation I'm in, but with multiple applications. The idea is to pull out the "identity x permission x resource" logic so that each new project doesn't need to re-implement it..
Oh yes, I'm using a pkg shared between apps, didn't mean you should rewrite it each time, just that it can be much simpler than the linked pkg. Not aware of any widely used ones, you should release yours at some point if you extract it. The one I'm using is here in case it is of interest: https://github.com/fragmenta/auth/tree/master/can
After implementing an ACL system with permissions inheritance for child nodes, I'm of the opinion that it's not really something that can be written by humans efficiently. Not to say that the concept is bad, just that it touches on so many things that it should probably only be attempted by way of a framework (which largely doesn't exist, at least not universally, so kudus to ladon for trying).
For anyone struggling with permissions, it might be easier to think about them in terms of which actions are available to a user at each endpoint, something along the lines of this with HATEOAS and filtering links:
* PUT/PATCH requests: every relationship (and every attribute if using field-level security) of every resource needs permissions checks
* Database consistency: if logic is too complex to put in triggers, then permissions table can get out of sync with roles
* Russian doll caching (and caching in general): views now vary by user based on what subviews are visible
There are so many ramifications with permissions systems that it's worth implementing them early on in your project if you know you'll need them, or approaching them from a different angle like how Firebase rules are implemented declaratively and inherited per-resource.
For services I write I've been using simple permission strings. Call them scopes on the form:
'service:action:resource/sub-resource...'
Each client is then associated a set of scopes, if a scope ends with '' it matches all suffixes. And then you just ask if a client has a set of scopes.
By only allowing at the end, and otherwise just having permission as a set of strings you can most interesting operations:
- intersection
- union
- empty-set
- sub-set
between any two sets of scopes.
Hence, you can do do automated reasoning about permissions assigned. For example you check automatically verify an assumption that no role grants a scope A to a user who also has scope B.
Lack of support for doing combining IAM policies makes it hard to verify your policies with high-level assertions.
Why do those policies make it there in the first place? Could you share some scenarios? I'd love to improve the managibility of policies :)
The hydra ( http://github.com/ory/hydra ) project for example has groups, which allow you to set e.g. an admin group and then assign people to it. I think this helps a lot with managing policies!
The inclusion of boolean logic in the policies is the root cause.
Specifically, having not resources, or not principals and their interaction with the other policies in the account.
The second highest common cause is misunderstanding how the default deny works.
Again, not really an issue with the landon project, but more an observation on how added power (complexity) to access control systems can sometimes make things less secure.
Yeah, I can see how using "Not" as opposed to "Inverted" would trip up people here. However, I would say that's a naming issue and (for some reason) a resiliency to using explicit deny policies.
Sorry, but if you had read the README you would probably have noticed that it does not matter if you use Google Auth, LDAP, MySQL or anything else. Subjects are just string identifiers, so it works per definition with everything, including LDAP.
This is a good example for separation of concerns. LDAP is for authentication, ladon is for Authorization. Don't mix those.
Kerberos and OAuth are examples of authentication protocols. LDAP is not principally designed for authentication, it is a protocol for reading and modifying an hierarchical directory service (think phone book, DNS, etc.), but the "LDAP bind" operation has often been pressed into service for authn.
In case I just missed them, are there some comparable projects to this? Is there an established library in the space?