Skip to content
Darren L. Weber, Ph.D edited this page Jan 30, 2016 · 11 revisions

Authorization in Argo

This is summary of authorization processes in Argo. This authorization is specific to actions permitted on DOR objects. It depends on prior webauth authentication processes.

Argo global permissions

The only place where Argo can override the dor-services methods is in it's definition of User#is_admin?, User#is_manager? and User#is_viewer?. This depends only on inspecting user workgroups and the core of this authorization depends on matching a workgroup to one of the constants in the Argo User model, e.g.

ADMIN_GROUPS   = %w(workgroup:sdr:administrator-role).freeze
MANAGER_GROUPS = %w(workgroup:sdr:manager-role).freeze
VIEWER_GROUPS  = %w(workgroup:sdr:viewer-role).freeze

These workgroups override any permissions granted by DOR object roles defined by dor-services.

Argo requests permission from a DOR object

When a user does not have any of the global workgroup permissions, Argo will query a DOR object for roles permitted to act on it (actually an APO, but that detail is discussed below). Whenever it does that, it first inspects the Solr index fields for the object and tries to match up any user workgroups to DOR roles. Argo uses it's own data definitions for the roles to search in the Solr document and a set of User#known_roles [1]. So, Argo tries to translate a user's workgroups into DOR roles. For details on this, see the User#roles method, which partially relies on the User#known_roles method.

TODO: describe how the permissions are added to a Solr document and how the Argo User#permitted_queries works. Also comment on app/models/argo/access_controls_enforcement.rb.

The result of inspecting the Solr document to match workgroups to roles is a set of DOR roles that might be permitted to do something with a DOR object. (If the set of roles is empty, well, that's a problem actually and Argo should probably log something or raise an exception; TODO issue).

The next step for Argo is to pull the Dor object from Fedora so that Argo can clarify what the something actions are for the set of roles found. This involves passing the set of roles to methods like Dor::Governable#can_manage_item? and Dor::Governable#can_view_metadata? etc. This is the ultimate authority on what a role can do with a DOR object. It has it's own set of roles and all this can be seen in Dor::Governable in dor-services [1].

Now, the actual DOR object that Argo queries for permission depends on the type of the object. For the most part, every DOR object is considered to be either an "item" or an "APO" and it is assumed that every DOR object (both "item" and "APO") has one "governing APO". (The exception to this rule is the "Uber APO". It is assumed that this governance hierarchy is a directed acyclic graph [DAG].) So, the "APO" is the object that authorizes the actions for roles (this is defined in the roleMetadata datastream of the APO). The authorization request for an "item" or an "APO" first tries to find it's "governing APO". This search is only one level up the governing hierarchy and it stops there, regardless of how deep that path could be and what other permissions could be defined higher in that path.

The permission request logic is:

  • for any DOR object, get it's governing-APO
  • request permission from the governing-APO
    • if that fails:
      • if the DOR object is an APO, request permission from it
        • if that fails, don't display the DOR object
      • otherwise, don't display the DOR object
  • if it doesn't have a governing-APO (exceptional cases)
    • if the DOR object is an APO, request permission from it
      • if that fails, don't display the DOR object
    • otherwise, don't display the DOR object

This permission logic allows an APO to be a self-referential authority on acting on it (when it's governing APO does not specify permission or forbids access or does not exist). These permissions are largely consolidated in the Argo User model (see User#can_manage_object? and User#can_view_object?) and the dor-services Dor::Governable concern.


[1] The Argo User#known_roles may or may not actually exist in the Dor object, currently defined by Dor::Governable; Argo doesn't query Dor::Governable for that information, at present, and we agreed in Slack chat that this would be a good idea, so a PR on dor-services enables this by defining a constant in Dor::Permissable::KNOWN_ROLES. The PR is in