For web applications with highly complex access control rules, do you always use an ACL?
When determining my users' privileges I have a multitude of considerations, including:
Developing an ACL was proving to be difficult. After a while I resorted to doing "if/then" checks on basic attributes at the top of every action, e.g. if(isAdmin) {...}
This seems to be working OK and I'm wondering whether I should leave it in place as a permanent solution. Thus the question: does there come a point where the complexity of access control outgrows an ACL? Or is it simply that I need to try a bit harder?
When your access control model becomes too complex because access is no longer only based on the identity of the user, you want to move to another access control model.
You could use role-based access control (RBAC) where permissions are grouped into roles and roles are assigned to users. Active Directory and other LDAP products let you do role-based access control.
But if you want to implement more than just roles and in particular you want to take into account relationships, graphs, and graph edges, you want to use attribute-based access control (ABAC). In attribute-based access control, you can implement authorization logic that takes into account user attributes (their role, department, location, age, citizenship...) as well as resource attributes (the node's location within a graph, the edge...) as well as the relationship between the node and the user.
I uploaded a video on ABAC: www.youtube.com/watch?v=xUEbBKnxWSo CERIAS also have some great ones: www.youtube.com/watch?v=3ZCoupGHmwo
The main standard that implements ABAC today is XACML, the eXtensible Access Control Markup Language. I would look into XACML (disclaimer - I work for Axiomatics, a XACML vendor).
There are vendor and open source XACML implementations you can check out.
With XACML, instead of having a bunch of if(isAdmin) and if(validCitizen) statements, you end up having a single if (isAuthorized()) statement. The actual authorization logic is centralized inside a policy expressed in XACML. This is also known as externalized authorization.