Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions services/postgres/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Postgres configuration

Read and follow instructons in `./scripts/init.sql` script. This needs to be executed once in every postgres database we run (both self-hosted and RDS)

Create role and users scripts need to be run on demand (e.g. in case we need a readonly user). Generate scripts using repo config values, read and follow instructions inside. This needs to be executed once.
3 changes: 2 additions & 1 deletion services/postgres/scripts/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*
!.gitignore
!*.template.*
!*.template
!init.sql
32 changes: 32 additions & 0 deletions services/postgres/scripts/create-readonly-role.sql.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
Create read-only role for ${POSTGRES_DB} database.

This role can be used to give read-only access to the ${POSTGRES_DB} database
to users.

Permission grants inspired from: https://stackoverflow.com/questions/760210/how-do-you-create-a-read-only-user-in-postgresql/762649#762649
IMPORTANT: must be executed while connected to the ${POSTGRES_DB} database
as it refers to public schema in that database.
*/

CREATE ROLE ${POSTGRES_DB}_readonly NOLOGIN;

GRANT CONNECT ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_DB}_readonly;

-- https://stackoverflow.com/questions/17338621/what-does-grant-usage-on-schema-do-exactly
GRANT USAGE ON SCHEMA public TO ${POSTGRES_DB}_readonly;

-- Grant permissions for (existing) tables, sequences, functions
GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${POSTGRES_DB}_readonly;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO ${POSTGRES_DB}_readonly;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO ${POSTGRES_DB}_readonly;

-- Grant permissions for (future) tables, sequences, functions
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO ${POSTGRES_DB}_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON SEQUENCES TO ${POSTGRES_DB}_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT EXECUTE ON FUNCTIONS TO ${POSTGRES_DB}_readonly;

SELECT * FROM pg_roles WHERE rolname NOT LIKE 'pg_%';
22 changes: 3 additions & 19 deletions services/postgres/scripts/create-readonly-user.sql.template
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
-- SQL script to create a read-only user and grant privileges


--Create the read-only user with a password
CREATE USER ${POSTGRES_READONLY_USER} WITH PASSWORD '${POSTGRES_READONLY_PASSWORD}';

--Grant CONNECT privilege to the database (e.g., 'foo' is the database name)
GRANT CONNECT ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_READONLY_USER};

--Grant USAGE privilege on the **public** schema
GRANT USAGE ON SCHEMA public TO ${POSTGRES_READONLY_USER};

--Grant SELECT privilege on all existing tables and sequencies in the **public** schema
GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${POSTGRES_READONLY_USER};
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO ${POSTGRES_READONLY_USER};

--Ensure that future tables created in the public schema and sequencies will have SELECT privilege for the read-only user
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ${POSTGRES_READONLY_USER};
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON SEQUENCES TO ${POSTGRES_READONLY_USER};
-- Grant read-only role (privilages) to the user
GRANT ${POSTGRES_DB}_readonly TO ${POSTGRES_READONLY_USER};

-- Listing all users
SELECT * FROM pg_roles;
SELECT * FROM pg_roles WHERE rolname NOT LIKE 'pg_%';
13 changes: 13 additions & 0 deletions services/postgres/scripts/init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
Do not allow users to create new objects in the public schema

Must be executed against every created database (e.g. for simcore, for metabase, ...)
(as long as we use Postgres 14 or earlier)

Sources:
* https://wiki.postgresql.org/wiki/A_Guide_to_CVE-2018-1058:_Protect_Your_Search_Path
* https://www.reddit.com/r/PostgreSQL/comments/1hvxw0s/understanding_the_public_schema_in_postgresql/
*/

-- As a superuser, run the following command in all of your databases
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
17 changes: 17 additions & 0 deletions services/postgres/scripts/remove-readonly-role.sql.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- Make sure this role is not used by any user or else this script will fail

REVOKE CONNECT ON DATABASE ${POSTGRES_DB} FROM ${POSTGRES_DB}_readonly;

REVOKE ALL PRIVILEGES ON SCHEMA public FROM ${POSTGRES_DB}_readonly;

REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM ${POSTGRES_DB}_readonly;
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM ${POSTGRES_DB}_readonly;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM ${POSTGRES_DB}_readonly;

ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM ${POSTGRES_DB}_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON SEQUENCES FROM ${POSTGRES_DB}_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM ${POSTGRES_DB}_readonly;

DROP ROLE IF EXISTS ${POSTGRES_DB}_readonly;

SELECT * FROM pg_roles WHERE rolname NOT LIKE 'pg_%';
18 changes: 4 additions & 14 deletions services/postgres/scripts/remove-readonly-user.sql.template
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
-- Revoke all privileges the user has on the public schema
REVOKE ALL PRIVILEGES ON SCHEMA public FROM ${POSTGRES_READONLY_USER};
-- Revoke readonly role from user
REVOKE ${POSTGRES_DB}_readonly FROM ${POSTGRES_READONLY_USER};

-- Revoke all privileges the user has on tables and sequences in the public schema
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM ${POSTGRES_READONLY_USER};
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM ${POSTGRES_READONLY_USER};
DROP USER IF EXISTS ${POSTGRES_READONLY_USER};

-- Revoke any future privileges set via ALTER DEFAULT PRIVILEGES
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM ${POSTGRES_READONLY_USER};
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON SEQUENCES FROM ${POSTGRES_READONLY_USER};

-- Drop the user
DROP USER ${POSTGRES_READONLY_USER};

-- Listing all users
SELECT * FROM pg_roles;
SELECT * FROM pg_roles WHERE rolname NOT LIKE 'pg_%';
Loading