9

In my DDD application written in javascript (Node.js), I am stumbling on the implementation of the authorization generic subdomain. I checked on the RBAC / ACL authorization models on how to implement this, but they don't seem to have per-instance permissions, which I need.

From what I understand, RBAC has role-based authorizations. Users are assigned to roles. Roles are hierarchical and inherit permissions. Roles can have multiple permissions. Permissions allow commands to be executed on resources.

But, as defined by RBAC, resources are generic like "Posts", "Comment", "Book", etc. They are not instance-specific (like Post(id:9283984)). For example, it's not possible to define in RBAC that only a user that created a Post can edit it. It seems to be impossible to assign the role "Admin" to a "User(id:(8290321)" on a given "Post(id:2398493)"

It becomes even more complicated to define roles that have permissions to execute commands that modify other people's roles on a specific a resource.

The requirements of my applications are :

The User who issued the CreateLedger command is automatically assigned as the Admin of this Ledger. He can only assign other people as Managers or Collaborators or Viewers of the Ledgers he is Admin of. He can also revoke those roles. Managers are allowed to manage the Accounts of the Ledger. Collaborators are allowed to edit Transactions on this Ledger, and Viewers only able to view the data (read only). An Admin can assign the Admin role to books he is Admin of to another User.

My initial idea was that in order for a user to be able to manage user's roles on a resource, there would need to be a mapping between

user(id:X) -> role(name:Z) -> permissions -> resource(id:Y) -> commands

but in RBAC it's only possible to assign

user(id:X) -> role(name:Z) -> permissions -> resource(name:"Ledger") -> commands

Then, to overcome this limitation of RBAC, I thought about naming resources with their ids like

user(id:X) -> role(name:Z) -> permissions -> resource(name:"Ledger:39823847") -> commands

But this seems wrong. I haven't seen any example of RBAC using resource names as mapping for actual instances.

I am using the wrong hammer? I am seeing this wrong? Is there some other access control model more suited to this task? Or is this the way to go? I would appreciate if someone would point me in the right direction.

Thank you for your help

Gab
  • 7,869
  • 4
  • 37
  • 68
Ludovic C
  • 2,855
  • 20
  • 40

1 Answers1

5

Authorization as generic subdomain

If you want to model authorization as generic subdomain, you indeed are using the wrong hammer. Take a look at claims-based authorization. Using claims, you could define a claim like modify-post:2937472. Or of course you could further abstract that information.

With this approach, the generic authorization subdomain provides a "container" where the other subdomains store associations. Thus, this approach requires careful integration of the subdomains in order to keep things where they belong.

Authorization as supporting subdomain

Note: If you concluded from careful analysis & design that authorization needs to be a generic subdomain, then the following is not what you want. I add it to my answer anyway, because it can be a viable solution for projects that don't require a separate authorization subdomain. So here it comes:

A fundamentally different approach is to design authorization as supporting subdomain that has a dependency on the core subdomain. With this, you can use the core model to define access rights, which makes it a lot simpler and easier to understand.

As an example, the authorization mechanism for a blog system can use the Author, Post, Moderator, etc concepts from the core domain. This is a big win if you have complex authorization requirements.

The obvious trade-off compared to the generic subdomain approach is that authorization will not be generic, but tied to a specific subdomain. This may or may not be acceptable for a specific project, but it is a pragmatic approach for smaller systems that don't need a separate, reusable authorization mechanism.

Community
  • 1
  • 1
theDmi
  • 17,546
  • 6
  • 71
  • 138
  • Could you expand a bit more on authorization as supporting subdomain. I'm not so sure what you mean by using the core model to define access rights. That seems backwards if you consider your subdomain as a supporting one. Other subdomains should be using the supporting subdomain to define access right no? Also with claims-based-autorization, does all the claims have to live in memory to be verified? If so, how to you only load claims relevant to the operation? You couldn't load entire ACLs. – plalx Nov 04 '15 at 13:19
  • @plalx: The supporting subdomain in that case does not support a core domain, but the application itself. I guess some would argue that the authorization is not a separate subdomain in that case, but part of the core domain. – theDmi Nov 04 '15 at 13:24
  • @plalx: Note that this is not a good solution if you want to build a reusable authorization mechanism, which is usually the case if you arrive at a design with authorization as generic subdomain. So it is kind of against the question here. I just wanted to mention it, because it is a simple solution for applications with an "isolated" authorization mechanism. I'll update my answer so that this is clear. – theDmi Nov 04 '15 at 13:33
  • @theDmi Could an hybrid solution be advisable? By implementing a generic authorization subdomain, which could then be used by let's say a supporting LedgerAuthorization subdomain? The LedgerAuthorization subdomain would be responsible for the mapping between the generic auth subdomain and the Ledger domain? – Ludovic C Nov 05 '15 at 04:38
  • @Ludo Do you think that the mapping alone is complex enough to require a stand-alone subdomain? If yes, than this could indeed be a solution. – theDmi Nov 05 '15 at 06:10
  • I'm not sure. I would think that mapping JWTs from a generic claims-based authorization subdomain would not be the responsibility of an Accounting domain. Moreover that, in this case, users are allowed to edit the permissions of other users. This adds a level of "meta" that adds a lot of complexity. – Ludovic C Nov 05 '15 at 15:09
  • This problem of instance-level RBAC is something that I am facing now. I have a requirement to support 2 RBAC models: organization-wide RBAC + more finer grained permissions on the instance level: user can be assigned a role within the scope of the particular resource. (not within a particular resource type, but within the instance of resource). And it looks like instance-level RBAC becomes a concern of the service, which handles business logic/performs CRUD on the underlying data. – Ihor M. May 10 '21 at 15:05