We are using SQL Server multi-tenancy using views.
All our stored procedures use only views and tables are completely restricted.
We use grant execute permission to all our stored procedures to execute.
To restrict our developers not to use any tables instead of views, can we have a rule or constraint or check which stops creating or altering stored procedures with tables.
Please provide your suggestions.
DDL Triggers
Example:
CREATE TRIGGER safety
ON DATABASE
FOR DROP_TABLE, ALTER_TABLE
AS
PRINT 'You must disable Trigger "safety" to drop or alter tables!'
ROLLBACK;
Related
I work for a large organization that relies heavily on SQL developer for financial reconciliation. We have only SELECT privileges. Several people have access to the same SQL statements, is there a way to ensure they cant change the code? We need to ensure that people who have access to run our SQL statements to generate a report, do not have the ability to change the code. This forces them to submit change requests if they need the code change, which helps us to create and audit log of the changes made. Our financial audit includes audit of our SQL statements. With too many people making changes it is hard to track/validate the change.
Remove their privileges to SELECT from the tables directly.
Wrap the existing code in a stored procedure (if bind variables are used in the SQL statement then they can be arguments to the stored procedure).
This also allows you to put additional code for verification/auditing inside the stored procedure so that it is automatically run with the query(ies) that the users require.
Create a ROLE and grant the EXECUTE privilege on the stored procedure to that role.
Give that role only to the people who are required to run that stored procedure.
Version: PostgresQL 9.6
I create a trigger.
Even if I create a trigger as a superuser, the owner of the database can remove the trigger.
Is it possible to protect the trigger from deletion?
You cannot keep the owner of the table from dropping a trigger on it unless you want to go to the extreme of writing an event trigger for that.
Maybe you should use a different permission concept where you give people only limited privileges if you want to keep them from dropping your triggers. Instead of allowing others to own tables, grant others privileges on the tables.
One of my models in Phoenix application has append-only semantics. There will be events that can be created, but should never be updated by the application (read only after creation).
Is there a postgres mechanism to enforce such thing on a table?
How should I define my migration to use it?
You can set the permissions on the table to allow INSERT and SELECT but not, for example, UPDATE or DELETE for the role that is used to access the data. This way there is no possibility to alter the data.
More information on permissions.
I have a Postgresql database for a web application. The database is owned by a particular user on the system, let's say foouser. As the owner, this user has full permissions on the database.
The server also has another user, let's say webappuser, which is the user under which the application server runs. Instead of specifying a username and password in the web application's config file, I want to use "peer" authentication. I have gotten the authentication to work properly, but I ran into the following issue.
When I created the webappuser role in Postgresql, I granted it LOGIN permission as well as GRANT ALL ON DATABASE foo TO webappuser; and within the database GRANT ALL ON SCHEMA public TO webappuser;.
The issue that I am having is with the table permissions. Unlike MySQL which allows access by default to all tables if you have access to the database (a reasonable assumption in my opinion), Postgresql denies access to all of the tables even though permission has been given on the schema and the database. In order to get around this, I have to explicitly grant permissions on all new tables, views, procedures, etc. that I create using GRANT ALL ON TABLE table_name TO webappuser; (and similarly for views, etc.).
It ends up that any time I run a database migration, I have to add the permissions to the database for the new tables that were created. The problem is that I can't add this permission information to the migrations themselves because developer machines don't have that additional user. In any case, that really looks like the wrong way of doing things.
How can I allow access to the database tables from this additional user without needing manual intervention every time a table, view, procedure, etc. is created?
BONUS POINTS: Is there a way to restrict the user's permission to only CRUD operations instead of full permissions and still do the whole thing automatically?
Without experience with the specifics of Laravel migrations: When you do migrations on the same server there should be no problem, so long as the permissions are also migrated, because the webappuser is available cluster-wide.
When migrating to a different server you need to create the user on that new server and set the permissions for all migrated objects. You basically have two ways to do that.
The first is to set default privileges on the tables in the schema before you migrate or GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA sch_name TO webappuser after the migration. Default privileges are set with:
ALTER DEFAULT PRIVILEGES IN SCHEMA sch_name
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO webappuser;
Both commands are fully SQL-standard compliant so you should have no problems across compliant architectures.
Keep in mind that any other tables created in the same schema will also have privileges set for webappuser. Setting privileges this way for an "untrusted" user (the person using the web application) is not recommended in a production environment because of potential privilege leaks; in a development environment it may be acceptable.
The second - which I would favour personally - is to write a stored procedure that sets the appropriate permissions. Do the migration, run the stored procedure once and you should be up-and-running. This gives you more control over the permission granting. The procedure could be something like:
CREATE FUNCTION grant_webapp_privileges() RETURNS void AS $$
-- Create the webappuser, if necessary
CREATE ROLE webappuser LOGIN;
-- Grant privileges on all required objects
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE table1 TO webappuser;
...
$$ LANGUAGE SQL;
On the master database you simply need to keep the stored procedure up-to-date when you create or drop new relations. If Laravel supports insertion of code blocks not in the schema you are migrating, you can make the above procedure an anonymous code block that gets executed after the migration.
(As an aside, I NEVER give webappuser-like roles CRUD access. Instead I always provide access through views that hide some of the underlying data model specifics, such as a person having an address, contact_information and other details; the view serves it all up in one big row. That way you can easily change the underlying relations and update the view, rather than having to tweak your web application. Same principle really as OOP and easier to manage privileges.)
SQL server has an option to create proxy user accounts with the statement
CREATE USER proxyUser WITHOUT LOGIN;
I couldn't find much help on internet on getting the db2 (v8) equivalent of this. I'm not sure whether this is possible, if yes please let me know how.
The scenario where i want to use this is as follows.
I have table with ~8 million records which gets updated daily. Before the inserts happen, few records are deleted from the table and the number is ~2 million. Since these deletes need not be logged, we decided on setting off Logging during the deletes. Since our credentials do not have alter table rights, we decided to put the ALTER and DELETE statements in a script and and execute the script using the proxy account irrespective of what user executes the SP.
I foud this article which closely describes the scenario which i described above. The differences are that i need to do this on db2 and i need to do deletes without logging them.
http://www.mssqltips.com/sqlservertip/2583/grant-truncate-table-permissions-in-sql-server-without-alter-table/
Thanks
Arjun
It will work basically in the same manner in DB2, with a few exceptions. Firstly, there's no TRUNCATE TABLE statement in DB2 8.2 (and there's no DB2 version 8 on Linux). Secondly, there are no database users in DB2 -- all users are defined externally in the operating system, so there's no CREATE USER statement either.
All statements in a stored procedure, except dynamic SQL, are executed with the authorization of the procedure creator.
So, using the authorized ID, e.g. the database administrator's ID, create the stored procedure that does what you need (ALTER, DELETE, whatever), then grant the EXECUTE privilege on that procedure to whoever needs to run it.