When systems get bigger and attract multiple users a need for security policies arises. In Zotonic we have a pluggable ACL system which makes it possible to define access policies. These policies usually work nicely for normal publication websites. But for other types of sites, the standard policy is usually insufficient, which leads to writing custom acls in erlang.
What I’m curious at, what do other larger erlang systems use for access control? Do you use a formalised system like XACML (common in java/ms enterprise systems), or something else?
Which leads to the following question. Is there a need for some sort of cooperation on this subject?
XACML looks very interesting, especially if it could be compiled to a black box which we can ask questions like is A allowed to do B on C.
To me this looks like a very generic solution to a problem (ACL) many systems have.
I guess XACML works with properties (esp. of A and C in the above), so I assume some code to extract those properties is still needed?
Yes, it works like that. That black box is called a policy decision point, or PDP. This is usually called by a Policy Enforcement Point. In zotonic case this would be the
The idea is that you feed the PDP with an access policy which contains the rules on who can access what under what conditions. Usually there is also something called a PIP (Policy Information Point) which role is to feed the PDP the properties it needs to come to a decision. This is the part where the system retrieves the properties mentioned in the policy rules. This part, and the PEP are the ones you integrate into your system.
The main idea is that you can express the access policy for your system in a language designed for this purpose. This makes it easier to review your system by external parties. And prevents hard-coded policy decision making in the application code itself.
I guess it is not that hard to compile policies into erlang beams which can be dynamically loaded/unloaded and distributed and consulted by a PDP component. The PEP is simply an api which can be integrated into an application, and de PIP simply a component which retrieves properties from your system.
If we can define the beam module name, then I think this is something that is very useful for many projects.
And indeed, as you say, having a specification makes it possible to test and inspect the policies as a black box, separate from the rest of the system where it is used.
Yes, I was just curious what other Erlang or Elixir projects use for access control, and maybe it is worth to cooperate on some level on this subject.
Good old Diameter?
For an external full Policy system, I’d probably look at OPA (Open Policy Agent). It’s written in Go and an HTTP call away from your Erlang component.
The Rego policy language looks quite acceptable, at least compared to writing policies in XML.
Of course, it’d be nice to have a system in Erlang…
For zotonic an erlang system is a must. During rendering of a template the acl is checked for all properties requested, so adding a http call for every access is too much overhead.
Opa’s acl language (Rego) looks quite interesting. With roots in datalog. Personally I don’t like the XML syntax of XACML too. Way to cumbersome to be typed by hand. I was interested in using an alternative syntax called Alpha (ALFA (XACML) - Wikipedia). But Rego looks promising, and is already used.
Thanks for the input.
@afa Have you used opa in practice? It looks very promising, but I’m also a bit hesitant because of all the complexity they added to a security product.
The basic idea looks ok, and it is good that it looks like there are quite some users. I’ve created a simple yecc parser for some more experiments.
I haven’t used OPA in production. I checked it out extensively about a year ago. I started with a Rego parser in Erlang but then realised I don’t need it because I can write OPA scripts directly and, by that, define the access policies already. The context is VerneMQ, with an obvious need for authentication and authorisation.
So my hope was (and is) that OPA would take care of all the integration needed for authorisation, avoiding the necessity of multiple auth plugins (let’s say for OAuth, LDAP etc.). Your goal is likely different.
I can confirm that Rego scripts give you full power and fine-grained control in an ABAC based fashion. You’ll pack the attributes in a JSON request to OPA in Erlang and then process OPA’s decision (in a JSON answer).
I had 3 “problems/challenges”: first, to not go overboard with the Rego scripts (that is, decide on a sane set of attributes), and second how to best feed external data (not the Rego scripts) to OPA - they usually do this with
data.json. Third, there was the issue of JSON API compatibility when you have an existing API to integrate into the OPA response format. There’s a chance OPA might be more flexible in that regard by now.
Also note that I never tested performance of OPA. Verne potentially would request a ton of decisions per second.
That is what I like about it. That the rules are not hard-coded somewhere. I’m glad that it works in practice.
After looking at opa I found out that the grammar rules for rego on their site is just wrong. It won’t even parse their simplest hello world example. That left me a bit wondering on its maturity. I opened a couple of issues for them. I extracted the yecc grammar from their old peg grammar.
The thing is that in Zotonic we check acl’s a lot (every template render using resources), so it has to be fast. Going over the network is a no, and resources are added and removed dynamically. So the acl system must be tightly integrated.
Going to investigate a little bit further. Thanks for pointing me to it. In the past I have done research into delegation in distributed trust management systems. I have some questions regarding that for opa. In practice it means that you have to be sure that your trust management language allows checking if somebody delegates strictly less rights to others. I’m not sure if that is possible with Opa. Maybe with a subset of the rules.
Interesting. Maybe the doc is out of sync. (it happens to me too…)
I’ve never looked for open-source OPA alternatives, btw. There might be other promising ones.
That looks like the case. It is not so easy to document rego’s grammar, because they now use a hand-coded parser.
@mmzeeman Have you had any luck in your ACL investigations? We are also looking into ACL systems and need a pure Erlang implementations that also has to be fast.
I personally wouldn’t mind an Erlang language (that maybe could map 1:1 to something else like XACML or Repo). The problem has definitely been solved many times before and it would be sad to reinvent the wheel again in the Erlang domain.
Yes, rego looks really nice I must say. The language itself is single assignment like erlang. At the moment I’m looking into how I can map rego policies/packages into the beam (not full-time, it is a bit of a side project). I have a rego parser ready in a personal repo.
In zotonic we already have policies in erlang (See: zotonic/mod_acl_user_groups.erl at master · zotonic/zotonic · GitHub), but they become complex quite fast.
This also makes it difficult to get the policies reviewed by an outsider. Rego is used in more area’s than I realized. There are even online courses you can follow. https://academy.styra.com/courses/opa-rego.
We need an access control layer for our product (which mainly has a web UI). Our requirements are a bit simpler:
- It MUST be possible to build a GUI to edit role-based permissions
- Roles and policies MUST be serializable to a database
- It MUST have an Erlang API
But ideally, it should still be general enough so we can make a library out of it and use it in other systems too (or even better, open source).
I remain very interested in policies/Rego too.
I think the work @mmzeeman currently does (an Erlang runtime representation for the policies) will totally unlock the general use case (role based or attribute based). The reason for this is that the attributes are entirely free, it’s up to your application to define the meaning and boundaries of them.
Regarding the decision point component, it sounds like both of you are looking for a tight integration more than an external service component like OPA.
Interesting… we currently have a web interface for our role baed permissions. This interface mainly creates the necessary edges between the resources.
We however found out in practice that you often need custom tweaks. In some situations we want to change/extend what the core acl module does. More ABAC style. Like give view rights to all media resources connected to a resource when a user has a connection to it. Zotonic has a flexible resource edge model. (The Zotonic data model @ Zotonic). This does not need a separate UI, because it is kind of follows logically from what relations there are in the system.
What I’m aiming for is that I can express the underlying policy of that core acl in a policy language (rego looks nice), so it can be changed, verified and extended more easily. The policy itself will be stored as code in a repository. And the current user interface will basically stay the same.
At this stage we’re mostly interested in an “engine” that can store and validate these permissions for us when we perform actions. Parsing or loading data from some external format is a tertiary priority (first is to be able to store and load them from a database in a serializable format, and second is to be able to easily build a user friendly UI form them).