This is a repost of an article from my old blog about CodaServer. It's being published here for posterity.
Most business systems implement the concept of "users," those crazy scamps who login and actually use the software. They're pretty important; each has different capabilities within the system and their access levels need to be made available to application code so that it can render a suitable interface.
The Old Way
Traditional database systems have very solid user management systems with one caveat: Nobody uses them.
This is one of the greatest antipatterns in enterprise development. Due to the impedance mismatch between object-oriented application code and relational database tables, most application frameworks find it expedient to use a single database user with global permissions on the schema and implement a separate user management piece using database tables. This is bad on several fronts.
- Database permissions are pretty bulletproof. If you don't have INSERT on a table, you can't stick anything into it.
- Custom user management code is error-prone. All of the thinking needs to be done by developers on a timeline.
- Custom user management code reinvents the wheel, poorly. I have seen a number of half-baked permission schemes in my day, and I'm not really that old. There is no consistancy from one company to the next and the inner workings/caveats of these systems tend to live in the head of one or two developers.
That said, developers have no choice but to do it this way. The CRUD model used in SQL simply isn't dynamic enough for a good permissions architecture.
Everything is an UPDATE.
Once you grant UPDATE on a table, you pretty much give a user access to do anything they want with it.
The CodaServer Way
CodaServer has a much different approach. It is role-based, meaning that permissions are always assigned to roles rather than assigned to users directly. Being the Business Rules Engine, it isn't limited to having CRUD as a model. You can create a process map that goes something this:
- Enter leads to Place or Cancel.
- Place leads to Ship or Cancel.
- Cancel doesn't lead to anything.
Developers can then assign roles permissions on Enter, Place, Ship, and Cancel. It also has an ACL-type permission scheme where developers can create adhoc permissions and grant them to roles, SQL-style permissions for table objects, and permissions for stored procedures.
This plurality of permission schemes is meant to obviate the need for roll-it-yourself user management code and remove a major headache from developement.
Another way that CodaServer differs from traditional SQL databases is that the role-based permissions system is actually part of the schema for each application. It is deployed with the application as it moves between different environments and the roles themselves are managed by developers rather than database administrators. (The administrators have their own domain of responsibility covered in an upcoming article)
The logic behind this is that saying which role has what access to the system is very much a part of the business rules. Is there any reason why a shipping clerk should not be able receive a shipment in the development instance but should in production? Probably not. You may want to say that Charlie should be stripped of his shipping clerk role because things he signs for tend to disappear, but the role itself is still a valid entity and shouldn't change.
A user in CodaServer can have any number of roles in an application environment, and their permissions in the system are a union of all the permissions of the roles they have been granted. Metadata about a user's roles and permissions can be gleaned through the SHOW ROLES and SHOW PERMISSIONS commands. No more trolling around in the information_schema.
Finally, a user management system that works with you rather than against you.
Til next time.
If you like this post, you should follow me on Twitter.