I want a RoleGroup to have certain privileges on a specific column in a table ….the roleGroup not DB owner :
grant SELECT, INSERT ,UPDATE (colOne) on table schemaOne.tableOne
to roleGroup;
When I want alter default privileges of this column (to include future users), I get ERROR saying can’t alter default privileges of one column only :
alter default privileges for role DB_OWNER in schema schemaOne grant
select,insert,update(colOne) on table schemaOne.tableOne to
roleGroup;
which forced me to do this :
Alter Default priviliges for role DB_OWNER in schema schemOne grant
select,insert,update to roleGroup ;
what’s the point of the first grant then ?!! Or am I making some mistake ?
The whole question is a bit unclear as both of your statements are syntactically incorrect.
GRANT grants privileges on existing objects, while ALTER DEFAULT PRIVILEGES defines what privileges will automatically be granted to objects created in the future. So the scope of these statements does not overlap, but they complement each other.
I guess you misunderstood that point, otherwise you wouldn't try to ALTER DEFAULT PRIVILEGES on an existing table.
A valid form would be:
ALTER DEFAULT PRIVILEGES FOR ROLE db_owner IN SCHEMA schemaone
GRANT INSERT, SELECT, UPDATE ON TABLES TO rolegroup;
This will grant the privileges on all tables created in that schema by db_owner in the future.
The title of your question suggests that you are wondering why you cannot use ALTER DEFAULT PRIVILEGES to grant privileges on columns.
The likely answer is that not all future tables need to have a column colone, and what should happen with tables that don't have a column of that name. You might argue that no privileges should be granted in that case, and I guess that is a valid option. But it seems hard to come up with a use case for that, which may explain why nobody has considered implementing such a feature so far.
Alternatively, your desire could be that a column that will be added to an existing table in the future should automatically receive the privileges, but again I don't consider such a feature as very useful.
Related
Why a privileged user can't access newly created partition?
PostgreSQL version: 10.0
Suppose my PostgreSQL sever has a user called app with following permissions:
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO app;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public to app;
Now this user app can do select, insert and update action for "existing" table/partition (for example: mytable_partition_old) just as my expectation, everything goes well so far.
However, a master account creates a new partition of a table after the GRANT command above by following:
CREATE TABLE IF NOT EXISTS "mytable_partition_new" PARTITION OF mytable FOR VALUES IN('some_value');
After mytable_partition_new is created, the user app got "permission denied for this relation" by executing INSERT INTO mytable_partition_new values (...) command.
I understand it can be resolved by issue GRANT SELECT, .... TO app again.
My question is if there any better way to achieve it?
(we don't have a dedicated DBA and got stucked in this situation for a while..)
The GRANTs you have shown, only granted the privileges for existing objects. To grant the privileges for "future" objects, you need to alter the default privileges:
alter default privileges in schema public
for role master
GRANT SELECT, INSERT, UPDATE ON TABLES TO app;
alter default privileges in schema public
for role master
GRANT USAGE ON SEQUENCES TO app;
The above will only affect future objects, so for the tables (or partitions) you have already created, you need to re-run you original GRANT statements once again.
I am managing a database that has a number of schemas. I am having some difficulty with setting privileges and would like to request some help.
I have the schema called schemaA and a group_role db_writer
I use the following sql:
GRANT USAGE ON SCHEMA schemaA TO db_writer;
GRANT UPDATE, INSERT, SELECT, DELETE ON ALL TABLES IN SCHEMA schemaA TO db_writer;
However, the db_writer is unable to create views. They are returned with a permission denied error. Also, when I create views, she is then unable to select them...and I have to set the priviliges again for that view.
It was my understanding the views were treated as tables with respect to privileges...and if one is granted certain permissions to all tables in a schema this would apply to views also.
What am I missing? Any advice appreciated.
The problem is USAGE does not allow users to create objects within the database.
Try
GRANT USAGE, CREATE ON SCHEMA schemaA TO db_writer
Edit:
New objects will get default privileges, for the user to have those privileges for objects created in the future you can do it as:
ALTER DEFAULT PRIVILEGES IN SCHEMA schemaA GRANT UPDATE, INSERT, SELECT, DELETE ON TABLES TO db_writer;
ALTER DEFAULT PRIVILEGES IN SCHEMA schemaA GRANT SELECT ON TABLES TO db_reader;
Check this answer for more info
I'm moving from MySQL to PostgreSQL and have hit a wall with user privileges. I am used to assigning a user all privileges to all tables of a database with the following command:
# MySQL
grant all privileges on mydatabase.* to 'myuser'#'localhost' identified by 'mypassword';
It appears to me that the PostgreSQL 9.x solution involves assigning privileges to a "schema", but the effort required of me to figure out exactly what SQL to issue is proving excessive. I know that a few more hours of research will yield an answer, but I think everyone moving from MySQL to PostgreSQL could benefit from having at least one page on the web that provides a simple and complete recipe. This is the only command I have ever needed to issue for users. I'd rather not have to issue a command for every new table.
I don't know what scenarios have to be handled differently in PostgreSQL, so I'll list some of the scenarios that I have typically had to handle in the past. Assume that we only mean to modify privileges to a single database that has already been created.
(1a) Not all of the tables have been created yet, or (1b) the tables have already been created.
(2a) The user has not yet been created, or (2b) the user has already been created.
(3a) Privileges have not yet been assigned to the user, or (3b) privileges were previously assigned to the user.
(4a) The user only needs to insert, update, select, and delete rows, or (4b) the user also needs to be able to create and delete tables.
I have seen answers that grant all privileges to all databases, but that's not what I want here. Please, I am looking for a simple recipe, although I wouldn't mind an explanation as well.
I don't want to grant rights to all users and all databases, as seems to be the conventional shortcut, because that approach compromises all databases when any one user is compromised. I host multiple database clients and assign each client a different login.
It looks like I also need the USAGE privilege to get the increasing values of a serial column, but I have to grant it on some sort of sequence. My problem got more complex.
Basic concept in Postgres
Roles are global objects that can access all databases in a db cluster - given the required privileges.
A cluster holds many databases, which hold many schemas. Schemas (even with the same name) in different DBs are unrelated. Granting privileges for a schema only applies to this particular schema in the current DB (the current DB at the time of granting).
Every database starts with a schema public by default. That's a convention, and many settings start with it. Other than that, the schema public is just a schema like any other.
Coming from MySQL, you may want to start with a single schema public, effectively ignoring the schema layer completely. I am using dozens of schema per database regularly.
Schemas are a bit (but not completely) like directories in the file system.
Once you make use of multiple schemas, be sure to understand search_path setting:
How does the search_path influence identifier resolution and the "current schema"
Default privileges
Per documentation on GRANT:
PostgreSQL grants default privileges on some types of objects to
PUBLIC. No privileges are granted to PUBLIC by default on tables,
columns, schemas or tablespaces. For other types, the default
privileges granted to PUBLIC are as follows: CONNECT and CREATE TEMP TABLE
for databases; EXECUTE privilege for functions; and USAGE privilege for languages.
All of these defaults can be changed with ALTER DEFAULT PRIVILEGES:
Grant all on a specific schema in the db to a group role in PostgreSQL
Group role
Like #Craig commented, it's best to GRANT privileges to a group role and then make a specific user member of that role (GRANT the group role to the user role). This way it is simpler to deal out and revoke bundles of privileges needed for certain tasks.
A group role is just another role without login. Add a login to transform it into a user role. More:
Why did PostgreSQL merge users and groups into roles?
Predefined roles
Update: Postgres 14 or later adds the new predefined roles (formally "default roles") pg_read_all_data and pg_write_all_data to simplify some of the below. See:
Grant access to all tables of a database
Recipe
Say, we have a new database mydb, a group mygrp, and a user myusr ...
While connected to the database in question as superuser (postgres for instance):
REVOKE ALL ON DATABASE mydb FROM public; -- shut out the general public
GRANT CONNECT ON DATABASE mydb TO mygrp; -- since we revoked from public
GRANT USAGE ON SCHEMA public TO mygrp;
To assign "a user all privileges to all tables" like you wrote (I might be more restrictive):
GRANT ALL ON ALL TABLES IN SCHEMA public TO mygrp;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO mygrp; -- don't forget those
To set default privileges for future objects, run for every role that creates objects in this schema:
ALTER DEFAULT PRIVILEGES FOR ROLE myusr IN SCHEMA public
GRANT ALL ON TABLES TO mygrp;
ALTER DEFAULT PRIVILEGES FOR ROLE myusr IN SCHEMA public
GRANT ALL ON SEQUENCES TO mygrp;
-- more roles?
Now, grant the group to the user:
GRANT mygrp TO myusr;
Related answer:
PostgreSQL - DB user should only be allowed to call functions
Alternative (non-standard) setting
Coming from MySQL, and since you want to keep privileges on databases separated, you might like this non-standard setting db_user_namespace. Per documentation:
This parameter enables per-database user names. It is off by default.
Read the manual carefully. I don't use this setting. It does not void the above.
Maybe you could give me an example that grants a specific user
select/insert/update/delete on all tables -- those existing and not
yet created -- of a specific database?
What you call a database in MySQL more closely resembles a PostgreSQL schema than a PostgreSQL database.
Connect to database "test" as a superuser. Here that's
$ psql -U postgres test
Change the default privileges for the existing user "tester".
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT INSERT, SELECT, UPDATE, DELETE ON TABLES
TO tester;
Changing default privileges has no effect on existing tables. That's by design. For existing tables, use standard GRANT and REVOKE syntax.
You can't assign privileges for a user that doesn't exist.
You can forget about the schema if you only use PUBLIC.
Then you do something like this: (see doc here)
GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
[, ...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] table_name [, ...]
| ALL TABLES IN SCHEMA schema_name [, ...] }
TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]
I don't want to grant rights to all users and all databases, as seems to be the conventional shortcut, because that approach compromises all databases when any one user is compromised. I host multiple database clients and assign each client a different login.
OK. When you assign tables to the correct role, the privileges granted will be role-specific and not to all users! Then you can decide who to give roles to.
Create a role for each database. A role can hold many users.
Then assign a client-username to the correct role.
Also assign your-username to each role if needed.
(1a) Not all of the tables have been created yet, or (1b) the tables have already been created.
OK. You can create tables later.
When you are ready, assign tables to the correct client role.
CREATE TABLE tablename();
CREATE ROLE rolename;
ALTER TABLE tablename OWNER TO rolename;
(2a) The user has not yet been created, or (2b) the user has already been created.
OK. Create usernames when you are ready. If your client needs more than one username simply create a second client-username.
CREATE USER username1;
CREATE USER username2;
(3a) Privileges have not yet been assigned to the user, or (3b) privileges were previously assigned to the user.
OK. When you are ready to give privileges, create the user and assign the correct role to her.
Use GRANT-TO command to assign roles to users.
GRANT rolename TO username1;
GRANT rolename TO username2;
(4a) The user only needs to insert, update, select, and delete rows, or (4b) the user also needs to be able to create and delete tables.
OK. You run these commands to add permissions to your users.
GRANT SELECT, UPDATE, INSERT, DELETE ON dbname TO role-or-user-name;
ALTER USER username1 CREATEDB;
I am running PostgreSQL 9.3.2 on Linux.
I have a group role 'data_scientist' and permissions to a particular (already populated) schema like so
grant usage on schema schemaname to data_scientist;
grant select, references, trigger
on all tables in schema schemaname
to data_scientist;
This fixes the problem of data_scientist using past tables. For future tables I added
alter default privileges in schema schemaname
grant select, references on tables
to data_scientist;
Still, whenever a new table is added, other data_scientist's permissions fail on the new tables.
By default, ALTER DEFAULT PRIVILEGES only applies to the role that ran the command. Suppose we have 2 users: ramfjord and animalito. If I (ramfjord) run
ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO public; CREATE TABLE ramfjord_table;
Then animalito will be able to see it. If animalito runs
CREATE TABLE animalito_table
Then ramfjord won't be able to see it, because ramfjord's default privileges don't apply. See default privileges and their owners with \ddp
Because of this, we've stopped using default privileges at my company, and started using explicit GRANT's. To remove default privs, you have to run
ALTER DEFAULT PRIVILEGES FOR ROLE <owner> REVOKE...
The owner, schema, relation type and privileges have to match those listed in \ddp for this command to do anything. Do not just delete everything from the internal table that stores default privileges... trust me.
What are min permission we need to truncate table ? Apart from DDLAdmin. And what is best pratice to give permission to the user to truncate the user on SQL 2008 R2
Truncate table documentation at books online here
Permissions
The minimum permission required is
ALTER on table_name. TRUNCATE TABLE
permissions default to the table
owner, members of the sysadmin fixed
server role, and the db_owner and
db_ddladmin fixed database roles, and
are not transferable. However, you can
incorporate the TRUNCATE TABLE
statement within a module, such as a
stored procedure, and grant
appropriate permissions to the module
using the EXECUTE AS clause. For more
information, see Using EXECUTE AS to
Create Custom Permission Sets.
MSDN:
The minimum permission required is
ALTER on table_name. TRUNCATE TABLE
permissions default to the table
owner, members of the sysadmin fixed
server role, and the db_owner and
db_ddladmin fixed database roles, and
are not transferable.
If you don't want to grant rights (which are excessive, really, and described in other answers) you can escalate permissions within a stored procedure...
CREATE PROC DoTruncate
WITH EXECUTE AS OWNER
AS
TRUNCATE TABLE Mytable
GO
And permission this instead with "normal" rights