TechRepublic's free SQL Server newsletter, delivered each Tuesday, contains hands-on tips that will help you become more adept with this powerful relational database management system. Automatically subscribe today!
Imposing security on a database typically involves use of three database objects—logins, users, and roles. It's ingrained in the minds of SQL Server developers to think about the following tools in this specific order: logins, users, and roles. However, every time I used logins, users, and roles in that order, I felt like there must be a more effective method. After several attempts, I devised a plan that's much more efficient. I'll explain what's wrong with the current way of using SQL, and then I'll describe my effort to improve upon this logic.
Identifying the problem with the natural order
Here are three tools SQL Server developers have available to them, listed in the natural order:
- Logins: A login identifies a user and a password and allows the user to access the database instance.
- Users: A user identifies a user from the group of logins and allows the user access to one or more databases on the instance.
- Roles: A role identifies a collection of users and grants them all the same set of permissions.
Due to deadline pressures, developers are often forced to think in terms of this order. In my opinion, this is precisely the wrong way to think about security.
Rethinking the natural order
The natural order places roles at the bottom of the list, but when you're designing a database, I believe it makes more sense to think about roles rather than specific users. Therefore, here's how I suggest the list should be ordered:
- Roles: A role identifies a collection of users and the permissions that collection enjoys.
- Users: A user is a member of a role.
- Logins: A login permits a user to get into one or more databases.
Design the roles from the bottom up; that is, think of the least powerful role first and then each successive role. Also, it's important to note that a role can be a user. This is the where the architectural power lies.
A sample scenario
Let's suppose that we have five roles:
- Role 1: Data-entry only. This person cannot add to the various lookup tables, and conversely is dependent upon the required lookups being available.
- Role 2: Manager is responsible for adding the lookups required by Role 1 and can do data entry in a pinch. This person has access to a limited number of reports (i.e., stored procedures that deliver the data for the reports).
- Role 3: Supermanager has access to all of her underlings' reports, plus some they cannot see.
- Role 4: Director has access to everything and saves changes to the database in a structural way.
- Role 5: Developer/DBA (in a big organization this might be two roles, with DBA as Role 6).
A note about table
The cardinal rule is no one (except the Developer/DBA) has direct access to tables. This means that you need to create sprocs, views, and UDFs to provide UIDS (Update, Insert, Delete, Select) access to the tables. You impose permissions upon these objects, not upon the tables themselves.
Here's how we might utilize this information:
- Map who needs to do what. This mapping may reveal the need for a new sproc, UDF, or view.
- Create the roles, beginning with the least powerful. We need to have an accurate vision of exactly what powers the least powerful role requires.
For example, Role 1 needs the ability to add to and edit Table1, Table2, and Table3 and delete from Table2 and Table3 but not Table1. She cannot actually address the tables. Therefore, her permissions pertain to the stored procedures that enable these capabilities but not to the tables themselves. This principle applies all the way up the line, with the exception of Developer/DBA.
In the case of Role 2, we would want to add Role 2 as a user of Role 1. Then, Role 2 automatically gains all the powers of Role 1, plus the additionally specified powers of Role 2.
Similarly, for Roles 3, 4, and 5, each new role is recorded once as a member of the preceding role, thereby inheriting all of its permissions. Then, we can add additional permissions.
In Role 5, Developer/DBA inherits everything already declared, plus the ability to alter structures, create and delete objects, and even create and delete databases.
The ultimate role, DBA, can create or destroy entire instances of the database server and any object beneath that level in the tree.
Questioning the current logic
Understandably (and responsibly), you feel the need to meet deadlines, but at what cost? If you haven't got time to do it right, where will you find the time to do it again?
To think effectively about roles, users, and logins, you must demand that your manager specifies the roles. (Remember to emphasize the fact that this will help you meet your deadlines.) Then, you can proceed to create the roles; add the higher roles to lower roles as users if required; finally, create the users and assign them to their highest role.
I can attest that this method works and is more efficient than the natural order most SQL Server developers are forced to use. If you've refined your own approach to working around this frustrating problem, I'd love to hear about it. Please describe your method in the article discussion.