Where I&#x27;m currently working we have quite complicated roles which are based upon the position a member of staff holds. Positions may change, and the permissions follows the position not an individual user. We have many applications, and each is free to implement their own roles but we have an open source gem which forms the basis of it:<p><a href="https:&#x2F;&#x2F;github.com&#x2F;ifad&#x2F;eaco" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;ifad&#x2F;eaco</a><p>At an application level there is a simple DSL that lets us define abilities on a resource (e.g. a document can be viewed, edited, approved and deleted) and roles (e.g. editor, reviewer, auditor), and to link those two.<p>On the actor (a user &#x2F; member of staff) we define a set of designators such as what department they belong to, what position they hold in that department, what projects they are responsible for, etc.<p>When we then create resources, we link the actor and the designator which is ACL definition. For example, to say everyone that is a manager of department 5 can review a given document we do this:<p><pre><code>   document.grant :reviewer, :department_manager, 5
</code></pre>
Permissions can be added and removed to the resource&#x27;s ACL on the fly - so for example we could grant temporary access to a member of staff to review a document, then revoke their access once they&#x27;ve given the ok.<p>It&#x27;s easy to check if a user can perform a given action on a single resource, but we also want to see what actions a user can perform against a collection of resources, for example to present a list of Documents they have access to. The ACL is stored using PostgreSQLs JSONB columns, which can be efficiently queried against:<p><pre><code>    { &quot;department_manager:5&quot; =&gt; :reviewer, &quot;department:3&quot; =&gt; :editor }

    SELECT * FROM documents WHERE documents.acl ?| array[&#x27;department_manager:5&#x27;]</code></pre>