4. Role-based security
When discussing security in SQL Server, the terms principal and securable
are commonly used. A principal is an entity requesting access to SQL
Server objects (securables). For example, a user (principal) connects to
a database and runs a select command against a table (securable).
When a principal requests access to a securable,
SQL Server checks the permissions before granting or denying access.
Considering a database application with hundreds or thousands of
principals and securables, it's easy to understand how the management of
these permissions could become time consuming. Further, the difficulty
in management could lead to elevated permissions in an attempt to reduce
the time required to implement least privilege.
Fortunately, SQL Server offers several methods
for simplifying permissions management. As a result, you can spend more
time designing and deploying granular permissions to ensure the least
privilege principle is applied all the way down to individual objects
within a database.
Database roles
A database role, defined within a database, can
be viewed in a similar fashion to an Active Directory group in a Windows
domain: a database role contains users (Windows or SQL Server logins)
and is assigned permissions to objects (schema, tables, views, stored
procedures, and so forth) within a database.
Take our earlier example of the difficulty of
managing the database permissions of thousands of users. Using database
roles, we can define the permissions for a database role once, and grant
multiple users access to the database role. As such, the user's
permissions are inherited through the role, and we needn't define
permissions on a user-by-user basis. Should different permissions be
required for different users, we can create additional database roles
with their own permissions.
Let's walk through an example of creating and
assigning permissions via a database role. To begin, let's create a role
called ViewSales in a database called SalesHistory using T-SQL, as
shown in listing 1. We'll assign permissions to the role, select permissions on a view and table, and execute permissions on a stored procedure.
Example 1. Creating a database role
-- Create the Role
USE [SalesHistory]
GO
CREATE ROLE [ViewSales]
GO
-- Assign permissions to the role
GRANT EXECUTE ON [dbo].[uspViewSalesHistory] TO [ViewSales]
GO
GRANT SELECT ON [dbo].[Store] TO [ViewSales]
GO
GRANT SELECT ON [dbo].[vwSalesRep] TO [ViewSales]
GO
|
With the database role in place, we can now
assign logins to the role and have those logins inherit the role's
permission. Consider the T-SQL code in listing 2.
Example 2. Assigning logins to a database role
-- Create Logins from Windows Users
USE [MASTER]
GO
CREATE LOGIN [WIDGETINC\JSMith]
FROM WINDOWS WITH
DEFAULT_DATABASE=[SalesHistory]
GO
CREATE LOGIN [WIDGETINC\KBrown]
FROM WINDOWS WITH
DEFAULT_DATABASE=[SalesHistory]
GO
CREATE LOGIN [WIDGETINC\LTurner]
FROM WINDOWS WITH
DEFAULT_DATABASE=[SalesHistory]
GO
-- Create Database Users mapped to the Logins
USE [SalesHistory]
GO
CREATE USER JSMith FOR LOGIN [WIDGETINC\JSMith]
GO
CREATE USER KBrown FOR LOGIN [WIDGETINC\KBrown]
GO
CREATE USER LTurner FOR LOGIN [WIDGETINC\LTurner]
GO
-- Assign the Users Role Membership
EXEC sp_addrolemember N'ViewSales', N'WIDGETINC\JSmith'
GO
EXEC sp_addrolemember N'ViewSales', N'WIDGETINC\KBrown'
GO
EXEC sp_addrolemember N'ViewSales', N'WIDGETINC\LTurner'
GO
|
The code in listing 2
has three sections. First, we create SQL Server logins based on
existing Windows user accounts in the WIDGETINC domain. Second, we
create users in the SalesHistory database for each of the three logins
we just created. Finally, we assign the users to the ViewSales database
role created earlier. The net effect is that the three Windows accounts
have access to the SalesHistory database with their permissions defined
through membership of the database role.
Apart from avoiding the need to define
permissions for each user, the real power of database roles comes with
changing permissions. If we need to create a new table and grant a
number of users access to the table, we can grant the permissions
against the database role once, with all members of the role
automatically receiving the permissions. In a similar manner, reducing
permissions is done at a role level.
Not only do roles simplify permissions
management, they also make permissions consistent for all similar users.
In our example, if we have a new class of users that require specific
permissions beyond those of the ViewSales role, we can create a new
database role with the required permissions and add users as
appropriate.
Beginning in SQL Server 2005, database schemas
are a distinct namespace, without the tight user coupling that existed
in SQL Server 2000 and earlier. Each database user is created with a default schema
(dbo is the default if none is specified) and is used by SQL Server
when no object owner is specified in T-SQL commands, such as select * from sales.
Objects within a schema can be transferred to another schema, and the
ability to grant or deny permissions at a schema level permits both
powerful and flexible permissions structures. This means that sensitive
tables could be placed in their own schema with only selected users
granted access. Finally, schema permissions can be granted to database
roles; for example, database role users can be granted select permissions on schema standard but denied select permission on schema payroll.
|
In cases where permissions are defined at an application level, application roles can be used.
Application roles
In some cases, access to database objects is
provided and managed as part of an application rather than direct
database permissions granted to users. In such cases, there's typically
an application management function where users are defined and managed
on an administration screen. In these cases, application roles can be
used to simplify permissions. In effect, the application role is granted
the superset of the permissions required, with the individual user
permissions then managed within the application itself.
Application roles are invoked on connection to SQL Server by using the sp_setapprole
stored procedure and supplying an application role name and password.
As with a SQL Server login, you must ensure the password is stored in a
secure location. Ideally, the password would be stored in an encrypted
form, with the application decrypting it before supplying it to SQL
Server.
The side benefit of application roles is that
the only means through which users are able to access the database is
via the application itself, meaning that direct user access using tools
such as SQL Server Management Studio is prevented.
In closing this section, let's consider two additional types of roles: fixed server and database roles.
Fixed server roles
In environments with lots of server instances
and many DBAs, some sites prefer to avoid having all DBAs defined as
members of the sysadmin role and lean toward a more granular approach
whereby some DBAs are allocated a subset of responsibilities. In
supporting this, SQL Server provides a number of fixed server roles in
addition to the sysadmin role, which grants the highest level of access
to the server instance.
An example of a fixed server role is the
processadmin role, used to grant users permissions to view and kill
running server processes, and the dbcreator role, used to enable users
to create, drop, alter, and restore databases. SQL Server BOL contains a
complete listing of the fixed server roles and their permissions.
Similar to fixed server roles, fixed database
roles come with predefined permissions that enable a subset of database
permissions to be allocated to a specific user.
Fixed database roles
In addition to the db_owner role, which is the
highest level of permission in a database, SQL Server provides a number
of fixed database roles. Again, all of these roles and descriptions are
defined in BOL. Commonly used fixed database roles are the db_datareader
and db_datawriter roles, used to grant read and add/delete/modify
permissions respectively to all tables within a database.
One of the nice features of permissions
management within SQL Server is that roles can include other roles. For
example, the db_datareader role could contain the custom ViewSales
database role that we created earlier, in effect granting select
permissions on all tables to members of the ViewSales role, in addition
to the other permissions granted with this role.