
Show HN: A Go Library for Better Access Control - golangman
https://github.com/ory/ladon?branch=master
======
caipre
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?

~~~
grey-area
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.

~~~
caipre
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..

~~~
grey-area
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](https://github.com/fragmenta/auth/tree/master/can)

------
zackmorris
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:

[https://opencredo.com/designing-rest-api-fine-grained-
resour...](https://opencredo.com/designing-rest-api-fine-grained-resources-
hateoas-hal/)

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.

~~~
eternalban
> 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](https://en.wikipedia.org/wiki/Capability-based_security)

------
posnet
"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.

~~~
golangman
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](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!

~~~
posnet
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.

~~~
schlarpc
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...](https://www.reddit.com/r/aws/comments/3recc9/this_iam_policy_did_not_do_what_i_thought/)

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

~~~
dastbe
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.

------
pebblexe
Reminded me of this fantastic video from Zed Shaw:
[https://vimeo.com/2723800](https://vimeo.com/2723800)

------
7ewis
Can you recommend any resources to start learning Go?

~~~
ereyes01
\- Learn the language:
[https://tour.golang.org/welcome/1](https://tour.golang.org/welcome/1)

\- Learn the programming environment:
[https://golang.org/doc/code.html](https://golang.org/doc/code.html)

\- Learn the idioms and best practices:
[https://golang.org/doc/effective_go.html](https://golang.org/doc/effective_go.html)

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

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

~~~
golangman
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.

~~~
sk5t
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.

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

