Skip to content

Commit 606cd8a

Browse files
YuweiXiaoclaude
andauthored
fix: add missing REVOKE on config-write functions (#64)
## Summary - `set_config()` and `set_group_config()` were missing `REVOKE ALL ON FUNCTION ... FROM PUBLIC`, allowing any database user to modify global and per-group pipeline configuration - All 12 other management functions already had this protection — these two were the only gap - Added ACL regression test coverage for both config-write (denied) and config-read (allowed) functions ## Test plan - [x] `make check-regression TEST=acl` — verifies `set_config` and `set_group_config` are denied for non-superusers, and `get_config`/`get_group_config` remain accessible - [x] Full regression suite (42/42 tests pass) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 43eadd5 commit 606cd8a

3 files changed

Lines changed: 36 additions & 0 deletions

File tree

duckpipe-pg/src/api.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,6 +2611,7 @@ CREATE FUNCTION duckpipe.set_config(
26112611
) RETURNS void
26122612
AS 'MODULE_PATHNAME', '@FUNCTION_NAME@'
26132613
LANGUAGE C STRICT;
2614+
REVOKE ALL ON FUNCTION duckpipe.set_config(TEXT, TEXT) FROM PUBLIC;
26142615
")]
26152616
fn set_config(key: &str, value: &str) {
26162617
// Validate key and value
@@ -2691,6 +2692,7 @@ CREATE FUNCTION duckpipe.set_group_config(
26912692
) RETURNS void
26922693
AS 'MODULE_PATHNAME', '@FUNCTION_NAME@'
26932694
LANGUAGE C STRICT;
2695+
REVOKE ALL ON FUNCTION duckpipe.set_group_config(TEXT, TEXT, TEXT) FROM PUBLIC;
26942696
")]
26952697
fn set_group_config(group_name: &str, key: &str, value: &str) {
26962698
// Validate key and value

test/regression/expected/acl.out

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,28 @@ SELECT has_table_privilege('acl_owner', 'public.acl_source_ducklake', 'DELETE')
5151
SET ROLE acl_owner;
5252
SELECT duckpipe.add_table('public.acl_source'); -- should fail: permission denied
5353
ERROR: permission denied for function add_table
54+
RESET ROLE;
55+
-- Verify config-write functions are NOT callable by non-superusers
56+
SET ROLE acl_owner;
57+
SELECT duckpipe.set_config('duckdb_threads', '2'); -- should fail: permission denied
58+
ERROR: permission denied for function set_config
59+
SELECT duckpipe.set_group_config('default', 'duckdb_threads', '2'); -- should fail: permission denied
60+
ERROR: permission denied for function set_group_config
61+
RESET ROLE;
62+
-- Verify config-read functions ARE callable by non-superusers
63+
SET ROLE acl_owner;
64+
SELECT duckpipe.get_config('duckdb_threads') IS NOT NULL OR TRUE AS can_call_get_config;
65+
can_call_get_config
66+
---------------------
67+
t
68+
(1 row)
69+
70+
SELECT duckpipe.get_group_config('default', 'duckdb_threads') IS NOT NULL OR TRUE AS can_call_get_group_config;
71+
can_call_get_group_config
72+
---------------------------
73+
t
74+
(1 row)
75+
5476
RESET ROLE;
5577
-- Verify monitoring functions ARE callable by non-superusers (schema USAGE granted to PUBLIC)
5678
SET ROLE acl_owner;

test/regression/sql/acl.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,18 @@ SET ROLE acl_owner;
2929
SELECT duckpipe.add_table('public.acl_source'); -- should fail: permission denied
3030
RESET ROLE;
3131

32+
-- Verify config-write functions are NOT callable by non-superusers
33+
SET ROLE acl_owner;
34+
SELECT duckpipe.set_config('duckdb_threads', '2'); -- should fail: permission denied
35+
SELECT duckpipe.set_group_config('default', 'duckdb_threads', '2'); -- should fail: permission denied
36+
RESET ROLE;
37+
38+
-- Verify config-read functions ARE callable by non-superusers
39+
SET ROLE acl_owner;
40+
SELECT duckpipe.get_config('duckdb_threads') IS NOT NULL OR TRUE AS can_call_get_config;
41+
SELECT duckpipe.get_group_config('default', 'duckdb_threads') IS NOT NULL OR TRUE AS can_call_get_group_config;
42+
RESET ROLE;
43+
3244
-- Verify monitoring functions ARE callable by non-superusers (schema USAGE granted to PUBLIC)
3345
SET ROLE acl_owner;
3446
SELECT count(*) >= 0 AS can_call_groups FROM duckpipe.groups();

0 commit comments

Comments
 (0)