user roles

David Merrill dmerrill@lupercalia.net
Wed, 3 Jan 2001 17:04:50 -0500


On Wed, Jan 03, 2001 at 04:29:31PM -0500, Derek Atkins wrote:
> David Merrill <dmerrill@lupercalia.net> writes:
> 
> > Because it is so much more manageable when you have sets of users who
> > all have the same permissions. Maybe that's not the situation I should
> > be optimizing, though.
> 
> When you have sets of users, you create a group (role) and then acl
> the group; then you can add and remove users from that group
> dynamically and everyone obtains the priviledges of that group
> membership.  But this is orthogonal to having ACLs with both users and
> groups on it.
> 
> > Can you show me how you would store rights assigned to a specific user
> > in the same table in which you store group (role) rights, then?
> 
> Well, I don't know enough SQL to be able to do it right, but basically
> in pseudo-IDL:
> 
> Acl ::= {
> 	AclEntry[]	AclList
> }
> 
> AclEntry ::= {
> 	int		type			<group or user>
> 	GUID		NameID			<GroupID or UserID>
> 	BitSet		Priviledges
> }
> 
> Group ::= {
> 	GUID		GroupID
> 	GUID[]		MembersList
> 	...
> }
> 
> User ::= {
> 	GUID		UserID
> 	...
> }

Ahhh. Pseudo-code is so much more precise than English can ever hope
to be. Thank you. I see now that you are including an additional level
of abstraction, by separating "group" from "role". My concept of
"role" is analagous to AclEntry, and I don't have a separate "group"
concept.

I can also see a clear benefit to your approach. It is a bit more
complex to implement because of the additional layer, but I think it
is still manageable.

In every other way, we are already in agreement. Good.

> Then any other object just needs to include an Acl..  Now, I know this
> is not a direct representation in SQL, but perhaps you can see what
> I'm trying to do?  And yes, users can be members of multiple groups,
> at least in my model.  When looking at priviledges, you get the union
> of all priviledges on the ACL.
> 
> > Because the db doesn't work with names; it works with guids, and there
> > are referential integrity rules to think of.
> 
> Could you please explain what "referential integrity rules" there are
> and how they apply?

In your IDL, you have a GUID that can be *either* a user's GUID or a
group's GUID. Referential integrity can't say that it can be either
one or the other; it must be exactly one of them. But we can just do
away with the refint on that field and there is no problem.

> > Here are the table structures (simplified) I'm looking at right now:

Here are table structures that implement your acl concept:


USER
----
dbuser_guid


GROUP
-----
group_guid


USER_GROUP
----------
dbuser_guid
group_guid


ACL
---
acl_guid
set of permissions


USER_ROLE
---------
guid (either user or group)
acl_guid

user_role is where the fun stuff happens. You have defined your users;
you have defined roles/acls which specify a set of permissions; you
have assigned each of your users to a group or groups. Then, in a
completely separate structure, you can assign any set of acls to a
user or to a group. And a user inherits all the permissions assigned
via the acls which have been given to him or to his groups.

This approach is more flexible for administrators in that it allows
them to grant or revoke entire sets of permissions across groups and
users by changing the acl. You could also do that in the simpler
design, but you would have to edit each role directly, because the
"acl" concept is tied directly to the group. Your approach is easier
on administrators willing to understand them, but probably harder to
understand.

> This looks like the permissions are assigned to a role directly.
> That's wrong (and backwards).  A role doesn't have any permissions by
> itself.  Indeed, that's why I keep referring to it as a group, not a
> role.  Anyways, an _object_ assigns a set of permissions to a group.
> A role is just a grouping of users who all get the same permissions,
> but those permissions are not inherent in the role, they are assigned
> by various objects in the datastore.  In other words, a role is just a
> convienient way to assign permissions but allow the actual users to
> change over time.

Yes, they are assigned directly.

> For example, you have a role (group) of users called "accounts
> receivable data entry".  Obviously, your team of workers can change
> over time, so membership in this group will change as well.  Then you
> add that group to the acl on a set of accounts, where each account may
> assign different permissions to that particular group.  For example,
> you probably don't want to grant access to the payroll accounts to
> this group.  In order to have this functionality, permissions for the
> group must be tied to the object being protected, not to the group
> itself.

I don't think this is true. Maybe in a standard acl design, but not in
a database permissions design. It may not be as manageable in some
environments, but you can accomplish all the same end results. It just
may take more work.

What your design buys us is the ability to define permissions
separately from a group, and then reuse them across groups. That's
all. I'm not saying that that isn't enough, though.

> > user_role, iow, assigns a role to the user. The permissions are in the
> > role table. Using my latest proposal, you would have a role record for
> > each user, created automatically when you create a user. Assigning
> > rights to the user specifically is a matter of changing the
> > permissions in this record.
> 
> But you need to be able to set the rights based on the various objects
> in the system.  How would you assign the rights to, say, read current
> transactions but not previous transactions?

One way or another you would have a flag in the role record to set it
on or off for that role/group.

> > And I'm not recommending separate lists for groups and users. I am in
> > fact proposing a way around doing that. I thought when you said to
> > assign permissions directly to users you intended to add the "set of
> > permissions" fields directly into the dbuser table. I think now I
> > might have misunderstood.
> 
> No, I'm proposing that permissions are stored with neither users nor
> roles; permissions are stored with objects, and objects assign
> permissions to users OR groups/roles.  Roles are just a convenient way
> to abstract away the set of users who get those permissions.  This
> allows you to change the group membership without having to reACL
> everything.
> 
> > I'm beginning to think we're talking past each other?
> 
> Perhaps, but I think we're really just looking at things differently.
> You're looking at roles having predefined permissions, and I'm looking
> at roles as really just a group of users, and permissions for that
> role can vary throughout the database.

Yes, the permissions are predefined in the sense that defaults are
installed. But they are fully configurable. I'm not proposing that
they be hard coded in any way.

It is difficult to discuss this whole issue when we are coming from
such different backgrounds and seeing things through different
filters. But if I interpret your proposal correctly, there is only one
difference: the ability to have a set of permissions, a role, defined
separately from the groups who use them. So, you can define a set of
permissions to a set of accounts, and then assign them to multiple
groups. In my design, you would have to set each group's permissions
individually. I don't provide for a set of permissions being separate
from a group/role (which are the same thing in my model).

I'm happy to go with the more complex design as long as we're sure the
additional functionality is worth the additional complexity.

-- 
Dr. David C. Merrill                     http://www.lupercalia.net
Linux Documentation Project                dmerrill@lupercalia.net
Collection Editor & Coordinator            http://www.linuxdoc.org
                                       Finger me for my public key

White magic is poetry, black magic is anything that actually works.
		-- Victor Anderson