Grant all on a specific schema in the db to a group role in PostgreSQL - postgresql

Using PostgreSQL 9.0, I have a group role called "staff" and would like to grant all (or certain) privileges to this role on tables in a particular schema. None of the following work
GRANT ALL ON SCHEMA foo TO staff;
GRANT ALL ON DATABASE mydb TO staff;
Members of "staff" are still unable to SELECT or UPDATE on the individual tables in the schema "foo" or (in the case of the second command) to any table in the database unless I grant all on that specific table.
What can I do make my and my users' lives easier?
Update: Figured it out with the help of a similar question on serverfault.com.
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA foo TO staff;

You found the shorthand to set privileges for all existing tables in the given schema. The manual clarifies:
(but note that ALL TABLES is considered to include views and foreign tables).
Bold emphasis mine. serial columns are implemented with nextval() on a sequence as column default and, quoting the manual:
For sequences, this privilege allows the use of the currval and nextval functions.
So if there are serial columns, you'll also want to grant USAGE (or ALL PRIVILEGES) on sequences
GRANT USAGE ON ALL SEQUENCES IN SCHEMA foo TO mygrp;
Note: IDENTITY columns in Postgres 10 or later use implicit sequences that don't require additional privileges. (Consider upgrading serial columns.)
What about new objects?
You'll also be interested in DEFAULT PRIVILEGES for users or schemas:
ALTER DEFAULT PRIVILEGES IN SCHEMA foo GRANT ALL PRIVILEGES ON TABLES TO staff;
ALTER DEFAULT PRIVILEGES IN SCHEMA foo GRANT USAGE ON SEQUENCES TO staff;
ALTER DEFAULT PRIVILEGES IN SCHEMA foo REVOKE ...;
This sets privileges for objects created in the future automatically - but not for pre-existing objects.
Default privileges are only applied to objects created by the targeted user (FOR ROLE my_creating_role). If that clause is omitted, it defaults to the current user executing ALTER DEFAULT PRIVILEGES. To be explicit:
ALTER DEFAULT PRIVILEGES FOR ROLE my_creating_role IN SCHEMA foo GRANT ...;
ALTER DEFAULT PRIVILEGES FOR ROLE my_creating_role IN SCHEMA foo REVOKE ...;
Note also that all versions of pgAdmin III have a subtle bug and display default privileges in the SQL pane, even if they do not apply to the current role. Be sure to adjust the FOR ROLE clause manually when copying the SQL script.

My answer is similar to this one on ServerFault.com.
To Be Conservative
If you want to be more conservative than granting "all privileges", you might want to try something more like these.
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO some_user_;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO some_user_;
The use of public there refers to the name of the default schema created for every new database/catalog. Replace with your own name if you created a schema.
Access to the Schema
To access a schema at all, for any action, the user must be granted "usage" rights. Before a user can select, insert, update, or delete, a user must first be granted "usage" to a schema.
You will not notice this requirement when first using Postgres. By default every database has a first schema named public. And every user by default has been automatically been granted "usage" rights to that particular schema. When adding additional schema, then you must explicitly grant usage rights.
GRANT USAGE ON SCHEMA some_schema_ TO some_user_ ;
Excerpt from the Postgres doc:
For schemas, allows access to objects contained in the specified schema (assuming that the objects' own privilege requirements are also met). Essentially this allows the grantee to "look up" objects within the schema. Without this permission, it is still possible to see the object names, e.g. by querying the system tables. Also, after revoking this permission, existing backends might have statements that have previously performed this lookup, so this is not a completely secure way to prevent object access.
For more discussion see the Question, What GRANT USAGE ON SCHEMA exactly do?. Pay special attention to the Answer by Postgres expert Craig Ringer.
Existing Objects Versus Future
These commands only affect existing objects. Tables and such you create in the future get default privileges until you re-execute those lines above. See the other answer by Erwin Brandstetter to change the defaults thereby affecting future objects.

Related

How to grant permissions to user for current schemas and schemas created in the future?

I have a Postgres database and a read-only user that I want to grant permissions to. I have two schemas currently but expect to make many more in the future. How do I grant select permissions to my read-only user so that they can read data from the tables that are currently created as well as tables that will be created in a new schema in the future?
I don't want to have to explicitly grant permissions for each new schema when they are created.
Use ALTER DEFAULT PRIVILEGES without specifying any schema:
The privileges can be set globally (i.e., for all objects created in the current database) […]
If IN SCHEMA is omitted, the global default privileges are altered.
So this should do it:
ALTER DEFAULT PRIVILEGES FOR whoever_will_create_the_tables
GRANT SELECT ON TABLES TO the_readonly_user;
ALTER DEFAULT PRIVILEGES FOR whoever_will_create_the_schemas
GRANT USAGE ON SCHEMAS TO the_readonly_user;
Granting the privilege on the tables that already are created needs a separate statement:
GRANT SELECT ON ALL TABLES IN SCHEMA schema_1, schema_2 TO the_readonly_user;

Grant privileges on all future tables, independently of their owner

I read the following question before: Grant privileges on future tables in PostgreSQL?.
But if I run the following query while logged in as rbourgeon (which is a superuser):
ALTER DEFAULT PRIVILEGES GRANT ALL ON TABLES IN SCHEMA myschema TO username;
I notice that the user username will have the privileges only on the future tables created by me, and not on all the future tables.
The official PostgreSQL documentation, on this issue, reads:
ALTER DEFAULT PRIVILEGES allows you to set the privileges that will be
applied to objects created in the future. (It does not affect
privileges assigned to already-existing objects.) Currently, only the
privileges for tables (including views), sequences, and functions can
be altered.
You can change default privileges only for objects that will be
created by yourself or by roles that you are a member of. The
privileges can be set globally (i.e., for all objects created in the
current database), or just for objects created in specified schemas.
Default privileges that are specified per-schema are added to whatever
the global default privileges are for the particular object type.
Is there a workaround? Because many users may create tables in this database.

Amazon Redshift Grants - New table can't be accessed even though user has grants to all tables in schema

I have a bit of a funny situation in Amazon Redshift where I have a user X who has grant select on all tables in schema public, but once a new table is created, this grant doesn't seem to apply to the new table. Is this normal behaviour? If yes, how does one deal with it such that the schema level grants are maintained. Thank you.
Executing the following command as super user (master):
alter default privileges
for user staging_user
in schema staging
grant select on tables
to reporting_user;
will allow reporting_user to select data from all future tables created by staging_user in schema staging.
In Redshift tables and views do not automatically inherit the permissions of their parent schema. Your newly created tables are only accessible to the user who created them, and the superuser.
In a recent patch to Redshift a new feature to grant default privileges was implemented that addresses this issue.
Alter Default Privileges
The following code snippet will grant select privileges only for all future tables in the sales schema to the sales_admin group. If you want this to apply to existing tables in a schema you will need to combine it with a second grant statement.
alter default privileges in schema sales grant select on tables to group sales_admin;
This is a normal behavior. Only the object owner/superuser have permission to use the object by default.
http://docs.aws.amazon.com/redshift/latest/dg/r_Privileges.html
You can add grant command to your create table statement and grant needed privileges for the user.
When we first spotted new tables not appearing in our reporting tool, I discovered a quick workaround is to re-execute the following SQL statement for the groups/users impacted:
ALTER DEFAULT PRIVILEGES IN SCHEMA <SCHEMANAME> GRANT SELECT ON TABLES TO GROUP <USER/GROUPNAME>;

DB2 Privileges for Create or Declare Global / temp table

Is it possible to grant privileges to allow developers to Create/Declare Temp table/variables but not allow Create Table.
Developers are asked to analyse data from different data sources and a temp table would help a lot.
Because of how the feature is supposed to be used, no special authorization is required:
Authorization
None are required, unless the LIKE clause is specified when additional
privileges might be required.
PUBLIC implicitly has the following privileges without GRANT authority
for declared temporary tables:
The CREATETAB privilege to define a declared temporary table in the database that is defined AS WORKFILE, which is the database for declared temporary tables.
The USE privilege to use the table spaces in the database that is defined as WORKFILE.
All table privileges on the table and authority to drop the table. (Table privileges for a declared temporary table cannot be granted or revoked.)
These implicit privileges are not recorded in the DB2® catalog and
cannot be revoked.
The exceptions for the LIKE clause basically amount to needing SELECT access to the table/columns, which you'd need anyways...
Since temporary tables require a special type of tablespace, user temporary, I think you should be able to accomplish this indirectly: issue GRANT USE OF TABLESPACE on the user temporary tablespace(s) while revoking that privilege on all regular tablespaces.

PostgreSQL: making a schema restricted/unchangable?

We like our production environment with a restricted/unchangable schema -- the development side can be owned by the developers and changed as they like -- and we like to vet changes as they are promoted.
I'm wondering if this may be a solution to making that happen:
postgres% create proddb with owner=postgres;
unixside% pg_restore --dbname=devdb [--schema-only] --no-owner proddb
/* grants to users on schema objects appear to remain intact */
/* here's the magic, I hope... */
postgres% revoke create on schema public from public;
postgres% grant usage on schema public to produser(s);
Some testing seems to show that a user in this new proddb can interact with tables normally (with appropriate grants) and cannot alter the schema (alter table, create table, drop table, etc). But I'm paranoid and very new to Postgres, so...
Q: Is this correct?
Q: Am I missing anything?
Thanks muchly.
Yes, that is correct. The only addition is that the owner of a table can always delete or modify it. So it may not work if you have existing tables in the schema.
Discovered a missing element: sequences.
The user was finding errors in his scripts; similar errors appeared in the logs:
ERROR: permission denied for sequence <sequence>
The production schema showed that although sequences were created, they were owned by postgres and no explicit grants were given to the users. As per the GRANT documentation:
Granting permission on a table does not automatically extend permissions to any sequences used by the table, including sequences tied to SERIAL columns. Permissions on sequence must be set separately.
Our fix (verbose for this demonstration) was to find all sequences:
unixside% pg_dump --schema-only proddb > proddb.schema
unixside% grep -i 'create sequence' proddb.schema
...and apply appropriate grants (select to prevent table scans, update to prevent the above errors):
postgres% grant select,update on <sequence> to produser(s);
So far, the user says it's working and errors to the log have stopped...
I forget what version PostgreSQL added the syntax, but one of the easiest ways to administer permissions in PostgreSQL is through the "GRANT foo, priv ON ALL something IN SCHEMA" syntax.
BEGIN;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA my_schema TO my_role;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA my_schema TO my_role;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA my_schema TO my_role;
COMMIT;
Very handy for making sure that permissions are always set correctly.
The EXECUTE for FUNCTIONS may seem spooky, but shouldn't be unless your functions were created with the SECURITY DEFINER attribute (and if you are using SECURITY DEFINER, you'd better be cautious since you're playing around with the PostgreSQL version of a "setuid" function). If you space out your TABLES across different SCHEMAS based on the expected permissions, then this becomes a pretty handy convention when used with the search_path variable.
ALTER ROLE my_role SET search_path = my_schema, auth_schema, public;
-- Avoid using the public schema (pretty please)
Where auth_schema has a collection of tables that my_role shouldn't have direct read or write privileges on. Assigning privs to GROUPS is also useful.
Here are some relevant docs:
http://developer.postgresql.org/pgdocs/postgres/sql-grant.html
Don't forget you can use "\h GRANT" in psql to easily figure out the syntax or remember what can be done on all objects in a schema (search for "IN SCHEMA").