Files
windmill/backend/migrations/20260413160755_add_http_trigger_insert_delete_policies.up.sql
hugocasaandClaude Opus 4.6 9fb78164b4 feat: allow non-admins to create and edit HTTP triggers (#8810)
* feat: allow non-admin users to create HTTP triggers with forced workspaced routes

Non-admin users can now create and fully edit HTTP triggers, but are forced
to use workspaced routes (workspace-prefixed URLs). Instance-wide routes
remain admin-only to prevent cross-workspace URL conflicts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add missing RLS INSERT/DELETE policies for http_trigger table

Non-admin users were blocked by row-level security when creating HTTP triggers.
Added INSERT, DELETE, see_own, and see_member policies matching other trigger tables.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: allow user paths for HTTP triggers

Remove the hideUser restriction on the Path component so HTTP triggers
can be created under user paths (u/username/...) in addition to folder paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: remove added note from instance settings description

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: allow non-admins to edit non-workspaced routes without changing route config

Non-admins can now open and edit existing non-workspaced HTTP triggers
(created by admins) as long as they don't modify route_path, http_method,
or workspaced_route. The workspaced prefix is only forced on new triggers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: allow non-admins to change route_path on workspaced routes

The prevent_route_path_change DB trigger blocked all route_path changes
for windmill_user, even on workspaced routes. Now only instance-wide
(non-workspaced) routes are protected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add explicit GRANT and force workspaced routes in OpenAPI generator

- Add explicit GRANT INSERT, DELETE on http_trigger to windmill_user
  for safety on customer instances
- Force workspaced_route: true for non-admins in OpenAPI route generator

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 18:43:49 +00:00

54 lines
3.1 KiB
PL/PgSQL

-- Add missing INSERT and DELETE RLS policies for http_trigger table.
-- These are needed now that non-admin users can create HTTP triggers (with forced workspaced routes).
-- All other trigger tables already have these policies.
-- Ensure windmill_user has INSERT and DELETE privileges (original migration only granted SELECT, UPDATE).
-- Note: 20250205131523_grant_all_in_current_schema also grants ALL, but we add explicit grants for safety.
GRANT INSERT, DELETE ON http_trigger TO windmill_user;
-- Folder-based policies
CREATE POLICY see_folder_extra_perms_user_insert ON http_trigger FOR INSERT TO windmill_user
WITH CHECK (SPLIT_PART(http_trigger.path, '/', 1) = 'f' AND SPLIT_PART(http_trigger.path, '/', 2) = any(regexp_split_to_array(current_setting('session.folders_write'), ',')::text[]));
CREATE POLICY see_folder_extra_perms_user_delete ON http_trigger FOR DELETE TO windmill_user
USING (SPLIT_PART(http_trigger.path, '/', 1) = 'f' AND SPLIT_PART(http_trigger.path, '/', 2) = any(regexp_split_to_array(current_setting('session.folders_write'), ',')::text[]));
-- User extra_perms policies
CREATE POLICY see_extra_perms_user_insert ON http_trigger FOR INSERT TO windmill_user
WITH CHECK ((extra_perms ->> CONCAT('u/', current_setting('session.user')))::boolean);
CREATE POLICY see_extra_perms_user_delete ON http_trigger FOR DELETE TO windmill_user
USING ((extra_perms ->> CONCAT('u/', current_setting('session.user')))::boolean);
-- Group extra_perms policies
CREATE POLICY see_extra_perms_groups_insert ON http_trigger FOR INSERT TO windmill_user
WITH CHECK (exists(
SELECT key, value FROM jsonb_each_text(extra_perms)
WHERE SPLIT_PART(key, '/', 1) = 'g' AND key = ANY(regexp_split_to_array(current_setting('session.pgroups'), ',')::text[])
AND value::boolean));
CREATE POLICY see_extra_perms_groups_delete ON http_trigger FOR DELETE TO windmill_user
USING (exists(
SELECT key, value FROM jsonb_each_text(extra_perms)
WHERE SPLIT_PART(key, '/', 1) = 'g' AND key = ANY(regexp_split_to_array(current_setting('session.pgroups'), ',')::text[])
AND value::boolean));
-- Owner and member policies (other trigger tables have these, http_trigger was missing them)
CREATE POLICY see_own ON http_trigger FOR ALL TO windmill_user
USING (SPLIT_PART(http_trigger.path, '/', 1) = 'u' AND SPLIT_PART(http_trigger.path, '/', 2) = current_setting('session.user'));
CREATE POLICY see_member ON http_trigger FOR ALL TO windmill_user
USING (SPLIT_PART(http_trigger.path, '/', 1) = 'g' AND SPLIT_PART(http_trigger.path, '/', 2) = any(regexp_split_to_array(current_setting('session.groups'), ',')::text[]));
-- Update prevent_route_path_change to allow non-admins to change route_path on workspaced routes.
-- Previously all route_path changes were blocked for windmill_user; now only instance-wide routes are protected.
CREATE OR REPLACE FUNCTION prevent_route_path_change()
RETURNS TRIGGER AS $$
BEGIN
IF CURRENT_USER = 'windmill_user' AND NEW.route_path <> OLD.route_path AND NOT COALESCE(NEW.workspaced_route, false) THEN
RAISE EXCEPTION 'Modification of route_path is only allowed by admins for non-workspaced routes';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;