How do I grant view permissions so a SQL Login can see only one database?

Rob Jarrett 96 Reputation points
2021-01-06T17:56:25.177+00:00

I want to create a database (SAMPLE) with an system administration account and then access it using a SQL Login, similar to a service account.

That SQL Login should not be able to see the other databases in my server instance. Online, there are many articles that offer one of three variations on a solution.

Option 1. do the following a) DENY ANY DATABASE to the user and then b) grant permissions on the database in the User Mappings. This does not work.

Option 2. do the following a) DENY ANY DATABASE to the user and then b) ALTER AUTHENTICATION on the database. This works, but changes the ownership of the database to the user SQL Login. I don't want this. The system admin account used to create the database needs to remain its owner. The SQL Login should be able to view it.

Option 3. involves using "contained" databases, which is not an option for me.

Conceptually, I am thinking there should be a fourth option that looks something like:

Option 4. do the following a) DENY ANY DATABASE to the user and then b) GRANT VIEW ON DATABASE::SAMPLE TO SAMPLE_USER. This would deny blanket visibility while restoring itemized visibility, but I have not figured it out.

Testing Results:

This is what the SAMPLE_USER sees when I implement Option 1. It does not expose the SAMPLE database to the SAMPLE_USER Login, even though it is mapped. This does not work.

54116-001.png

This is what SAMPLE_USER sees when I implement Option 2. This works, however, it changes the database ownership which I cannot allow.

54015-002.png

I am going to add a follow on with details of how this is configured. But, the question is, how do I grant view permissions to ONE database that does not change the ownership of that database?

SQL Server | Other
0 comments No comments
{count} votes

Accepted answer
  1. Rob Jarrett 96 Reputation points
    2021-01-06T19:55:38.71+00:00

    Bottom line: We cannot limit what the SQL Login sees without changing is role in an unacceptable way, but we can control what it can access.

    https://www.mssqltips.com/sqlservertip/2995/how-to-hide-sql-server-user-databases-in-sql-server-management-studio/

    Per the article,

    Conclusion
    …there are limited options to hiding databases. Once you hide all databases the only logins that can see the databases are the logins that are the owners of the database or if the login is a sysadmin. Also, each database can only have one owner, so you can’t assign multiple owners to the same database.

    Solution:

    Start with a database (SAMPLE), a database level user (SAMPLE_USER) that is linked to a server level login (SAMPLE_LOGIN).

    Use the server level login (SAMPLE_LOGIN) to set its Mappings to include the SAMPLE database.

    54050-d.png

    Here you can see what my SAMPLE_LOGIN sees at the server level (everything) while it throws an error if I try to access any database…

    54096-a.png

    In contrast, when SAMPLE_LOGIN tries to access a database that it is mapped to (as SAMPLE_USER is a database level user account that links to the server level SAMPLE_LOGIN), it can see the objects inside that database that have been granted to it under database user’s Securable permissions.

    54107-b.png 54108-c.png

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Rob Jarrett 96 Reputation points
    2021-01-06T18:11:38.137+00:00

    Background:

    Here is my source database.

    54088-003.png

    When we look at the database properties, it has my domain\user account as the owner, because I created it.

    54055-004.png

    I then created a SAMPLE_USER account with login to allow me to connect into SQL server (using SQL Authentication and the SAMPLE_USER login).

    54056-005.png

    However, when I connect using that account, the database is not visible.

    54049-006.png

    The SAMPLE_USER database user account is linked to the server level SQL Login of the same name.

    It owns no schemas. This is a viewer, not an owner…

    53839-007.png

    It has db_datareader permissions…

    54132-008.png

    It has connect permissions to the database…

    54057-009.png

    Looking at the SQL Login level

    54089-010.png

    It is in the public role.

    54124-011.png

    It is mapped to the SAMPLE database. Note:

    54058-012.png

    Finally, the SQL Login has connect permissions on my local machine.

    54066-013.png

    When I connect to the server, I use the SAMPLE_USER login…

    54033-014.png

    So, this represents Option 1.

    54034-015.png

    This is the script for Option 2.

    54035-016.png

    As mentioned previously, this works, but…

    54036-017.png

    It changes the ownership. This is not allowable. I don’t want SAMPLE_USER owning it, but simply connecting and viewing it.

    0 comments No comments

  2. Tom Phillips 17,771 Reputation points
    2021-01-06T18:26:15.56+00:00

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.