-- Allow blacklist entries to be bypassed by callers who hold a specific permission bit. -- bypass_mask NULL means the rule blocks everyone unconditionally. ALTER TABLE blacklist ADD COLUMN bypass_mask TEXT; -- Existing user/permission rules: SUPER_ADMIN (bit 32) can bypass them so the -- admin UI can reach these tables via the generic /api/:table CRUD endpoint. UPDATE blacklist SET bypass_mask = '32' WHERE pattern IN ('/api/users/**', '/api/permissions/**'); -- Add rules for queries and blacklist tables, which also need admin-only CRUD access. INSERT INTO blacklist (pattern, method, reason, active, bypass_mask) VALUES ('/api/users', NULL, 'admin-only table', true, '32'), ('/api/permissions', NULL, 'admin-only table', true, '32'), ('/api/queries', NULL, 'admin-only table', true, '32'), ('/api/queries/**', NULL, 'admin-only table', true, '32'), ('/api/blacklist', NULL, 'admin-only table', true, '32'), ('/api/blacklist/**', NULL, 'admin-only table', true, '32'); -- Automatically update updated_at on queries mutations so the generic CRUD -- endpoint doesn't need to know about that column. CREATE OR REPLACE FUNCTION update_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER queries_updated_at BEFORE UPDATE ON queries FOR EACH ROW EXECUTE FUNCTION update_updated_at();