How to handle per-resource (fine grained) permissions in OAuth

oauthoauth2

I'm designing an app architecture using OAuth 2.0. I have a separate Resource Server and Authorization Server. The latter keeps a database of users and the scopes available to them.

Now, my question is: How and where to store/model fine-grained, per-resource permissions?

I'm talking about a scenario similar to what happens in a file sharing app, say Dropbox, where user can choose which files to share with which other users. How to model this in context of OAuth?

Notably, in my case some users may exist purely in the Authorization Server database (the Resource Server doesn't know about them at all). Let's call them "read-only users"; in AS they would have access to a scope of read_files_shared_to_me. And thus, that scope is the grant/token that my Client App displays to the Resource Server when asking for a particular resource (file). Now, how should I track which files are shared to which users, in the framework of OAuth (2.0)?

  • If it is responsibility of the Resource Server, then how should it store the list of "allowed" users, if the users exist only in Authorization Server? Should the RS use the "token introspection endpoint" of AS to drill down what particular user is asking, and store a list of "allowed users" per resource ("ACL")?
  • If it is responsibility of Authorization Server, then how should it pass the information about "resources available to this user" to the RS? From what I understand, "scopes" are rather general, they correspond to "roles/groups", not concrete fine-grained resources, so putting a list of resource IDs in a "scope" field of Authorization Grant / Access Token doesn't seem OK?

1 After some further research, I found a 2011 thread with similar question on [oauth-wg] mailing list. Some answers there suggest looking at "UMA". Unfortunately, the links seem to be either bit-rotten, or too vague. The apparent main page of UMA seems huge and still unclear to me. Also it's not clear to me if it's still relevant and up-to-date in 2018. Googling further on UMA I couldn't find helpful results. If "use UMA" is what you'd like to write as an answer, please try to explain a bit more on how I should apply it. Also, do you know of any concrete services using UMA for this purpose?

Best Answer

Eh, answering my own question... I followed up a bit more on UMA, and it seems to be indeed some kind of a possible solution:

UMA seems to be a semi-official (or at least the only official-looking one I could find) extension to OAuth 2.0, adding support for "fine grained", M:N sharing of resources. In simple words, it allows a scenario such as:

"Alice shares a folder of cat photos with Bob."

The UMA spec itself is, um... somewhat of a bucketload of wordy formalese, as specs of this world like to be; but if you squeeze it to get to the juice, it suddenly starts to show as actually quite approachable, in my opinion. The core underlying "trick" I'd say is in an idea that:

"It should be AS's responsibility (to guard the access & manage individual permissions), but it would work on opaque resource pointers provided by RS (thus not needing to know about semantics of particular resources)."

Expanding a bit more on the idea, a "high level" architecture sketch of a possible implementation could be like below:

  • Authorization Server must store one extra persistent table, "resource_sets", where each row represents "an opaque pointer to some concrete resource(s) in RS". [For example, a row could represent Alice's folder named: "Rly funny CATS!!!1!1"] The columns would need to be more or less:
    • id — unique row ID in the AS
    • ownerResource Owner of the resources [e.g. "alice"]
    • rs_id — ID provided by Resource Server (the "opaque pointer")
    • name — human-friendly name, also provided by RS [e.g. "Rly funny CATS!!!1!1"]
    • max_scopes — also provided by RS [e.g. "view", or "view add delete"]
    • a list of (user, scopes) pairs, dynamically managed by Resource Owner via some UI on AS. (This could be kept in a separate table if needed, implementation detail.) [e.g. ("bob", "view")]
  • AS must also expose a REST API, through which Resource Server can create, edit, and delete resource_sets entries (more details in the UMA spec),
  • and a UI, through which RO can add/remove users & permissions, i.e. (user, scopes) pairs, to owned resource_sets (or at least some REST endpoints, so that implementer could build UI on those).
  • Resource Server must keep a mapping of: resourcers_id;
  • when some Client requests a resource in RS, the RS must find the rs_id, and ask AS what are allowed scopes for this rs_id, through some elaborate dance using Access Tokens etc.

For full details, see obviously the full spec:

User-Managed Access (UMA) Profile of OAuth 2.0 [html]

EDIT: The 2.0 version of UMA spec in HTML format seems to be here, IIUC:

User-Managed Access (UMA) 2.0 Grant for OAuth 2.0 Authorization [html]

but I haven't looked into it yet, to confirm if that's indeed related.