TeamVis Self-Host-Bundle v0.59.1
This commit is contained in:
1 parent
72a1260546
commit
73653b5e2d
4 files changed
+121
-7
No files matched your search
@@ -0,0 +1,114 @@
|
||||
-- ====================================================================
|
||||
-- 0073_anon_rechte_minimal — anon nur noch dort, wo die Karte liest
|
||||
-- ====================================================================
|
||||
-- Sicherheitsplan M22 (24.10.2026). Supabase vergibt über seine
|
||||
-- Default-Privileges jeder neuen Tabelle volle Rechte an anon (inkl.
|
||||
-- TRUNCATE, das RLS nicht erfasst). RLS hat das bisher abgefangen; jetzt
|
||||
-- werden die Rechte selbst abgebaut. Öffentlich gelesen werden nur
|
||||
-- employees, persons und site_settings — dort gelten weiter die
|
||||
-- Spalten-Grants aus 0014/0045 ff. (ohne Geheimnis-Spalten).
|
||||
--
|
||||
-- Bewusst KEIN "revoke ... on all tables in schema public" und KEIN
|
||||
-- "alter default privileges": Auf gemeinsam genutzten Datenbanken (etwa
|
||||
-- supabase.stwhas.de) liegen fremde Tabellen derselben Eigentümerrolle im
|
||||
-- Schema public; deren Rechte dürfen sich nicht ändern. Deshalb eine
|
||||
-- ausdrückliche Liste der TeamVis-Tabellen. Neue Tabellen nehmen anon die
|
||||
-- Rechte in ihrer eigenen Migration (siehe 0060, 0072 und CLAUDE.md).
|
||||
--
|
||||
-- Ebenfalls entfernt: die Policies admin_write und public_read auf employees (ALL für
|
||||
-- authenticated, true). Sie stammt aus keiner TeamVis-Migration — TeamVis
|
||||
-- nutzt keine Supabase-Auth —, lag aber auf einer Bestandsinstanz und hätte
|
||||
-- jedem Inhaber eines authenticated-JWT Schreibzugriff gegeben.
|
||||
|
||||
do $$
|
||||
declare t text;
|
||||
begin
|
||||
foreach t in array array[
|
||||
'admin_invites',
|
||||
'admin_users',
|
||||
'appointment_requests',
|
||||
'bookings',
|
||||
'calendar_connections',
|
||||
'card_leads',
|
||||
'card_view_log',
|
||||
'change_log',
|
||||
'compliance_role_bindings',
|
||||
'deputies',
|
||||
'external_parties',
|
||||
'job_description_blocks',
|
||||
'job_description_versions',
|
||||
'job_descriptions',
|
||||
'locations',
|
||||
'magic_link_tokens',
|
||||
'org_units',
|
||||
'organigram_versions',
|
||||
'portal_api_tokens',
|
||||
'position_assignments',
|
||||
'positions',
|
||||
'push_preferences',
|
||||
'push_subscriptions',
|
||||
'reception_kiosks',
|
||||
'reception_visit_audit',
|
||||
'service_relations',
|
||||
'teamvis_schema_migrations',
|
||||
'trusted_access_log',
|
||||
'visitor_preregistrations',
|
||||
'wallet_pass_registrations',
|
||||
'webhook_deliveries',
|
||||
'webhook_subscriptions'
|
||||
] loop
|
||||
if to_regclass('public.' || t) is not null then
|
||||
execute format('revoke all on table public.%I from anon', t);
|
||||
end if;
|
||||
end loop;
|
||||
end $$;
|
||||
|
||||
drop policy if exists admin_write on public.employees;
|
||||
|
||||
-- authenticated: dieselben engen Rechte wie anon. TeamVis nutzt keine
|
||||
-- Supabase-Auth; auf gemeinsam genutzten Datenbanken kann es aber Inhaber
|
||||
-- eines authenticated-JWT geben. Übrige Tabellen: keine Rechte; die drei
|
||||
-- Kartentabellen: genau die Lesespalten, die anon hat.
|
||||
do $$
|
||||
declare t text; cols text;
|
||||
begin
|
||||
foreach t in array array[
|
||||
'admin_invites', 'admin_users', 'appointment_requests', 'bookings',
|
||||
'calendar_connections', 'card_leads', 'card_view_log', 'change_log',
|
||||
'compliance_role_bindings', 'deputies', 'external_parties',
|
||||
'job_description_blocks', 'job_description_versions', 'job_descriptions',
|
||||
'locations', 'magic_link_tokens', 'org_units', 'organigram_versions',
|
||||
'portal_api_tokens', 'position_assignments', 'positions',
|
||||
'push_preferences', 'push_subscriptions', 'reception_kiosks',
|
||||
'reception_visit_audit', 'service_relations', 'teamvis_schema_migrations',
|
||||
'trusted_access_log', 'visitor_preregistrations',
|
||||
'wallet_pass_registrations', 'webhook_deliveries', 'webhook_subscriptions'
|
||||
] loop
|
||||
if to_regclass('public.' || t) is not null then
|
||||
execute format('revoke all on table public.%I from authenticated', t);
|
||||
end if;
|
||||
end loop;
|
||||
foreach t in array array['employees', 'persons', 'site_settings'] loop
|
||||
if to_regclass('public.' || t) is null then continue; end if;
|
||||
select string_agg(quote_ident(column_name), ', ' order by column_name) into cols
|
||||
from information_schema.column_privileges
|
||||
where table_schema = 'public' and table_name = t
|
||||
and grantee = 'anon' and privilege_type = 'SELECT';
|
||||
execute format('revoke all on table public.%I from authenticated', t);
|
||||
if cols is not null then
|
||||
execute format('grant select (%s) on public.%I to authenticated', cols, t);
|
||||
end if;
|
||||
end loop;
|
||||
end $$;
|
||||
|
||||
-- Ebenfalls nicht aus TeamVis: Policy public_read (Rolle public, aktive
|
||||
-- Karten). Für anon gilt public_read_active_employees (0001/0014).
|
||||
drop policy if exists public_read on public.employees;
|
||||
|
||||
do $$
|
||||
begin
|
||||
if to_regclass('public.teamvis_schema_migrations') is not null then
|
||||
alter table public.teamvis_schema_migrations enable row level security;
|
||||
revoke all on table public.teamvis_schema_migrations from anon;
|
||||
end if;
|
||||
end $$;
|
||||
Reference in new issue
Block a user