I need to grant someone the permission to execute a bigquery stored procedure but I don't want to grant them roles/bigquery.admin, I would rather grant only the required permissions via a custom role.
This led me to question the who a stored procedure executes as. I have a background in SQL Server and there is an option there to have a stored procedure execute as owner which means that it runs as the owner of the stored procedure and thus the permissions assigned to that owner...but I don't think there's anything similar in BigQuery.
In short, how do I grant someone permission to execute a stored procedure and do I need to grant the person executing the stored procedure the appropriate permissions on the datasets affected by the stored procedure?
I've pored over the documentation, mainly https://cloud.google.com/iam/docs/understanding-roles#bigquery-roles, but I can't find anything that provides clarity on this issue.
What you describe "it runs as the owner of the stored procedure and thus the permissions assigned to that owner" is similar to the concept of "Authorized Routines". Unfortunately, per the REST documentation, "only UDF [routine] is supported for now".
I've filed a request in the BigQuery public issue tracker here: https://issuetracker.google.com/184160882 You may click the star button on the issue to follow it and show your interest.
Regarding the permissions needed, the bigquery.routines.get permission is required to execute a stored procedure or UDF. This is provided by roles/bigquery.metadataViewer and/or roles/bigquery.dataViewer. In addition, if it is not an authorized routine (which it can't be for procedures at the moment), then yes the query user also requires the appropriate permissions on the datasets affected by the stored procedure.
Resources:
BigQuery permissions
BigQuery roles
Related
In UNIX (and, if my memory is not betraying me, in Linux too), there is a mechanism through which execute permission is given to users (that cannot access other files) but the program itself runs with different credentials, such that the same files the invoking users cannot access, the user of the program can.
Is there any similar (or equivalent) mechanism that would allow a DB-defined user only to execute a specific procedure and nothing else, while the same procedure would have permission to invoke any other procedure within the schema and, if needed, also access other DBs?
If you grant permissions to user to execute specific procedures then user will only be able to execute those procedures. Inside those procedures you can use same schema objects or call other procedures within same schema (called "ownership chaining") or other schema if that other schema is owned by same owner.
If needed, you can use "Execute As" for stored procedures so that user rights inside procedure are different from user that calls those procedures. That gets tricky in some more complex scenarios (e.g. dynamic SQL).
It gets more complicated if you want to call procedures from other database. In that case would recommend using certificates and procedure signing (Erland Sommarskog blog is execelent).
I am configuring the database accounts for some new users. I have come up with the following solution which is 99% of the way to getting the accounts to work but I have hit a problem which I cannot resolve.
Firstly, I created a new login with SQL Server authentication and then gave them the EXECUTE permission to all stored procedures. This allows them to run them all but they cannot view the code and they cannot view the database tables.
Inside the stored procedures I added the following:
WITH EXEC AS OWNER
This allowed the stored procedures to run as the default account we normally use and this has the role of db_owner. This allows the new users to run all the stored procedures and it works great until I hit the following problem:
Some of the stored procedures (all of which are using dynamic SQL) call some synonyms which link to tables in two other databases (history and a data mart database). This gives me the following error:
The server principal "{username}" is not able to access the database "{database name}" under the current security context.
The account which I am using in the WITH EXEC AS is the db_owner of all three databases I am working with.
What can I do to resolve this problem? Many thanks
EXECUTE AS Owner is a database sandbox. Think about it, it has to be. Otherwise a database administrator can issue and EXECUTE AS USER = 'somesystemadmin' and elevate himself to an instance level administrator. The details are described in Extending Database Impersonation by Using EXECUTE AS:
when impersonating a principal by using the EXECUTE AS USER statement, or within a database-scoped module by using the EXECUTE AS clause, the scope of impersonation is restricted to the database by default. This means that references to objects outside the scope of the database will return an error.
The solution is simple: sign the procedure. See Call a procedure in another database from an activated procedure for an example. Read more at Module Signing and Signing Stored Procedures in SQL Server.
I have a procedure which selects data from a table in another database and also uses sp_send_dbmail. It seems execute permission is denied on cross database calls inside the procedure.
Can someone confirm that I need separate permissions on these cross database objects too or is there any way to grant execute permission so it can access anything under that proc?
This is the SQL statement for granting execute permission:
GRANT EXECUTE ON OBJECT::uspAppStoredProcedure TO AppRole;
This is the error I got:
The EXECUTE permission was denied on the object 'sp_send_dbmail',
database 'msdb', schema 'dbo'.
I got a similar error for trying to select data from another database.
This behavior is controlled by the cross db ownership chaining option in SQL Server, which is disabled by default.
uspAppStoredProcedure is attempting to execute a stored procedure outside of its ownership chain, so it would need explicit permission granted to execute the sp_send_dbmail.
It would be possible to enable ownership chaining on the databases involved, which would remove the need for granting specific permissions, but doing so would present a security risk... so it would likely be better to grant explicit access as needed.
This article goes into additional details on cross database ownership chaining.
Another potential solution would be to make use of the EXECUTE AS clause when defining the stored procedure, which would allow you to execute under the context of a different user as described in this article.
This would allow you to create a stored procedure that would allow specific users to execute it while avoiding having to grant permissions to the underlying objects directly to the users.
I am using SQL Server 2008 Express edition.
I have created a Login , User, Role and Schema.
I have mapped the user to the login, and assigned the role to the user.
The schema contains a number of tables and stored procedures.
I would like the Role to have execute permissions on the entire schema.
I have tried granting execute permission through management studio and through entering the command in a query window.
GRANT EXEC ON SCHEMA::schema_name TO role_name
But When I connect to the database using SQL management studio (as the login I have created) firstly I cannot see the stored procedures, but more importantly I get a permission denied error when attempting to run them.
The stored procedure in question does nothing except select data from a table within the same schma.
I have tried creating the stored procedure with and without the line:
WITH EXECUTE AS OWNER
This doesn't make any difference.
I suspect that I have made an error when creating my schema, or there is an ownership issue somewhere, but I am really struggling to get something working.
The only way I have successfully managed to execute the stored procedures is by granting control permissions to the role as well as execute, but I don't believe this is the correct, secure way to proceed.
Any suggestions/comments would be really appreciated.
Thanks.
There are couple of issues that I can see in your case.
First of all you would need View Definition granted for you to be able to see the objects in the Management studio.
I would recommend this if you want the role to have all permissions,
GRANT EXECUTE, SELECT, INSERT, UPDATE, DELETE, VIEW DEFINITION
ON Schema::SchemaName TO [RoleName/LoginName]
Also make sure the owner of your user-defined schema is "dbo".
At the bottom of most of our stored procedures we have a grant similar to
GRANT EXECUTE ON [dbo].[uspFOO] TO [DOMAIN\SQLServerUsers]
Luckily for me, our domain is changing and we now need to go through and change the permissions. Does anyone know of an easy way to do this using the DB metadata so I can pull out all the places where [DOMAIN\SQLServerUsers] is given permission to run and substitute it with [DOMAIN2\SQLServerUsers]?
Thanks.
For those asking, this is on SQL Server 2005.
What version of SQL Server are you on??
In 2005 and up, you could
create a new database role "db_executor" and do
GRANT EXECUTE TO db_executor
grant that database role to all necessary users
This will create a "catch all" role that has execute rights on every existing and future (!!) stored proc in your database. Yes, that does include future stored procs, too! Very handy indeed (at least as long as every user is allowed to execute all stored procs)
That way, you don't have to create separate GRANT EXECUTE statements for each and every stored proc.......