Hacker News new | comments | show | ask | jobs | submit login
Show HN: A Go Library for Better Access Control (github.com)
158 points by golangman on Mar 18, 2017 | hide | past | web | favorite | 25 comments

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?

We are using https://github.com/mikespook/gorbac right now, which works well for us.

But we do not have any multi tenant requirements.

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:


A few things that ACLs can potentially break:

* 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.

> think about them in terms of which actions are available to a user at each endpoint

It's called the Capability Model: https://en.wikipedia.org/wiki/Capability-based_security

"fine-grained access control in complex environments"

Oh that sounds...

"...is inspired by AWS IAM Policies."

Oh god no.

My day to day work is debugging IAM polices that have accidentally given global s3 write access or everyone but admins, admin access.

I agree... IAM policies are too complicated.

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!

It almost always comes down to complexity.

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.

Just to give an example of the pain that can be caused by NotAction in practice: https://www.reddit.com/r/aws/comments/3recc9/this_iam_policy...

This policy looks reasonable to a casual observer, but actually gives * access to everything in the account. IAM policies are _hard_.

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.

Reminded me of this fantastic video from Zed Shaw: https://vimeo.com/2723800

Can you recommend any resources to start learning Go?

- Learn the language: https://tour.golang.org/welcome/1

- Learn the programming environment: https://golang.org/doc/code.html

- Learn the idioms and best practices: https://golang.org/doc/effective_go.html

... and most importantly, go practice and build something!

Note: Ladon can be run as a service to use in your main application should you want to avoid learning go.

gopl.io is a great book

The official site is awesome

LDAP is still the industry standard for storing user data, please support that.

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.

It's probably just a typo, but OAuth(2) is exactly NOT an authentication protocol: https://oauth.net/articles/authentication/

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact