0

Example Application

I will try to explain my problem by using a familiar application. Lets'say I'm building a Discord / Slack / Microsoft Teams clone; and for simplicity’s sake, it will contain 2 services:

  • User service:

    1. Must sign in to use the application
    2. Once signed in, he/she can either join a group or create a group
    3. Can be part of multiple groups
  • Group: A place where multiple users can chat

    1. Users can either be a member or moderator (Permissions/Authorization)

When the user sign's in it will be given a JWT token to authenticate requests future request.

Problem

Not every user has the same permissions, some are members others are moderators. In other words, some users must be forbidden access from specific functionality/API endpoints.

As example, a member is not allowed to invite people to a group, only moderators are allowed to do that.

Upon sign in the user will get a JWT token with some information inside. This information excludes the permission list per group, since the permissions of all users are stored inside the group service.

This means that, upon sign in, the user is missing an authorization/permissions token while having an authentication token.

I don't want to create a dependency between the 2 services by requesting upon sign in (from the user service) the permission list (from the group service).

Question

When & where should I grab and assign the permission list?

Personal Thoughts

Currently, I have 2, probably not so great, options that I'm considering. Assuming that requesting the permission list upon sign in isn't possible (because that would create a dependency).

  • Create an API endpoint that generates the JWT token containing the permission list.

    1. This imitates the user sign in functionality where also a token is granted by calling an endpoint.
    2. The problem is that this would expose the internal functionality & would assume that the front-end developer knows about this really not so nice feature
  • Use middleware to generate the JWT token containing the permission list when no token is found.

    1. I'm currently using middleware to validate the presence of the JWT token.
    2. I'm not quite sure if it's considered good design when you do database calls & stuff inside middleware; but I'm not sure. Never done it before

Edit 1

Also, adding the permission list to the user service is not possible. The permissions depend on every single group.

A user can be a member of one group while being a moderator inside another group.

1

We have had a similar problem couple of years ago and we have seen two different approaches. They were different in a way where the role = permission set were stored.

  1. Centralized authorization:
    • Each and every role and permission has been defined in a central system.
    • The assignments between them were stored there as well.
  2. Decentralized authorization:
    • Only the roles were defined in a central system.
    • Each and every service defined different permissions.
    • The assignments between them were stored in the services.

We chose the 2nd option, because of the following reasons:

  1. The same role could have different meaning in different services.
  2. The permissions were really scoped (they belong to a specific domain).
  3. The role-permission set assignment can be changed with the need to change anything in the central authentication service.
  4. If a decrypted JWT token would leak (for some reason) then would not tell anything about the permissions for the malicious user.
  5. With this approach we prevented that the services become overly chatty.
| improve this answer | |
  • Thanks for your insights, the problem that I'm currently facing is more about where & when to assign the JWT that contains the permissions. User permissions are stored in another service which makes it impossible to sent them with the initial sign in JWT token. Did you store the user's permissions inside a JWT? – Michiel Aug 7 at 15:32
  • 1
    @Michiel Sorry for the late response. As I said the JWT does not contain any permission, just role names. Like this: "roles": "Admin, Moderator". And each and every service has defined a mapping between its permissions and the roles. For example: CommentService: "Moderator": "Edit, Delete, Hide"; ContentService: "Moderator": "Edit, WarnAuthor, Escalate", "Admin": "Edit, WarnAuthor, BanAuthor, Delete". Does it make sense? – Peter Csala Aug 13 at 15:44
  • 1
    I actually meant roles, but thanks for clarifying it anyway! I just wanted to know if its common practice to store the roles inside a JWT. Thanks for the help :) – Michiel Aug 13 at 19:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.