Skip to content
This repository has been archived by the owner on Apr 2, 2024. It is now read-only.

Commit

Permalink
Lockdown execute_everywhere
Browse files Browse the repository at this point in the history
This requires finer-grained permissions on tables in the catalog
schema so get rid of ALL TABLES assignments as well.
  • Loading branch information
cevian committed Apr 23, 2021
1 parent 0cf42bb commit 5f2908b
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 37 deletions.
28 changes: 14 additions & 14 deletions pkg/migrations/migration_files_generated.go

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions pkg/migrations/sql/idempotent/base.sql
Expand Up @@ -2093,7 +2093,7 @@ SET search_path = pg_temp;
REVOKE ALL ON FUNCTION SCHEMA_CATALOG.delay_compression_job(name, timestamptz) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION SCHEMA_CATALOG.delay_compression_job(name, timestamptz) TO prom_writer;

CALL execute_everywhere('SCHEMA_CATALOG.do_decompress_chunks_after', $ee$
CALL SCHEMA_CATALOG.execute_everywhere('SCHEMA_CATALOG.do_decompress_chunks_after', $ee$
--Decompression should take place in a procedure because we don't want locks held across
--decompress_chunk calls since that function takes some heavier locks at the end.
--Thus, transactional parameter should usually be false
Expand Down Expand Up @@ -2169,7 +2169,7 @@ END
$proc$ LANGUAGE PLPGSQL;
GRANT EXECUTE ON PROCEDURE SCHEMA_CATALOG.decompress_chunks_after(name, TIMESTAMPTZ, boolean) TO prom_writer;

CALL execute_everywhere('SCHEMA_CATALOG.compress_old_chunks', $ee$
CALL SCHEMA_CATALOG.execute_everywhere('SCHEMA_CATALOG.compress_old_chunks', $ee$
CREATE OR REPLACE PROCEDURE SCHEMA_CATALOG.compress_old_chunks(metric_table TEXT, compress_before TIMESTAMPTZ)
AS $$
DECLARE
Expand Down
11 changes: 9 additions & 2 deletions pkg/migrations/sql/preinstall/000-utils.sql
Expand Up @@ -8,9 +8,12 @@
transactional BOOLEAN,
command TEXT
);
--only the prom owner has any permissions.
GRANT ALL ON TABLE SCHEMA_CATALOG.remote_commands to CURRENT_USER;
GRANT ALL ON SEQUENCE SCHEMA_CATALOG.remote_commands_seq_seq to CURRENT_USER;


CREATE OR REPLACE PROCEDURE execute_everywhere(command_key text, command TEXT, transactional BOOLEAN = true)
CREATE OR REPLACE PROCEDURE SCHEMA_CATALOG.execute_everywhere(command_key text, command TEXT, transactional BOOLEAN = true)
AS $func$
BEGIN
IF command_key IS NOT NULL THEN
Expand All @@ -31,8 +34,10 @@ BEGIN
END;
END
$func$ LANGUAGE PLPGSQL;
--redundant given schema settings but extra caution for this function
REVOKE ALL ON PROCEDURE SCHEMA_CATALOG.execute_everywhere(text, text, boolean) FROM PUBLIC;

CREATE OR REPLACE PROCEDURE update_execute_everywhere_entry(command_key text, command TEXT, transactional BOOLEAN = true)
CREATE OR REPLACE PROCEDURE SCHEMA_CATALOG.update_execute_everywhere_entry(command_key text, command TEXT, transactional BOOLEAN = true)
AS $func$
BEGIN
UPDATE SCHEMA_CATALOG.remote_commands
Expand All @@ -42,3 +47,5 @@ BEGIN
WHERE key = command_key;
END
$func$ LANGUAGE PLPGSQL;
--redundant given schema settings but extra caution for this function
REVOKE ALL ON PROCEDURE SCHEMA_CATALOG.update_execute_everywhere_entry(text, text, boolean) FROM PUBLIC;
6 changes: 3 additions & 3 deletions pkg/migrations/sql/preinstall/001-users.sql
@@ -1,4 +1,4 @@
CALL execute_everywhere('create_prom_reader', $ee$
CALL SCHEMA_CATALOG.execute_everywhere('create_prom_reader', $ee$
DO $$
BEGIN
CREATE ROLE prom_reader;
Expand All @@ -9,7 +9,7 @@ CALL execute_everywhere('create_prom_reader', $ee$
$$;
$ee$);

CALL execute_everywhere('create_prom_writer', $ee$
CALL SCHEMA_CATALOG.execute_everywhere('create_prom_writer', $ee$
DO $$
BEGIN
CREATE ROLE prom_writer;
Expand All @@ -20,6 +20,6 @@ CALL execute_everywhere('create_prom_writer', $ee$
$$;
$ee$);

CALL execute_everywhere('grant_prom_reader_prom_writer',$ee$
CALL SCHEMA_CATALOG.execute_everywhere('grant_prom_reader_prom_writer',$ee$
GRANT prom_reader TO prom_writer;
$ee$);
2 changes: 1 addition & 1 deletion pkg/migrations/sql/preinstall/002-schemas.sql
@@ -1,4 +1,4 @@
CALL execute_everywhere('create_schemas', $ee$ DO $$ BEGIN
CALL SCHEMA_CATALOG.execute_everywhere('create_schemas', $ee$ DO $$ BEGIN
CREATE SCHEMA IF NOT EXISTS SCHEMA_CATALOG; -- catalog tables + internal functions
GRANT USAGE ON SCHEMA SCHEMA_CATALOG TO prom_reader;

Expand Down
28 changes: 22 additions & 6 deletions pkg/migrations/sql/preinstall/003-tables.sql
Expand Up @@ -9,6 +9,8 @@ CREATE TABLE public.prom_installation_info (
key TEXT PRIMARY KEY,
value TEXT
);
GRANT SELECT ON TABLE public.prom_installation_info TO PUBLIC;
--all modifications can only be done by owner

INSERT INTO public.prom_installation_info(key, value) VALUES
('catalog schema', 'SCHEMA_CATALOG'),
Expand All @@ -26,13 +28,17 @@ CREATE TABLE SCHEMA_CATALOG.series (
labels SCHEMA_PROM.label_array NOT NULL, --labels are globally unique because of how partitions are defined
delete_epoch bigint NULL DEFAULT NULL -- epoch after which this row can be deleted
) PARTITION BY LIST(metric_id);
GRANT SELECT ON TABLE SCHEMA_CATALOG.series TO prom_reader;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE SCHEMA_CATALOG.series TO prom_writer;

CREATE INDEX series_labels_id ON SCHEMA_CATALOG.series USING GIN (labels);

CREATE INDEX series_labels_id ON SCHEMA_CATALOG.series USING GIN (labels);
CREATE INDEX series_deleted
ON SCHEMA_CATALOG.series(delete_epoch, id)
WHERE delete_epoch IS NOT NULL;

CREATE SEQUENCE SCHEMA_CATALOG.series_id;
GRANT USAGE ON SEQUENCE SCHEMA_CATALOG.series_id TO prom_writer;


CREATE TABLE SCHEMA_CATALOG.label (
Expand All @@ -42,6 +48,9 @@ CREATE TABLE SCHEMA_CATALOG.label (
PRIMARY KEY (id) INCLUDE (key, value),
UNIQUE (key, value) INCLUDE (id)
);
GRANT SELECT ON TABLE SCHEMA_CATALOG.label TO prom_reader;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE SCHEMA_CATALOG.label TO prom_writer;
GRANT USAGE ON SEQUENCE SCHEMA_CATALOG.label_id_seq TO prom_writer;

CREATE TABLE SCHEMA_CATALOG.ids_epoch(
current_epoch BIGINT NOT NULL,
Expand All @@ -50,6 +59,8 @@ CREATE TABLE SCHEMA_CATALOG.ids_epoch(
is_unique BOOLEAN NOT NULL DEFAULT true CHECK (is_unique = true),
UNIQUE (is_unique)
);
GRANT SELECT ON TABLE SCHEMA_CATALOG.ids_epoch TO prom_reader;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE SCHEMA_CATALOG.ids_epoch TO prom_writer;

-- uses an arbitrary start time so pristine and migrated DBs have the same values
INSERT INTO SCHEMA_CATALOG.ids_epoch VALUES (0, '1970-01-01 00:00:00 UTC', true);
Expand All @@ -66,13 +77,18 @@ CREATE TABLE SCHEMA_CATALOG.label_key(
PRIMARY KEY (id),
UNIQUE(key)
);
GRANT SELECT ON TABLE SCHEMA_CATALOG.label_key TO prom_reader;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE SCHEMA_CATALOG.label_key TO prom_writer;
GRANT USAGE ON SEQUENCE SCHEMA_CATALOG.label_key_id_seq TO prom_writer;

CREATE TABLE SCHEMA_CATALOG.label_key_position (
metric_name text, --references metric.metric_name NOT metric.id for performance reasons
key TEXT, --NOT label_key.id for performance reasons.
pos int,
UNIQUE (metric_name, key) INCLUDE (pos)
);
GRANT SELECT ON TABLE SCHEMA_CATALOG.label_key_position TO prom_reader;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE SCHEMA_CATALOG.label_key_position TO prom_writer;

CREATE TABLE SCHEMA_CATALOG.metric (
id SERIAL PRIMARY KEY,
Expand All @@ -86,17 +102,17 @@ CREATE TABLE SCHEMA_CATALOG.metric (
UNIQUE (metric_name) INCLUDE (table_name),
UNIQUE(table_name)
);
GRANT SELECT ON TABLE SCHEMA_CATALOG.metric TO prom_reader;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE SCHEMA_CATALOG.metric TO prom_writer;
GRANT USAGE ON SEQUENCE SCHEMA_CATALOG.metric_id_seq TO prom_writer;

CREATE TABLE SCHEMA_CATALOG.default (
key TEXT PRIMARY KEY,
value TEXT
);
GRANT SELECT ON TABLE SCHEMA_CATALOG.default TO prom_reader;

INSERT INTO SCHEMA_CATALOG.default(key,value) VALUES
('chunk_interval', (INTERVAL '8 hours')::text),
('retention_period', (90 * INTERVAL '1 day')::text),
('metric_compression', (exists(select * from pg_proc where proname = 'compress_chunk')::text));

GRANT USAGE ON ALL SEQUENCES IN SCHEMA SCHEMA_CATALOG TO prom_writer;
GRANT SELECT ON ALL TABLES IN SCHEMA SCHEMA_CATALOG TO prom_reader;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA SCHEMA_CATALOG TO prom_writer;
('metric_compression', (exists(select * from pg_proc where proname = 'compress_chunk')::text));
10 changes: 5 additions & 5 deletions pkg/migrations/sql/preinstall/006-tables_ha.sql
Expand Up @@ -5,6 +5,8 @@ CREATE TABLE SCHEMA_CATALOG.ha_leases
lease_start TIMESTAMPTZ,
lease_until TIMESTAMPTZ
);
GRANT SELECT ON TABLE SCHEMA_CATALOG.ha_leases TO prom_reader;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE SCHEMA_CATALOG.ha_leases TO prom_writer;

CREATE TABLE SCHEMA_CATALOG.ha_leases_logs
(
Expand All @@ -14,6 +16,8 @@ CREATE TABLE SCHEMA_CATALOG.ha_leases_logs
lease_until TIMESTAMPTZ, -- exclusive
PRIMARY KEY (cluster_name, leader_name, lease_start)
);
GRANT SELECT ON TABLE SCHEMA_CATALOG.ha_leases_logs TO prom_reader;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE SCHEMA_CATALOG.ha_leases_logs TO prom_writer;


-- STUB for function that trigger to automatically keep the log calls - real implementation in ha.sql
Expand All @@ -38,8 +42,4 @@ EXECUTE PROCEDURE SCHEMA_CATALOG.ha_leases_audit_fn();
INSERT INTO SCHEMA_CATALOG.default(key, value)
VALUES ('ha_lease_timeout', '1m'),
('ha_lease_refresh', '10s')
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;

GRANT USAGE ON ALL SEQUENCES IN SCHEMA SCHEMA_CATALOG TO prom_writer;
GRANT SELECT ON ALL TABLES IN SCHEMA SCHEMA_CATALOG TO prom_reader;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA SCHEMA_CATALOG TO prom_writer
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
17 changes: 13 additions & 4 deletions pkg/migrations/sql/versions/dev/0.3.1-dev/1-fix_permissions.sql
@@ -1,4 +1,6 @@
CREATE OR REPLACE PROCEDURE execute_everywhere(command_key text, command TEXT, transactional BOOLEAN = true)
DROP PROCEDURE execute_everywhere(text, TEXT, BOOLEAN);

CREATE OR REPLACE PROCEDURE SCHEMA_CATALOG.execute_everywhere(command_key text, command TEXT, transactional BOOLEAN = true)
AS $func$
BEGIN
IF command_key IS NOT NULL THEN
Expand All @@ -19,8 +21,9 @@ BEGIN
END;
END
$func$ LANGUAGE PLPGSQL;
REVOKE ALL ON PROCEDURE SCHEMA_CATALOG.execute_everywhere(text, text, boolean) FROM PUBLIC;

CREATE OR REPLACE PROCEDURE update_execute_everywhere_entry(command_key text, command TEXT, transactional BOOLEAN = true)
CREATE OR REPLACE PROCEDURE SCHEMA_CATALOG.update_execute_everywhere_entry(command_key text, command TEXT, transactional BOOLEAN = true)
AS $func$
BEGIN
UPDATE SCHEMA_CATALOG.remote_commands
Expand All @@ -30,9 +33,10 @@ BEGIN
WHERE key = command_key;
END
$func$ LANGUAGE PLPGSQL;
REVOKE ALL ON PROCEDURE SCHEMA_CATALOG.update_execute_everywhere_entry(text, text, boolean) FROM PUBLIC;


CALL execute_everywhere(null::text, command =>
CALL SCHEMA_CATALOG.execute_everywhere(null::text, command =>
$ee$ DO $$ BEGIN
REVOKE USAGE ON SCHEMA SCHEMA_CATALOG FROM prom_writer;
REVOKE USAGE ON SCHEMA SCHEMA_DATA FROM prom_writer;
Expand All @@ -51,9 +55,14 @@ $ee$ DO $$ BEGIN
ALTER DEFAULT PRIVILEGES IN SCHEMA SCHEMA_SERIES REVOKE SELECT ON TABLES FROM prom_reader;

GRANT USAGE ON ALL SEQUENCES IN SCHEMA SCHEMA_CATALOG TO prom_writer;
GRANT SELECT ON TABLE public.prom_installation_info TO PUBLIC;
REVOKE SELECT, INSERT, UPDATE, DELETE ON TABLE SCHEMA_CATALOG.default FROM prom_writer;
REVOKE SELECT ON TABLE SCHEMA_CATALOG.remote_commands FROM prom_reader;
REVOKE SELECT, INSERT, UPDATE, DELETE ON TABLE SCHEMA_CATALOG.remote_commands FROM prom_writer;
REVOKE USAGE ON SEQUENCE SCHEMA_CATALOG.remote_commands_seq_seq FROM prom_writer;
END $$ $ee$);

CALL update_execute_everywhere_entry('create_schemas', $ee$ DO $$ BEGIN
CALL SCHEMA_CATALOG.update_execute_everywhere_entry('create_schemas', $ee$ DO $$ BEGIN
CREATE SCHEMA IF NOT EXISTS SCHEMA_CATALOG; -- catalog tables + internal functions
GRANT USAGE ON SCHEMA SCHEMA_CATALOG TO prom_reader;

Expand Down

0 comments on commit 5f2908b

Please sign in to comment.