I need to limit access to a particular user, but they still need to be able to see the data in tables owned by dbo.
I'm trying to do the following:
- dbo schema functions as it would normally, has access to everything
- schema1 schema has access to only schema1 objects
- if a schema1 view or stored procedure accesses data in tables owned by dbo, the permissions chain appropriately
- user1 has access to schema1, and nothing else; except in the case of #3
Here's what I've tried:
- Create a user1 user mapped to a test login with a random password
- Created a couple tables in the dbo schema with some test data in them
- Created a schema1 schema
- Created a schema1.get_profiles that selects from a view called schema1.profiles which accesses data in dbo.people, dbo.taglinks, and dbo.tags
However, using the following statement while logged in as user1:
EXEC get_profiles 1
results in:
The SELECT permission was denied on the object 'tags', database 'schema_test', schema 'dbo'.
I have tried WITH EXECUTE AS OWNER
and can't begin to understand how "ownership chaining" is supposed to work.
I have also tried
GRANT EXECUTE ON SCHEMA::schema1 TO user1
GRANT INSERT ON SCHEMA::schema1 TO user1
GRANT SELECT ON SCHEMA::schema1 TO user1
GRANT UPDATE ON SCHEMA::schema1 TO user1
GRANT VIEW DEFINITION ON SCHEMA::schema1 TO user1
but I get the following error (despite being a user with dbo-level access):
Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.
What I need is user1 to be able to access the data via the stored procedures I give it, and nothing else.
Additionally, this is intended to eventually live on an existing SQL Azure database, but I'm testing against a local dummy database first.
Best Answer
The basic concept is to use GRANT/DENY Schema Permissions. You can efficiently manage permissions by creating a role and then adding members to it.
Below is an example that will explain you in detail
Now test :
Now create Stored Procedures :
Now Grant execute permissions to UserA on schemaB's SP
Test it .. to see if UserA is able to run SP from schemaB. This will PASS
But UserA wont be able to see data from SchemaB
Alternatively you can use DATABASE ROLE and just add users to it for better manageability of permissions:
Below statement will make sure that UserA is able to see schemaA and NOT schemaB. The good thing is that you can just add users to
SchemaBUsesSchemaAProc
role and they will inherit all the permissions granted to that role.If you only want to allow UserA to execute SP's which are owned by SchemaB then below statement will do the job:
This way, UserA is not able to see SchemaB's tables, but still can execute procs from SchemaB.
Below will explain the permission hierarchy :