Using Window Authentication via Active Directory Groups, if an Active Directory user exists in two different Active Directory Groups with different permissions to a database, which Active Directory group does it use to set the permissions?

  1. The most restrictive
  2. The least restrictive
  3. Cumulative of the two
  4. Random

Setting this up in a test environment is proving difficult, because I am not a domain administrator, and we have no test domain. Plus we have seen results both ways. Just wondering if anybody knows the answer.


2 Answers 2


Rights applicable to the login are summed then applied from least restrictive to most restrictive on a per object basis. DENY'd rights take precedence over GRANT'd rights.

Taken from the MSDN SQL Server page on Database Engine Permissions:

Checking permissions can be complex. The permission check algorithm includes overlapping group memberships and ownership chaining, both explicit and implicit permission, and can be affected by the permissions on securable classes that contain the securable entity. The general process of the algorithm is to collect all the relevant permissions. If no blocking DENY is found, the algorithm searches for a GRANT that provides sufficient access. The algorithm contains three essential elements, the security context, the permission space, and the required permission.

General Steps of the Algorithm

  • When the algorithm is determining whether to allow access to a securable, the precise steps that it uses can vary, depending on the principals and the securables that are involved. However, the algorithm performs the following general steps:

    1. Bypass the permission check if the login is a member of the sysadmin fixed server role or if the user is the dbo user in the current database.

    2. Allow access if ownership chaining is applicable and the access check on the object earlier in the chain passed the security check.

    3. Aggregate the server-level, database-level, and signed-module identities that are associated with the caller to create the security context.

    4. For that security context, collect all the permissions that are granted or denied for the permission space. The permission can be explicitly stated as a GRANT, GRANT WITH GRANT, or DENY; or the permissions can be an implied or covering permission GRANT or DENY. For example, CONTROL permission on a schema implies CONTROL on a table. And CONTROL on a table implies SELECT. Therefore, if CONTROL on the schema was granted, SELECT on the table is granted. If CONTROL was denied on the table, SELECT on the table is denied.

    5. A GRANT of a column-level permission overrides a DENY at the object level.

    6. Identify the required permission.

    7. Fail the permission check if the required permission is directly or implicitly denied to any of the identities in the security context for the objects in the permission space.

    8. Pass the permission check if the required permission was not denied and the required permission contains a GRANT or a GRANT WITH GRANT permission either directly or implicitly to any of the identities in the security context for any object in the permission space.


Purely for completeness (since I keep forgetting it myself, and this was the top Google result at the time I last needed it), you can determine which server and database credentials apply to your current login, using the sys.login_token and sys.user_token views. These will tell you all the AD groups that SQL Server has applied to your session, at the server and current-database levels.

If you join those views to the sys.server_principals or sys.database_principals views (typically via sid or principal_id columns), you can derive which ones are actually applying defined server or database roles to you.

If you further join those to the sys.server_permissions or sys.database_permissions (typically via grantee_principal_id), you can determine which are actually applying grants to individual objects.

I don't know of any way to see current tokens for users other than your own, though (although the join between *_principals and *_permissions still provides a good starting reference).


This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .