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.
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.
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…
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.