What’s the issue?
Contained databases are a SQL Server feature that allows a database to be more independent of the SQL Server instance hosting it. In a partially contained database, users can be created and authenticated at the database level rather than through server level logins, which means the database can be moved or restored to another instance without requiring login synchronization or recreation.
This finding identifies instances where one or more databases are configured for partial containment. The feature is sometimes enabled intentionally to support portability or specific application requirements, and other times appears as a side effect of database creation by tools that default to containment.
Why is this a problem?
Contained database users authenticate directly against the database without requiring a corresponding server level login. This is convenient for portability, but it also means that anyone with a contained user account can connect to the SQL Server instance and gain access to the contained database without ever appearing in the server level security configuration.
This changes the security review model. Reviewing logins at the server level no longer provides a complete picture of who can connect to the instance, since contained users connect through the same network endpoints but are not visible in sys.server_principals. Reviews must now extend into each contained database to understand the full set of authenticated users.
Contained databases also have a privilege escalation consideration. A user with db_owner rights in a contained database can create new contained users, including users with strong passwords and broad rights inside that database. While the access remains scoped to the contained database, the ability to create authenticated principals without server level approval is a meaningful shift in the security model that deserves careful permission management on the db_owner role.
Containment also affects features that rely on server level objects, including SQL Agent jobs, server level triggers, and certain replication configurations. Some of these continue to work normally, while others may produce unexpected behavior when the database is moved between instances. Teams should verify that any external dependencies are documented and tested before relying on portability.
What should you do about this?
For each contained database, enumerate the contained users with sys.database_principals filtered to user types that include SQL authentication, and review the access list with the application owner.
Confirm that contained database authentication was enabled intentionally and is still required. The instance level setting is checked with EXEC sp_configure ‘contained database authentication’;, and the database level setting is visible in sys.databases. If neither setting was deliberate, plan to disable both: change the database back to full containment with ALTER DATABASE [DatabaseName] SET CONTAINMENT = NONE; (after handling any contained users), then disable the server level option if no databases require it.
For databases that legitimately require containment, document the reason, the owner, and the access list. Review contained users on the same cadence as server level logins so the security posture remains current. Pay particular attention to membership in db_owner for contained databases, since that role can create additional authenticated users within the database.
Read more…
Contained Databases (Microsoft)
Make your database portable by using contained databases (Microsoft)