I created a seperate schema in Redshift for my changelog tables:
CREATE SCHEMA liquibase_non_prd;
ALTER DEFAULT PRIVILEGES IN SCHEMA liquibase_non_prd GRANT ALL ON TABLES TO GROUP readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA liquibase_non_prd GRANT ALL ON TABLES TO GROUP readwrite;
Liquibase creates my log tables but not in desired schema. Instead, I see them in public.
In my db.config file I do use liquibaseSchemaName parameter to no success.
cat <<eof > liquibase.properties
driver: com.amazon.redshift.jdbc42.Driver
url: jdbc:redshift://${bamboo_secret_deploy_host}:${bamboo_secret_deploy_port}/dbname?sslmode=verify-full
username: ${bamboo_secret_redshift_non_production_deploy_username}
password: ${bamboo_secret_redshift_non_production_deploy_password}
changeLogFile: src/main/resources/db/changelog/db.config-development.yml
liquibaseSchemaName: liquibase_non_prd
contexts: !norun
databaseChangeLogTableName: chg_lg_t
databaseChangeLogLockTableName: chg_lg_lck_t
clearCheckSums: TRUE
eof
mv liquibase.properties ${bamboo_result_artifactId}-${bamboo_result_version}/src/main/resources
Am I missing something?
UPDT
In my bamboo logs I found below entry:
build 05-Jul-2022 18:43:32 [INFO] 'liquibaseSchemaName' in properties file is not being used by this task.
Below queries ran in order fixed the issue:
--run these ddls before first Liquibase run in target database
CREATE SCHEMA IF NOT EXISTS liquibase_non_prd;
GRANT ALL ON SCHEMA liquibase_non_prd TO GROUP readonly;
GRANT ALL ON SCHEMA liquibase_non_prd TO GROUP readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA liquibase_non_prd GRANT ALL ON TABLES TO GROUP readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA liquibase_non_prd GRANT ALL ON TABLES TO GROUP readwrite;
--run these ddls after first Liquibase run in target database
GRANT ALL ON TABLE liquibase_non_prd.chg_lg_lck_t TO GROUP readonly;
GRANT ALL ON TABLE liquibase_non_prd.chg_lg_lck_t TO GROUP readwrite;
GRANT ALL ON TABLE liquibase_non_prd.chg_lg_t TO GROUP readonly;
GRANT ALL ON TABLE liquibase_non_prd.chg_lg_t TO GROUP readwrite;
Related
I'm trying to setup a database with a readwrite user jirauser and a readonly user controlling_ro. This is my script to set it up based on this Blog article. testuser is the master user.
PGPASSWORD=XXX psql \
--dbname=postgres \
--host=XXX.XXX.eu-central-1.rds.amazonaws.com \
--port=5432 \
--username=testuser \
<<EOF
-- Clean DB
DROP DATABASE jiradb;
DROP USER jirauser;
DROP USER controlling_ro;
DROP SCHEMA jiraschema;
DROP ROLE readonly;
DROP ROLE readwrite;
-- Create DB
CREATE DATABASE jiradb;
\connect jiradb;
CREATE SCHEMA jiraschema;
-- Revoke privileges from 'public' role
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON DATABASE jiradb FROM PUBLIC;
-- Read-only role
CREATE ROLE readonly;
GRANT CONNECT ON DATABASE jiradb TO readonly;
GRANT USAGE ON SCHEMA jiraschema TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA jiraschema TO readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA jiraschema GRANT SELECT ON TABLES TO readonly;
-- Read/write role
CREATE ROLE readwrite;
GRANT CONNECT ON DATABASE jiradb TO readwrite;
GRANT USAGE, CREATE ON SCHEMA jiraschema TO readwrite;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA jiraschema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA jiraschema GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO readwrite;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA jiraschema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA jiraschema GRANT USAGE ON SEQUENCES TO readwrite;
-- Users creation
CREATE USER controlling_ro WITH PASSWORD 'XXX';
CREATE USER jirauser WITH PASSWORD 'XXX';
-- Grant privileges to users
GRANT readonly TO controlling_ro;
GRANT readwrite TO jirauser;
EOF
After running this script I expect the roles and the users only to be in the jiradb database. However looking into the default database postgres with dbeaver they are also there. Does this mean they also have access to the postgres database?
That's just an artifact of your client tool.
In reality, PostgreSQL users don't belong to any database; they are shared by all databases. So no matter to which database you are connected when you create a user, it will equally exist for all databases.
You can use the CONNECT permission on the database object or (more typically) configure pg_hba.conf to determine which user can access which database.
According to https://www.postgresql.org/docs/current/sql-createrole.html:
CREATE ROLE adds a new role to a PostgreSQL database cluster. A role is an entity that can own database objects and have database privileges; a role can be considered a “user”, a “group”, or both depending on how it is used. Refer to Chapter 21 and Chapter 20 for information about managing users and authentication. You must have CREATEROLE privilege or be a database superuser to use this command.
Note that roles are defined at the database cluster level, and so are valid in all databases in the cluster.
So it's just your GUI misleading you.
I have a readonly user that I defined as the following:
CREATE ROLE readonly;
GRANT CONNECT ON DATABASE dbname TO readonly;
GRANT USAGE ON SCHEMA public TO readonly;
GRANT USAGE ON SCHEMA schema_name TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA schema_name TO readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA schema_name GRANT SELECT ON TABLES TO readonly;
I am currently running these commands as the postgres user who is the rds_superuser (I'm using AWS RDS). This works fine, and allows readonly role to read existing tables that postgres user creates, and also any new tables that postgres creates. However, when a new role creates a table, readonly cannot SELECT the table that the new role creates. For example, I also have a readwrite role, and tables created in that schema by readwrite cannot be SELECT by readonly.
How do you create a read-only user in PostgreSQL? suggests that by default ALTER DEFAULT PRIVILEGES ... only works by default on objects created by the user that issued the command.
How can I more generally just allow readonly user to have SELECT privileges on ANY table created in the schema regardless of who creates it.
You will need to change the default privileges for any potential creator, e.g. for your readwrite role, use the following
ALTER DEFAULT PRIVILEGES for role readwrite
IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
I have a postgresql (v10) database. I've created database tn_beta_db with schema tn_schema. I've created three users and executed the following, which is meant to grant all of them read and maybe modify access on all tables, current and future that tn_beta_migrator might create.
\c tn_beta_db
-- User tn_beta_reader --
ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema FOR ROLE tn_beta_reader GRANT SELECT ON TABLES TO tn_beta_reader;
GRANT CONNECT ON DATABASE tn_beta_db TO tn_beta_reader;
GRANT USAGE ON SCHEMA tn_schema TO tn_beta_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_reader;
-- User tn_beta_migrator --
ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema FOR ROLE tn_beta_migrator GRANT ALL ON TABLES TO tn_beta_migrator;
GRANT CONNECT ON DATABASE tn_beta_db TO tn_beta_migrator;
GRANT USAGE ON SCHEMA tn_schema TO tn_beta_migrator;
GRANT ALL ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_migrator;
GRANT CREATE ON SCHEMA tn_schema TO tn_beta_migrator;
-- User tn_beta_writer --
ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema FOR ROLE tn_beta_writer GRANT SELECT,INSERT,DELETE,UPDATE ON TABLES TO tn_beta_writer;
GRANT CONNECT ON DATABASE tn_beta_db TO tn_beta_writer;
GRANT USAGE ON SCHEMA tn_schema TO tn_beta_writer;
GRANT SELECT,INSERT,DELETE,UPDATE ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_writer;
If I now connect as tn_beta_migrator, I can create a table and do things with it.
create table tn_schema.foo(x int);
-- and then INSERT, SELECT, UPDATE, even DROP
But now if I connect as either of tn_beta_reader or tn_beta_writer, I can not use that table.
tn_beta_db=> select * from tn_schema.foo ;
ERROR: permission denied for relation foo
tn_beta_db=>
I would expect to be able to read/write/modify/delete as tn_beta_writer and to be able to read as tn_beta_reader.
If I rerun the grant script, above, this permits me to access foo, but a newly created table bar would then be inaccessible.
I'd thought that the alter default privileges commands would permit these roles, in the future, to access the tables created by tn_beta_migrator.
Any pointers on what I've misunderstood?
The role in the FOR ROLE clause in ALTER DEFAULT PRIVILEGES is not the role that will get the privileges, it is the role that creates the tables.
So your statements should start with
ALTER DEFAULT PRIVILEGES FOR ROLE tn_beta_migrator ...
I would like to set default ACL for all roles (i.e. without using PUBLIC) in PostgreSQL and want to avoid enumerating.
Is there an easy way to do that?
You can do this in the following way:
Grant SELECT privilege to everyone for all tables (and views) you subsequently create in schema myschema:
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES TO PUBLIC;
and allow role webuser to INSERT into them too:
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT INSERT ON TABLES TO webuser;
and to Undo the above:
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE SELECT ON TABLES FROM PUBLIC;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE INSERT ON TABLES FROM webuser;
Source
That's it :)
Is it possible to alter default priviledges on PostgreSQL role, such that role has SELECT on any table in any schema (existing or created in future)
I have 3 roles (app_r is member of app_rw which is member of app_rwc)
and I am trying this:
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT USAGE ON SCHEMAS TO app_r;
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT SELECT ON TABLES TO app_r;
but it does not work.
SELECT has_table_privilege('app_r', 'some_schema.some_table', 'SELECT')
-- false
Is there a way to do this in PG or do I have to use IN SCHEMA and repeat for every schema? (ughhh)
ALTER DEFAULT PRIVILEGES FOR ROLE app_r IN SCHEMA some_schema GRANT SELECT ON TABLES TO app_r;
P.S.
I did try running ALTER DEFAULT before (and after also, just to test) creating schemas and tables...
P.P.S
My role setup is inspired by this answer and I saw in this answer that is not necessary having to explicitly specify schemas
UPDATE #1 - Here is exact role setup I am using:
CREATE ROLE app_rwc INHERIT CREATEDB CREATEROLE;
CREATE ROLE app_rw INHERIT;
CREATE ROLE app_r INHERIT;
GRANT app_r TO app_rw;
GRANT app_rw TO app_rwc;
-- these must be performed *before* any objects are created
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT USAGE ON SCHEMAS TO app_r;
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT SELECT ON TABLES TO app_r;
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT INSERT, UPDATE, DELETE ON TABLES TO app_rw;
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc REVOKE TRUNCATE ON TABLES TO app_rw;
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT SELECT, UPDATE ON SEQUENCES TO app_rw;
Is it possible to alter default priviledges on PostgreSQL role, such
that role has SELECT on any table in any schema (existing or created
in future)
As of version 9.6, no.