DDL_admin vs db_owner permissions

db_ddladmin vs db_owner

From what I can tell from what I tested and read up on, for the most part your list looks accurate except db_ddladmin DOES allow you to CREATE SCHEMA. I did confirm that the other security permissions you listed were indeed denied.

Denied with DDLADMIN only:

[ALTER ANY USER]

[BACKUP DATABASE], [BACKUP LOG], [CHECKPOINT]

[ALTER ANY APPLICATION ROLE], [ALTER ANY ROLE]

[DROP DATABASE]

Noting that the. . .

  1. db_datareader will allow SELECT access to all tables
  2. db_datarwriter will allow INSERT, UPDATE, and DELETE access to all tables
  3. db_executor will allow EXECUTE access to all executable objects

Additonally, having db_ddladmin role permissions may mean. . .

Note: Since you have so many different versions of SQL Server from 2005 - 2014, it may be best to have a small set of users test this initially to see who screams to iron out any kinks, etc.

  • Objects they own with this role will not be owned by DBO so you may have to deal with ownership chaning issues if there's ever a problem with something at this level. I'm not 100% certain that this would be a problem but it's worth mentioning just in case.

    Source: Ownership Chains

  • With this role (may vary depending on the version of SQL Server) they may be able to add SQL security principles defined in the current DB to objects they own still, just not all objects (ones they do not own) nor add a new server-level defined principal to the DB level.


Additionally, not having DBO role permissions may mean. . .

Note: Since you have so many different versions of SQL Server from 2005 - 2014, it may be best to have a small set of users test this initially to see who screams to iron out any kinks, etc.

  • Not having the DBO role may prevent certain SSMS designer GUI interfaces (SQL Server version varying) from populating or opening without error (e.g. when modifying tables or columns through the GUI) even though doing it via T-SQL works and the permissions are in place. In some versions of SQL Server this may be resolved by allowing GRANT VIEW DEFINITION where this is an issue and it can also just be a warning only on certain versions of SQL Server.

    Resources

    • You are not logged in as the database owner or as a user that is a member of the db_owner role. You will not be able to save changes to tables that you do not own.

    • db_ddladmin Role doesn't allow use of "design" functions in SSMS

      "We try to prevent giving users/developers dbo in their QA databases as much as we can. One of the problems with this is that they still need to be able to create and modify database objects such as user tables. Many devs are new to MS SQL and thus tend to stick with the GUI (SSMS) for this sort of work. The problem arises when we grant them db_ddladmin (not dbo) and they are no longer able to modify tables or columns via the table designer GUI. Instead, they have to take additional time to learn the TSQL commands and their syntax (that they may never need again) or engage the DBA team which takes time away from our other activities.

      I don't know if this is a bug or a feature request but I consider it a bug since the user has sufficient permissions to alter the table via TSQL but the GUI gives them messages stating:

      "You are not logged on as the database owner or system administrator. You might not be able to save changes to tables that you do not own." AND "Table [schema].[table] is set to read only, user doesn't have enough rights on this table."

      A trace seems to point to the check being a is_member('db_owner') which will preclude members of db_ddladmin even though they do in fact have permissions to modify the object. Microsoft SQL Server Management Studio"


      Posted by Agent DBA on 1/25/2010 at 7:06 AM

      I had a similar issue and managed to solve it by performing the following grant

      GRANT view definition on schema:: <schemaname> to <username>
      

Other Considerations

Since you state that this is being reviewed on a case-by-case basis

One of the permissions currently being limited is db_owner permissions.

This permission is being reviewed on a case-by-case basis, but a common change is to replace the db_owner permissions with the following:

  • db_datareader
  • db_datawriter
  • db_ddladmin
  • db_executor

Have you considered creating additional custom roles for more "all object" DB-level access that each person needs rather than granting them the db_ddladmin role as that will probably give them more than they actually need to DB level objects as well.

I usually give what's needed exactly and nothing more for them to do their job and if there's a "usual" or "standard" need for DB level object access to all objects in a DB, I create a custom DB role sort of like the the db_executor but see my below example. This way you can grant the people what they really need to ALL DB object in a particular DB if you're not getting object level explicit in your DBs for their security.

----Custom Database Roles

/* CREATE A NEW ROLE  -- Execute to all stored procs including newly created ones*/
-- Database specific
CREATE ROLE db_All_StoredProc_Execute
GRANT EXECUTE TO db_All_StoredProc_Execute

/* CREATE A NEW ROLE  -- Alter to all stored procs including newly created ones*/
-- Database specific
CREATE ROLE db_All_StoredProc_Alter
GRANT ALTER ANY SCHEMA TO db_All_StoredProc_Alter

/* CREATE A NEW ROLE  -- View Definition to all stored procs including newly created ones*/
-- Database specific
CREATE ROLE db_All_StoredProc_View
GRANT VIEW DEFINITION TO db_All_StoredProc_View

/* CREATE A NEW ROLE - Any schema alter and create procedure permissions */
-- Database specific
CREATE ROLE db_All_CreateProc_AlterSchema
GRANT ALTER ANY SCHEMA TO db_All_CreateProc_AlterSchema
GRANT CREATE PROCEDURE TO db_All_CreateProc_AlterSchema
GO

/* CREATE A NEW ROLE - Any schema alter and create table permissions */
-- Database specific
CREATE ROLE db_All_CreateTable_AlterSchema
GRANT ALTER ANY SCHEMA TO db_All_CreateTable_AlterSchema
GRANT CREATE TABLE TO db_All_CreateTable_AlterSchema

/* CREATE A NEW ROLE - Any schema alter and create function permissions */
-- Database specific
CREATE ROLE db_All_CreateFunction_AlterSchema
GRANT ALTER ANY SCHEMA TO db_All_CreateFunction_AlterSchema
GRANT CREATE FUNCTION TO db_All_CreateFunction_AlterSchema

/* CREATE A NEW ROLE - Any schema alter and create aggregate permissions */
-- Database specific
CREATE ROLE db_All_CreateAggregate_AlterSchema
GRANT ALTER ANY SCHEMA TO db_All_CreateAggregate_AlterSchema
GRANT CREATE AGGREGATE TO db_All_CreateAggregate_AlterSchema

/* CREATE A NEW ROLE - Any schema alter and create view permissions */
-- Database specific
CREATE ROLE db_All_CreateView_AlterSchema
GRANT ALTER ANY SCHEMA TO db_All_CreateView_AlterSchema
GRANT CREATE VIEW TO db_All_CreateView_AlterSchema

/* CREATE A NEW ROLE - Any schema alter and create schema permissions */
-- Database specific
CREATE ROLE db_All_CreateSchema_AlterSchema
GRANT ALTER ANY SCHEMA TO db_All_CreateSchema_AlterSchema
GRANT CREATE SCHEMA TO db_All_CreateSchema_AlterSchema

I also wanted to share a db_DDLAdmin_Restriction role you may want to consider to consider creating otherwise with explicit DENY to restrict what db_ddladmin give access to so you could at least create this on the DBs where you grant them this role and set the explicit DENY for the actual object types, etc. you don't want them to have access to.

For example, if you know they will definitely be creating stored procedures and functions, you can exclude DENY CREATE FUNCTION, DENY CREATE PROCEDURE, DENY ALTER ANY SCHEMA.

---Create ddladmin restriction custom DB role
DENY ALTER ANY ASSEMBLY                    TO db_DDLAdmin_Restriction
DENY ALTER ANY ASYMMETRIC KEY              TO db_DDLAdmin_Restriction
DENY ALTER ANY CERTIFICATE                 TO db_DDLAdmin_Restriction
DENY ALTER ANY CONTRACT                    TO db_DDLAdmin_Restriction
DENY ALTER ANY DATABASE DDL TRIGGER        TO db_DDLAdmin_Restriction
DENY ALTER ANY DATABASE EVENT NOTIFICATION TO db_DDLAdmin_Restriction
DENY ALTER ANY DATASPACE                   TO db_DDLAdmin_Restriction
DENY ALTER ANY FULLTEXT CATALOG            TO db_DDLAdmin_Restriction
DENY ALTER ANY MESSAGE TYPE                TO db_DDLAdmin_Restriction
DENY ALTER ANY REMOTE SERVICE BINDING      TO db_DDLAdmin_Restriction
DENY ALTER ANY ROUTE                       TO db_DDLAdmin_Restriction
DENY ALTER ANY SCHEMA                      TO db_DDLAdmin_Restriction
DENY ALTER ANY SERVICE                     TO db_DDLAdmin_Restriction
DENY ALTER ANY SYMMETRIC KEY               TO db_DDLAdmin_Restriction
DENY CHECKPOINT                            TO db_DDLAdmin_Restriction
DENY CREATE AGGREGATE                      TO db_DDLAdmin_Restriction
DENY CREATE DEFAULT                        TO db_DDLAdmin_Restriction
DENY CREATE FUNCTION                       TO db_DDLAdmin_Restriction
DENY CREATE PROCEDURE                      TO db_DDLAdmin_Restriction
DENY CREATE QUEUE                          TO db_DDLAdmin_Restriction
DENY CREATE RULE                           TO db_DDLAdmin_Restriction
DENY CREATE SYNONYM                        TO db_DDLAdmin_Restriction
DENY CREATE TABLE                          TO db_DDLAdmin_Restriction
DENY CREATE TYPE                           TO db_DDLAdmin_Restriction
DENY CREATE VIEW                           TO db_DDLAdmin_Restriction
DENY CREATE XML SCHEMA COLLECTION          TO db_DDLAdmin_Restriction
DENY REFERENCES                            TO db_DDLAdmin_Restriction
GO

Using a SQL Script to list all the permissions, I went and created users for each case.

EXECUTE AS USER = 'test_user'
SELECT 
    permission_name 
FROM fn_my_permissions(null, 'DATABASE')
ORDER BY subentity_name, permission_name
REVERT;

I then compared the results, and came to the following list, with documentation from primarily msdn (any quotes not specifically referenced are from the msdn link).
Below is some of the documentation I used to inform the people who would be losing dbo permissions what exactly they were losing.

ALTER

Confers the ability to change the properties, except ownership, of a particular securable. When granted on a scope, ALTER also bestows the ability to alter, create, or drop any securable that is contained within that scope. For example, ALTER permission on a schema includes the ability to create, alter, and drop objects from the schema.

ALTER ANY APPLICATION ROLE
ALTER ANY DATABASE AUDIT
ALTER ANY ROLE
ALTER ANY USER

Confers the ability to CREATE, ALTER, or DROP individual instances of the Database Securable. For example, ALTER ANY SCHEMA confers the ability to create, alter, or drop any schema in the database.

Application roles are database principals that enable an application to run with its own, user-like permissions.

Auditing an instance of SQL Server or a SQL Server database involves tracking and logging events that occur on the system. The Database-Level Audit Specification object belongs to an audit. You can create one database audit specification per SQL Server database per audit.

Database Roles are used to easily manage the permissions in your databases, SQL Server provides several roles which are security principals that group other principals. They are like groups in the Microsoft Windows operating system. Database-level roles are database-wide in their permissions scope.

AUTHENTICATE
Found in msdn.

AUTHENTICATE & AUTHENTICATE SERVER permissions are only used when using EXECUTE AS in cross database and server-access (respectively) scenarios.

BACKUP DATABASE
BACKUP LOG

CONNECT REPLICATION

Used for database replication permissions.

CONTROL

Confers ownership-like capabilities on the grantee. The grantee effectively has all defined permissions on the securable. A principal that has been granted CONTROL can also grant permissions on the securable.

CREATE ROLE

Confers to the grantee the ability to create the Database Securable.

SHOWPLAN

Showplan permissions are used for various Showplan SET statement options when they are used with Transact-SQL batches.

SUBSCRIBE QUERY NOTIFICATIONS

Documentation about query notifications.

Built upon the Service Broker infrastructure, query notifications allow applications to be notified when data has changed. This feature is particularly useful for applications that provide a cache of information from a database, such as a Web application, and need to be notified when the source data is changed.

TAKE OWNERSHIP

Enables the grantee to take ownership of the securable on which it is granted.

VIEW DATABASE STATE

Used to view Dynamic Management Views and Functions (Transact-SQL).

VIEW DEFINITION

Documentation on view definition permissions.

The VIEW DEFINITION permission lets a user see the metadata of the securable on which the permission is granted. However, VIEW DEFINITION permission does not confer access to the securable itself. For example, a user that is granted only VIEW DEFINITION permission on a table can see metadata related to the table in the sys.objects catalog view. However, without additional permissions such as SELECT or CONTROL, the user cannot read data from the table.