Access Groups: Why only one per user?

A user can have multiple Roles - why can a user be in only one Access Group?

That limitation will cause lots and lots of duplicated configuration as we’ll need to “simulate” a user being in multiple AG’s by duplicating the constraints. (Which introduces maintenance issues of course.)

You are right, the current model is not as flexible as should be. We are going to re-design it in the future.


Good question! Let’s ask another question: why Java doesn’t allow multiple inheritance? This is the same thing - composition vs inheritance battle.

For the current implementation of access groups, in many ways, such a hierarchical approach is copied from the LDAP organizational units, which, in their turn, are supposed to mirror organizational structure. Normally org structure has a top-down topology, shaped like a tree, so lower node inherits all constraints from parent ones adding its own limitations on top.

On the other hand, we could flatten the structure of access groups having then as a plane list. Then we could go towards having multiple groups for a single user. But then we wouldn’t be able to follow the structure of the organization, which is very useful in most of the cases from my personal experience. Mirroring LDAP OUs would become much more complicated, and this is one of the most common requirements for the back office apps! Another thing is manageability. Say on the attribute level, you have overlapping constraints - technically we can handle this, but it would be nearly impossible to understand for the end-user why they don’t see some of the records.

Finally, I would like to point out that I see a lot of cases where developers use Access Groups as part of their business logic - thing that must be a part of the solution. They use it just for because it is easier to define an access group than adding a where clause or a condition to the data loader. I have no surprise that later on they suffer struggling to manage it. For example, if your functional specification clearly says that a screen should filter out some of the records depending on the user type - just introduce a specific permission and code it using data loader conditions and data loader coordinator. Why would you need to break cohesion? I would recommend having a look at this article - it will give a clear picture of a very important principle about “low coupling and high cohesion”.

P.S. Personally, I don’t think that it would be beneficial to trade the hierarchical structure we currently have for multiple access groups per a single user with a plane structure.

@knstvk and @stukalov - well - in our current system we have lots of ways to restrict viewing/interacting with records. Just for an example, firstly we have a concept of “practitioner groups” - this controls which practitioner’s schedules a user can view. A user can have access to zero or more practitioner groups. We also have a feature which controls which patient note types a user can access. Again a user can have access to zero or more patient note types. These two access types can be given in any combination as needed to any user. So user A might have access to pract. group C and D and note types X and Y, and user B could have p. group C and A and note types Y, Z, and B… and so on in any possible combination as needed.

Note that this just two of the features of the system that would be easily handled with Access Groups. There are many more.

So implementing both of these with Access Groups would be easy - just add each user to the Access Group(s) they need and done.

Using where statements on data loaders would require us to add the extra where’s to every. single. data loader where any of these entities is accessed - and then remember to change all of them if something changes or doesn’t work!

Access Groups would be much, much simpler - and centralized. Go to access groups, add users to the ones they need, done. Every screen and report which accesses an entity constrained by an access group is so constrained without a bunch of extra work.

Plus - using where statements makes it non-user-configurable. Users decide who has access to what in whatever way they need. Some of our users have it set up very, very complex and I don’t see a way to give that flexibility with hardcoded where statements…

Though I understand why you’re resistant to changing this if you view Access Groups as an org chart. It’s just that we don’t - we view them as a set of keys that can be given to a user in any combination necessary. And I honestly think that’s how many or most people would think of an “Access Groups” feature.

Actually, not a lot. If we talk about splitting Access Groups functionality into row-level constraints and org structure app component - this is probably the way to go.

Yeah - we are going to need “multiple access group per user” before we can go live, though, of course, we’re a long way from done with our conversion. (As you know our app is extremely complex, with a huge amount of functionality.)

Though I understand why you’re resistant to changing this if you view Access Groups as an org chart. It’s just that we don’t - we view them as a set of keys that can be given to a user in any combination necessary. And I honestly think that’s how many or most people would think of an “Access Groups” feature.

A very common requirement these days as people usually have different roles in different groups.

In my case, a person can be a contributor on one Group, but the same person can be a moderator on another Group; but you can’t do that in Cuba because a person can only appear in one place on the group hierarchy.


See - there’s another example where the “set of keys” metaphor makes more sense than an org chart metaphor.

Even the name of the feature - “Access Groups” - really sounds like what @ray1 and I are asking for.

@ray1, that’s right as this is the only manageable way to do that. Otherwise it would be a mess of applied rules. Again in the case you just don’t need Access Groups, just develop your own abstraction over existing ones.

Org chart is not a metaphor - it is the original idea. That’s why the root element is called “company”. If you use it differently - it would be logical to develop another module. This could be a very good app component :slight_smile: - you are welcome to contribute!

I’m getting a little confused here - @knstvk first said that a rework is in the works, then @stukalov basically said no way, then seemed to say it’s being considered, then in the latest post seems to be saying no again.

Is this access groups feature being considered for a rework into more of a “set of keys” type of thing or no?

Our conversion really requires it and if we have to develop something similar ourselves it will increase conversion time drastically.

We’re in a battle for survival here, so while I agree that would be a great thing to do, we’ve got to get our app converted and out to clients so we can survive as a company. We waited too long - all our fault of course (though we didn’t find a suitable platform till CUBA) - and now we’ve got to go as fast as possible.

I don’t even remotely have any idea how to get started with something like this.

I assumed Access Groups would handle what we need - just by the name - until I realized it’s one AG per user and then it all fell apart.


What I can say for sure - it is not in a short-term list, even not in mid-term. These are already fully booked.

Saying that this is one AG per user is not fully right, as the user also has all AGs under the one they belong to.


Still - the need is not for a hierarchy - the need is for a completely assortable set of permissions to various records.

To quote a previous post of mine:

This is exactly what I’m saying - you are trying to apply solution that solves a similarly looking problem, but not yours. This is just not right mechanism.

It’s is like trying to use wheels as continuous track - both do almost the same thing, but very differently, so one cannot substitute another one.

Agreed. I guess I’m just mentioning that an enhancement or redesign of this feature might be a good thing. At least two users from the tiny subset of CUBA users that come to the forums could very much use it, so… I don’t think I’m the only one that thought “access groups” meant something very different, and was surprised to find out the truth of it.

This adds a very large amount of time onto our conversion as this type of access control is pervasive in our system (and would be in any medical system really).

Yes, this is why I’ve always had a problem with this hierarchical groups thing. The organisational chart is about who reports to who, who gets paid what and where the buck stops, and usually doesn’t have that much to do with what’s going on in an application. The Finance Director sits at the same level as the IT Director, but I certainly wouldn’t want to give the Finance Director access to the Wipe Data menu item.(This is just an example, by the way. The only person who can wipe data is me :-))

1 Like

Yes, your best bet here is to roll your own access stuff. I set up the flat group structure and then just one-to-one link a profile class to the built in user class. That way, Cuba can still do the login stuff, but then you can do access stuff yourself.

Of course this was a lot easier when I could access the user session from the ui xml files.


back then at my old company we also hit the limitation of the fact that one user can only be in one group. But in that case, it was a very sophisticated permission requirement that surely not the average business application had.

The solution to get over this limitation was that we used the user & groups not as the source entities for managing the permission but instead as target entities. This is a good example where when you need higher-level abstractions, you can generate the target entities on the fly.

In this case, what we did in order to get over the one-business-user-per-constraint-hierarchy was that we for every business employee created multiple sec$User objects. Those different user objects were put into all the sec$Group instances that they needed. Then we used the great User substitution feature. With that the business user got the user selection drop-down and was able to switch between the target users. In this case, it actually made sense, because those different user instances, in fact, represented Hats that this business user could wear at a time. But normally the user did not wear two hats at a time.

With this implementation I learned an interesting lesson: the limits of the Platform are actually not just what the basic primitives allow, but they can be remote controlled (as they are just data in the DB) in order to make your own abstractions.

Another example where I remote controlled the CUBA building blocks is the very little known entity pin example: GitHub - mariodavid/cuba-component-entity-pin: CUBA component that allows to pin a particular entity to a user session. There I dynamically add session constraints programmatically based on some user-interaction (like pinning an entity instance). There the access groups are also just the starting point.

Besides that, I think that in the case of changing the behavior of the access groups and make it multi-dimensional it can get very complicated very quickly. You can see it in the multi roles concept, where it is from an operations perspective sometimes really hard to determine what actual permissions now apply to a particular user. In 7.2 the screen of the “effective role” was introduced in order to mitigate that problem. Back then I even created a dedicated addon just for that very case of managing the complexity (GitHub - balvi/cuba-component-user-session-information: CUBA component that shows detailed information about user sessions).

For the Access Groups, multi-dimensionality combined with the hierarchical structure will surely make it super hard to understand what particular constraints are actually applying to a particular user.

Also, I think we have to put it a little bit into context here. Comparing CUBAs security subsystem to the golden standard of security in the Java world: Spring security you will quickly see that in a lot of respects CUBA highly exceeds the capabilities of what you can do with Spring security. Even one of the most advanced parts of Spring Security: Spring Security ACL is covered (in a different way) and exceeded by CUBAs security subsystem.

Of course, the security requirements of a business can skyrocket. But then we also have to look at the average (or better the median) security-requirements of a business application. Because flexibility very often comes at the cost of complexity…

Mirroring the behavior of LDAP and with that the behavior of Microsoft Active Directory enables to work a lot of people from the ops domain here. So I think even that on its own has a high value.

I would suggest you that in case you already see that your requirements exceed the limits of CUBA, try to think of how to programmatically generate constraints as I did it in the entity-pin example and apply them on the fly. This way the sky is the limit…


1 Like