Skip to content

Instantly share code, notes, and snippets.

@ackerleytng
Created June 12, 2020 07:18
Show Gist options
  • Save ackerleytng/e26823e1a6d501757fbe2d826af90c21 to your computer and use it in GitHub Desktop.
Save ackerleytng/e26823e1a6d501757fbe2d826af90c21 to your computer and use it in GitHub Desktop.

Disambiguation of Authorization Terms

This is a preliminary attempt to coordinate the use of terms for authorization purposes.

There are many conflicting/duplicate definitions of terms in the world of authorization, because it is actually not easy to understand, and this has resulted in the use of different terms in different implementations.

In fact, this document https://profsandhu.com/workshop/role-group.pdf acknowledges the differences in definitions and proposes that we just need to define how it is used in a specific context.

In this document, I propose the use of some terms so that all of us implementers in the company can align on a common definition. Having this common definition will allow us to have a consistent language for implementation within the company.

I hope to eliminate the need to keep looking online or towards any other sources for new definitions and clarifications. I would like this document to be the definition for use within the company. This sounds like and extremely biased opinion and while every effort has been made to pick objective definitions, it is subjective, but this is purely in service of the goal of consistency within the company.

Consistency in security is of utmost importance and alignment should be sought beginning with authorization design, all the way to implementation in every app, including necessary modifications for purchased applications. It is only with a consistent definition of authorization can we begin to centralize authorization towards consistent management and externalization of data safely.

I hope that this document will serve as a disambiguation tool, and I feel that the maintainer of this document should accept new authorization issues as challenges and update this document as necessary.

Definitions

Permission

The right to perform a certain operation on a given resource

Granularity of permissions

The granularity of a permission should correlate with the level of control we would like to have over a certain resource. For example, a permission could read

(a) View line 256 in document "bobs-private-document.docx"

or it could be on the level of

(b) Do anything (upload/delete/comment on/watch/report videos) relating to youtube

(a) is more granular than (b), and comes at a higher cost of (engineering) operations and implementation than (b).

Costs relating to a more granular permission - (a) - will involve

  • Many more permission definitions at the design phase
  • Designing applications to permit viewing on a line-by-line basis
  • Management (granting/removing such permissions) by the user
  • Computational cost in computing the permissions of a user and determining authorization based on that

Benefits of a more granular permission include

  • Better and more explicit control of whether a user is permitted to do a certain operation
    • e.g. The central authority would know more precisely what the extent of a data leak is, in the event of a compromise, based on the granular permissions granted to the compromised user account
  • More flexibility in mixing and matching permissions as authorization requirements evolve

Defining authorization rules is a product decision, but the granularity of the permissions implemented is an engineering decision. The granularity of permissions should also be allowed to evolve - we could perhaps first design permissions broadly, and as the application develops, evolve the permissions towards something as granular as necessary (determined by authorization rules).

Purpose of permissions

Permissions are the primary way through which applications determine whether or not to allow operations on a resource. For example, the logic in the application should be

(a):

if "can view line 256 in document" in get_permissions():
    allow request to view line 256

The application, if built with the following logic, will be unnecessarily coupled to the prevailing hierarchy in the company and will break down when re-organization happens:

(b):

if person in "some-group-name"
    allow request to view line 256

or worse (c):

if person_name == "alice":
    allow request to view line 256

We seek to use the framework of users/groups/roles/permissions to move the mapping of person to permissions out of the application, decoupling application and authorization, allowing for independent evolution of both.

(a) is the preferred way of implementation for greater flexibility, although concessions can be made to accelerate implementation, perhaps at the following level (d):

if has_role(person, "reader"):
    allow request to view line 256

Role

A role is a named collection of permissions, and possibly other roles

There can definitely be collections of roles. For example,

(a) Permission: Delete slide 8 of "alices-private-slides.pptx"

(b) Role: Delete slides in "alices-private-slides.pptx"

(c) Role: Delete document "alices-private-slides.pptx"

(d) Role: Delete presentations

(e) Role: Delete files

In the above example, (e) is a superset of (d), which is a superset of (c), (b), and (a), transitively.

We can also accommodate different collections of permissions, for example

(dd) Manage document "alices-private-slides.pptx"

Here, authorization branches to two different forms. (dd) is a superset of (c), and it overlaps with (d), but granting (d) to a user is not the same as granting (dd) to a user, since (d) allows deleting all presentations, but (dd) allows only management (creation/reading/updating/deletion) of a single document in particular.

Purpose of roles

Roles are merely for convenience in administration and convenience in articulating policy. They can be shuffled and re-organized, because applications should be permitting access based on permissions, not on roles.

Group

A named collection of users

The above definition is obvious when described as above, but gets complicated when we look a bit deeper. Here are some explained examples for disambiguation purposes.

Group or Role: "System Administrators"

Suppose we have the following authorization rule:

All system administrators are allowed to do anything in an application

This can be interpreted as a role, because the administrator role is a collection of permissions. Specifically, it is a collection of permissions and roles of different granularities, like

Read documents of alice

Read documents of users

Delete documents of users

Create/read/update/delete documents of users

Create users

Grant users permissions

I can see "System Administrators" being defined as a group as well, but in our implementation, as described later, I would strongly advise that groups be strictly defined in terms of organizational groups (our group hierarchy)

Group or Role: "Managers"

This should be interpreted the same way as above, for "Administrators"

Group or Role: Team Names

Here, we are specifically addressing team names as used in the organizational hierarchy. For a common understanding, let's say we are designing authorization for a consulting agency, and the organizational structure is something like

Company: Consulting MegaCorp

Department: Consulting Arm (as opposed to Finance, or Marketing, etc)

Section: Tech Consulting (as opposed to other sectors like Environment, Finance)

Team: Everest (this team is a group that handles, specifically, tech giants. Other teams would be like K2, Fuji, Mont Blanc, etc)

Consultants: Alice, Bob, Charlie, etc

There are definitely company secrets to deal with here, and teams help different companies, such as Hooli (from Silicon Valley), so we don't want reports about companies to leak beyond each team.

Here, we would create a group called Everest, which includes Alice and Bob, and we will also create a role, called Everest, which represents all the reports and documents created by Alice and Bob during their time as members of Everest.

There is value in this "duplication" of groups and roles.

We should think of Everest in two ways:

  1. Everest is a collection of permissions, including create/read/update/delete access to all the reports Alice and Bob wrote for Hooli and other tech giants
  2. Everest is also a group of users, specifically, of Alice and Bob

This has value in the following ways

  1. When Everest as a group changes.

Everest is not a permanent group. Perhaps Consulting MegaCorp decides that Everest should grow, and now two new teams - Leopard and Tiger, should handle tech giants. Alice now leads team Leopard, and Bob leads team Tiger.

In implementation, there are these details:

  • The reports created by Everest as a team, continue that way. Everest represents the create/read/update/delete permissions to reports written by Alice and Bob during those times, and they should continue to retain access to those reports. The organizational hierarchy has changed, now under Tech Consulting, we have Leopard and Tiger, and we assign the role Everest to Alice and to Bob by virtue of the fact that they previously worked on those reports
  • For Alice's team, she decides that all members of her team should be granted access to previous Everest documents, so we assign Everest to the entire group Leopard. Bob is more cautious and prefers to grant access individually, so we assign Everest to only selected members of Bob's team.
  • We also create a new role Leopard, which represents all the permissions associated with all the reports written by everyone in the newly formed Leopard team. We create a new role Tiger for the Tiger team.
  1. When there is a need for temporary collaboration.

Say Zack needs to join this project for a while, and needs access to the reports written by Everest. If there were no distinction between Everest (group) and Everest (role), then we would be forced to let "join" the Everest group virtually for a while, giving Zack access to everything that Everest has, perhaps access to additional spending power on the Everest credit card, Everest printers.

Actually, what we want is to only give Zack access to reports written by Everest, which is rightfully represented in the Everest role.

With both the Everest role and Everest group, we can allow time bound access only to the reports written by the Everest team by assigning the Everest role to Zack.

Terms in implementations

These terms are all overloaded, and in this section, I seek to disambiguate them, and I hope that we can stick precisely to the semantics as disambiguated below, for the purposes of consistency, and as we try to build a consistent model together.

Client

A client is used to mean

  1. A client in a client-server relationship, as in a browser, curl, python, etc
  2. An OAuth 2.0 client, which is what most of us would refer to as a web application
    • To be precise, our web applications technically have a hybrid role of "client" and "resource server" as defined in the OAuth 2.0 spec
    • This is well explained in the first paragraph here: https://www.getambassador.io/docs/pre-release/topics/using/filters/oauth2/#the-oauth2-filter
      • Reproduced: The client is both:
        • An OAuth Client, which fetches resources from the Resource Server on the user's behalf.
        • Half of a Resource Server, validating the Access Token before allowing the request through to the upstream service, which implements the other half of the Resource Server.

We should be specific about what we mean client to mean in our discussions

Role

Role is used to mean

  1. Roles, as defined above (collection of permissions). This is, however, not defined in the OAuth 2.0 spec (RFC 6479). The OAuth spec does not make any reference to roles, but it does share our definition of permissions being an operation that is done on a resource
  2. Keycloak's realm roles and client roles. Both can be mapped into the access token. They will appear in different parts of the access token, under different parts of the json object given to the web applications
    • We want to use realm roles to mean groups of permissions, or even individual permissions, that apply for the entire realm, across clients
      • Example: administrator, superuser permissions on various clients
    • We want to use client roles to mean groups of permissions, or even individual permissions, that apply for just for specific clients
      • Example: app_name:read, allow reading on this certain application

Scope

Scope is used to mean

  1. Something that you request for, as a client. In OAuth 2.0, a client requests for scopes, which have an impact on the claims inserted into the token when the token is minted by the authorization server
    • In common examples, a scope will be used to determine which client's permissions are mapped into the access token
    • In another example, in RFC 6479, the scope is used to determine the lifespan of the access token, which affects the exp claim in the access token
    • The word scope is used, because the authorization server is first configured with what scope should be permitted, and the authorization server must only issue a subset (smaller or equal to) of the configured permitted scope, never more
  2. Some places use scope to mean what we define as permissions
    • For example, write_facebook_status is really a permission in our definition, not a scope
  3. Keycloak's client scope. This is an implementation of the definition of scopes in OAuth 2.0. In keycloak, we can define client scopes. These are the strings that a client will be able to request for, to invoke some mappers
  4. Keycloak has a concept of Assigned Optional Client Scope. If a client scope is set as an Assigned Optional Client Scope, it means that if a client requests for this scope, the mappers associated with this client scope will be executed to mint the access token associated with this request
  5. Keycloak has a concept of Assigned Default Client Scope. If a client scope is set as an Assigned Default Client Scope, it means whether or not a client requests for this scope, the mappers associated with this Assigned Default Client Scope will be executed to mint the access token associated with this request by the configured client

Proposed Implementation

TODO: Groups are strictly organizational groups. Line to draw is that if it's not on the org chart, it is a role. Roles are used as collections of permissions. Apps should use permissions (and permissions only) to determine access, allowing us flexibility in the evolution of roles. Roles and groups serve as tools to assign permissions to users. Also talk about how to use mappers to map AD security groups into Keycloak.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment