session_manifests.payload.hypervision_status = 'PASS_TIER2' · Tier 1 DEGRADED (PR #130 trigger viimase 24h 572 health_check), Tier 2 Supabase MCP otse LIVE. Paralleelseid status='running' sub-sessioone tuvastatud: vs_eirik koord 12 (id=74) = parent — ootuspärane.
Põhjus: RLS-puudus on tegelik risk avalikele tabelitele (LVM-kaart anon-key SELECT + personalos_waitlist anon-key INSERT), kuid 17 sisemist tabelit on madala riski-ga (mõju ainult kui anon-key publicly leakib). Lahendus on selge 3-faasiline migration, mis ei riku ühtegi LIVE-äppi.
3 PARANDUST:
service_role_only policy. 0 äpi-mõju, sest need tabelid pole anon-key kaudu kasutusel.anon_read/anon_insert policy: lvm_parcels, lvm_fells, lvm_nogabali (Janis-äpi kaart), personalos_waitlist (signup vorm). 8 SECURITY DEFINER vaate → SECURITY INVOKER konversioon koos baastabelite anon_read policy lisamisega. spatial_ref_sys JÄTTA puutumata (PostGIS standard, Supabase advisor false-positive).SET search_path = public, pg_catalog bulk-lock. PostGIS funktsioone EI puuduta (extension manageeritud).VERDICT-i kvalifikatsioon: Kui Faas 1 + Faas 2 + Faas 3 rakendatakse järjest 1 ETA-päeva sees → PASS. Praegune CONCERNS = LIVE-staatus (0% LIVE).
| Tabel | Suurus | Layer | Consumers (registry) | App-kasutus | Risk | Verdict | Faas | Soovitatav policy |
|---|---|---|---|---|---|---|---|---|
| lvm_nogabali | 39 MB | 2A | terranervus, timbertrace, janis_ui | lvm_geo_kaart_v1.html:400 ANON SELECT | 4 | anon_read | Faas 2 | CREATE POLICY anon_read ON public.lvm_nogabali FOR SELECT USING (true); |
| lvm_works | 9.5 MB | 2A | terranervus | — | 2 | service_only | Faas 1 | FORCE RLS; service_role ALL |
| lvm_cirsmas | 7.3 MB | 2A | terranervus, timbertrace, janis_ui | — (registry janis_ui aga grep 0 hit) | 3 | service_only* | Faas 1 | *Kui janis_ui hakkab anon-i kasutama, lisa anon_read hiljem (Faas 2 patch) |
| spatial_ref_sys | 7 MB | 2A | postgis | PostGIS extension data | 1 | postgis_skip | — | JÄTA puutumata. Supabase advisor INFO-level false-positive — PostGIS standard SRID tabel, ainult koordinaadid (EPSG:4326 jne), pole tundlikku andmeid. Migration ALTER TABLE spatial_ref_sys ENABLE RLS tekitab extension-level konfliktid. |
| lvm_parcels | 4 MB | 2A | terranervus, timbertrace, janis_ui | lvm_geo_kaart_v1.html:299 ANON SELECT + write_map_v2.py:270 | 5 | anon_read | Faas 2 | CREATE POLICY anon_read ON public.lvm_parcels FOR SELECT USING (true); |
| lvm_fells | 840 kB | 2A | terranervus, timbertrace | lvm_geo_kaart_v1.html:336 ANON SELECT | 4 | anon_read | Faas 2 | CREATE POLICY anon_read ON public.lvm_fells FOR SELECT USING (true); |
| pos_deep_memory_l2 | 392 kB | 2B | vs_eirik, cowork_eirik, chat_eirik | tier_2_5_helper SERVICE_ROLE | 7 | service_only | Faas 1 | Mälu-agendi narratiivi-mälu — sisaldab kogu Erki–Eirik kontekstuaal-info. Avalik = identiteedi leke. |
| lvm_service_providers | 240 kB | 2A | timbertrace | — | 3 | service_only | Faas 1 | FORCE RLS; service_role ALL |
| skills_registry | 152 kB | 2E | all_agents | kaudne läbi v_active_skills (SECURITY DEFINER view, anon bypass) |
2 | service_only | Faas 1 | Sõltuvus: v_active_skills jätkab töötamast SECURITY DEFINER tõttu (kuni Faas 2 view-konversioon). Pärast view INVOKER → vaja anon_read WHERE status='active'. |
| agent_runs | 144 kB | 4 | vs_eirik, cowork_eirik, chat_eirik, cursor_eirik, vahimees_eirik, malu_agent, archiver | eirik_live.html:336 ANON SELECT läbi v_agent_live (SECURITY DEFINER) |
5 | service_only | Faas 1 | SECURITY DEFINER view kaitseb täna anon-juurdepääsu. Kui view → SECURITY INVOKER, vaja anon_read või jätame view DEFINER-iks (Variant B). |
| santa_saatelehed | 128 kB | 2A | timbertrace | santa_xlsx_sync/sync.py:43 SERVICE_ROLE | 4 | service_only | Faas 1 | Vestmani transport-andmed — anon leke = klient-info paljas. |
| process_state_log | 120 kB | 4 | malu_agent, vahimees_eirik, archiver | kaudne läbi v_agent_live | 3 | service_only | Faas 1 | FORCE RLS; service_role ALL |
| agent_task_locks | 96 kB | 4 | vs_eirik, cowork_eirik, chat_eirik, cursor_eirik, vahimees_eirik, malu_agent | eirik_live.html:299 ANON SELECT (otsene) | 4 | anon_read* või service_only | Faas 2 | Erki otsus vajalik: kas eirik_live.html on (a) avalik dashboard → anon_read OR (b) sisemine → muuda eirik_live.html service_role peale või loginiga. |
| sec_filings | 96 kB | 2C | nw_kinnistu_optimizer | — | 2 | service_only | Faas 1 | FORCE RLS; service_role ALL (turuandmed avalik EDGAR, aga ETL-load on private) |
| integration_inventory | 64 kB | 2E | admin | — | 3 | service_only | Faas 1 | Admin-tabel |
| market_quotes | 64 kB | 2C | nw_kinnistu_optimizer | — | 2 | service_only | Faas 1 | FORCE RLS; service_role ALL |
| market_fundamentals | 64 kB | 2C | nw_kinnistu_optimizer | — | 2 | service_only | Faas 1 | FORCE RLS; service_role ALL |
| inventory_files | 56 kB | 2F | classifier.py, extractor.py, embedder.py, cataloger.py, vahimees_eirik | — | 5 | service_only | Faas 1 | Mälu-agendi failipaths Touro 461GB — leke = file-system kaardistus. |
| timbertrace_deliveries | 56 kB | 2A | timbertrace | ocr_pipeline.py:42 SERVICE_ROLE | 6 | service_only | Faas 1 | Vestmani veoselehed OCR — kliendi-tundlik (PR #112 andmete-omandus printsiip). |
| toftan_warehouse_stock | 48 kB | 2C | timbertrace | toftan_sftp_watcher/watcher.py:138 SERVICE_ROLE | 5 | service_only | Faas 1 | Toftan saetehas stock — partner-tundlik. |
| jetson_jobs | 40 kB | +B | malu_agent, vahimees_eirik, kaardiaju | — | 2 | service_only | Faas 1 | FORCE RLS; service_role ALL |
| nse_corporate_filings | 32 kB | 2C | nw_kinnistu_optimizer | — | 2 | service_only | Faas 1 | FORCE RLS; service_role ALL |
| insider_transactions | 32 kB | 2C | nw_kinnistu_optimizer | — | 2 | service_only | Faas 1 | FORCE RLS; service_role ALL |
| personalos_waitlist | 32 kB | 2C | personalos | personalos.html:599+617 ANON SELECT count + ANON INSERT | 8 | anon_insert + count | Faas 2 | KRIITILINE: avalik signup vorm — ilma RLS-iga saab anon SELECT *. Vajab: anon_insert policy (WITH CHECK true) + anon_count_only (näit USING (false) aga count-päring töötab või eraldi RPC) + service_role read full. |
| lvm_etl_sync_log | 24 kB | 2F | ops_board | — | 2 | service_only | Faas 1 | FORCE RLS; service_role ALL |
| View | Baastabel(id) | Anon-kasutus? | Verdict | Soovitatav samm |
|---|---|---|---|---|
| v_agent_live | agent_runs, process_state_log, agent_task_locks | eirik_live.html ANON | CONCERNS | Variant B (eelistatud): jätka SECURITY DEFINER + GRANT SELECT TO anon. Long-term Variant A: muuda INVOKER + baastabelite anon_read. |
| v_active_skills | skills_registry | tundmatu (grep 0 hit; tõenäoliselt ops_board admin) | PASS | Muuda SECURITY INVOKER. skills_registry service_role-only OK kuna ops_board kasutab ilmselt teenuse-võtit. |
| v_pending_invoices | invoice_verifications | tundmatu (eeldatavalt Janis admin) | CONCERNS | Muuda INVOKER. Vaja kontrollida kas Janis-äpp kasutab anon-key (PR #109 invoice-verify pipeline). |
| v_active_price_lists | price_lists | tundmatu | PASS | INVOKER + price_lists service_role-only |
| data_freshness_status | data_sources, sync_log | projektipuu.html ANON (data_sources) | CONCERNS | Säilita DEFINER VÕI lisa baastabelitele anon_read. Aga lihtsam: jätka DEFINER + GRANT. |
| v_changelog | agent_messages | tundmatu | CONCERNS | Säilita DEFINER + GRANT. agent_messages ON KAITSTUD täna (RLS LIVE) aga view bypassib seda — risk on lugemise scope laienemine. |
| v_active_coefficient | coefficient_history | tundmatu | PASS | INVOKER + coefficient_history service_role-only |
| v_layer_registry_summary | forestsense_layer_registry | tundmatu (ops_board admin) | PASS | INVOKER + forestsense_layer_registry anon_read OK (mitte tundlik — registry definitsioonid). |
SECURITY INVOKER + baastabelitele lisa anon_read spetsiifilise filter-iga. Puhtam PG 15+ best practice. Suurem töö, mitu policy-d.
Supabase advisor näitas 34 funktsiooni. Tegelikult ~30 user-funktsiooni (ülejäänud on PostGIS extension, ei puuduta). Kriitilisemad on 7 SECURITY DEFINER user-funktsiooni — neid kasutatakse RLS-bypass-iga, mistõttu mutable search_path = SQL-injection vektor.
| Funktsioon | Lang | Sec mode | Risk | Soovitus |
|---|---|---|---|---|
| hypervision_record_api_key_usage | plpgsql | DEFINER | 7 | SET search_path = public, pg_catalog |
| hypervision_verify_api_key | plpgsql | DEFINER | 7 | SET search_path = public, pg_catalog |
| insert_tma | plpgsql | DEFINER | 6 | SET search_path = public, pg_catalog |
| set_default_client_id | plpgsql | DEFINER | 5 | SET search_path = public, pg_catalog |
| trigger_embed_message | plpgsql | DEFINER | 5 | SET search_path = public, pg_catalog |
| trigger_red_team_check | plpgsql | DEFINER | 5 | SET search_path = public, pg_catalog |
| ~25 SECURITY INVOKER user-funktsiooni | — | INVOKER | 3 | Bulk ALTER FUNCTION SET search_path |
| ~140 PostGIS funktsiooni | sql/plpgsql | INVOKER | 1 | EI PUUDUTA — PostGIS extension management. |
-- Faas 1: 17 sisemise tabeli RLS + service_role-only policy
-- 0 äpi-mõju (pole anon-key kaudu kasutusel)
-- Apply: Supabase Studio → SQL Editor
BEGIN;
-- 1. LVM ETL tabelid (3)
ALTER TABLE public.lvm_works ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.lvm_cirsmas ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.lvm_service_providers ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.lvm_etl_sync_log ENABLE ROW LEVEL SECURITY;
-- 2. Market data (5)
ALTER TABLE public.sec_filings ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.market_quotes ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.market_fundamentals ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.nse_corporate_filings ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.insider_transactions ENABLE ROW LEVEL SECURITY;
-- 3. Mälu-agent + Hypervision (5)
ALTER TABLE public.pos_deep_memory_l2 ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.inventory_files ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.jetson_jobs ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.process_state_log ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.agent_runs ENABLE ROW LEVEL SECURITY;
-- 4. Tundlikud partner-tabelid (3)
ALTER TABLE public.santa_saatelehed ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.timbertrace_deliveries ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.toftan_warehouse_stock ENABLE ROW LEVEL SECURITY;
-- 5. Skills + integration (2)
ALTER TABLE public.skills_registry ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.integration_inventory ENABLE ROW LEVEL SECURITY;
-- service_role-only policy bulk (PostgreSQL alates 17 saab kasutada DO-blokis;
-- 16 või vanem — kirjuta need 18 lauset käsitsi)
DO $$
DECLARE t TEXT;
BEGIN
FOREACH t IN ARRAY ARRAY[
'lvm_works','lvm_cirsmas','lvm_service_providers','lvm_etl_sync_log',
'sec_filings','market_quotes','market_fundamentals','nse_corporate_filings','insider_transactions',
'pos_deep_memory_l2','inventory_files','jetson_jobs','process_state_log','agent_runs',
'santa_saatelehed','timbertrace_deliveries','toftan_warehouse_stock',
'skills_registry','integration_inventory'
] LOOP
EXECUTE format('CREATE POLICY service_role_all ON public.%I FOR ALL TO service_role USING (true) WITH CHECK (true);', t);
END LOOP;
END $$;
COMMIT;
-- Validatsioon
SELECT tablename, count(*) AS policy_count FROM pg_policies WHERE schemaname='public'
AND tablename IN ('lvm_works','lvm_cirsmas','lvm_service_providers','lvm_etl_sync_log',
'sec_filings','market_quotes','market_fundamentals','nse_corporate_filings','insider_transactions',
'pos_deep_memory_l2','inventory_files','jetson_jobs','process_state_log','agent_runs',
'santa_saatelehed','timbertrace_deliveries','toftan_warehouse_stock',
'skills_registry','integration_inventory')
GROUP BY tablename;
-- Eeldus: 19 rida, igaüks policy_count=1
v_agent_live jätame SECURITY DEFINER-iks, ka eirik_live.html anon-päring jätkab.
-- Faas 2: 4 avaliku tabeli anon_read/insert + agent_task_locks otsus + view INVOKER (valikuline) BEGIN; -- 1. LVM kaart (Janis-äpp anon-key SELECT) ALTER TABLE public.lvm_parcels ENABLE ROW LEVEL SECURITY; ALTER TABLE public.lvm_fells ENABLE ROW LEVEL SECURITY; ALTER TABLE public.lvm_nogabali ENABLE ROW LEVEL SECURITY; CREATE POLICY anon_read ON public.lvm_parcels FOR SELECT TO anon, authenticated USING (true); CREATE POLICY anon_read ON public.lvm_fells FOR SELECT TO anon, authenticated USING (true); CREATE POLICY anon_read ON public.lvm_nogabali FOR SELECT TO anon, authenticated USING (true); CREATE POLICY service_role_all ON public.lvm_parcels FOR ALL TO service_role USING (true) WITH CHECK (true); CREATE POLICY service_role_all ON public.lvm_fells FOR ALL TO service_role USING (true) WITH CHECK (true); CREATE POLICY service_role_all ON public.lvm_nogabali FOR ALL TO service_role USING (true) WITH CHECK (true); -- 2. PersonalOS waitlist (avalik signup vorm) ALTER TABLE public.personalos_waitlist ENABLE ROW LEVEL SECURITY; -- anon saab INSERT (signup) AGA EI saa SELECT (e-maile ei loe kõik) CREATE POLICY anon_insert ON public.personalos_waitlist FOR INSERT TO anon, authenticated WITH CHECK (true); -- count-päring vajab eraldi RPC funktsiooni VÕI policy USING(false) + count erand -- Lihtsam: loo RPC SECURITY DEFINER `personalos_waitlist_count()` CREATE OR REPLACE FUNCTION public.personalos_waitlist_count() RETURNS integer LANGUAGE sql SECURITY DEFINER SET search_path = public, pg_catalog AS $$ SELECT count(*)::int FROM personalos_waitlist; $$; GRANT EXECUTE ON FUNCTION public.personalos_waitlist_count() TO anon, authenticated; -- service_role full access CREATE POLICY service_role_all ON public.personalos_waitlist FOR ALL TO service_role USING (true) WITH CHECK (true); -- TODO: uuenda personalos.html:599 päring RPC kutsele -- 3. agent_task_locks — KAS eirik_live.html on avalik? -- VARIANT A (avalik dashboard, Erki valib): anon_read -- ALTER TABLE public.agent_task_locks ENABLE ROW LEVEL SECURITY; -- CREATE POLICY anon_read ON public.agent_task_locks FOR SELECT TO anon USING (true); -- CREATE POLICY service_role_all ON public.agent_task_locks FOR ALL TO service_role USING (true) WITH CHECK (true); -- VARIANT B (sisemine, Erki valib): service_only + muuda eirik_live.html service_role peale ALTER TABLE public.agent_task_locks ENABLE ROW LEVEL SECURITY; CREATE POLICY service_role_all ON public.agent_task_locks FOR ALL TO service_role USING (true) WITH CHECK (true); -- 4. spatial_ref_sys — JÄTA RLS OFF (PostGIS standard, advisor false-positive) -- (ei tee mingit muudatust) -- 5. SECURITY DEFINER → INVOKER konversioon (valikuline, soovituslik PG15+) -- Variant A — täielik: ALTER VIEW public.v_active_skills SET (security_invoker=true); ALTER VIEW public.v_active_price_lists SET (security_invoker=true); ALTER VIEW public.v_active_coefficient SET (security_invoker=true); ALTER VIEW public.v_layer_registry_summary SET (security_invoker=true); GRANT SELECT ON public.v_layer_registry_summary TO anon, authenticated; -- v_agent_live + v_changelog + v_pending_invoices + data_freshness_status — JÄTA DEFINER -- (anon-kasutus baastabelite vastu vajab täiendavat policy-tuningut, eraldi triaaž) COMMIT;
-- Faas 3: 30 user-funktsiooni search_path lukk -- PostGIS funktsioone EI muuda (extension management) BEGIN; -- 7 SECURITY DEFINER kriitilist ALTER FUNCTION public.hypervision_record_api_key_usage SET search_path = public, pg_catalog; ALTER FUNCTION public.hypervision_verify_api_key SET search_path = public, pg_catalog; ALTER FUNCTION public.insert_tma SET search_path = public, pg_catalog; ALTER FUNCTION public.set_default_client_id SET search_path = public, pg_catalog; ALTER FUNCTION public.trigger_embed_message SET search_path = public, pg_catalog; ALTER FUNCTION public.trigger_red_team_check SET search_path = public, pg_catalog; -- 23 SECURITY INVOKER user-funktsiooni ALTER FUNCTION public.acquire_agent_lock SET search_path = public, pg_catalog; ALTER FUNCTION public.audit_check_source SET search_path = public, pg_catalog; ALTER FUNCTION public.audit_immutable SET search_path = public, pg_catalog; ALTER FUNCTION public.auto_cleanup SET search_path = public, pg_catalog; ALTER FUNCTION public.block_legacy_watchdog SET search_path = public, pg_catalog; ALTER FUNCTION public.calculate_coefficient SET search_path = public, pg_catalog; ALTER FUNCTION public.check_response_format SET search_path = public, pg_catalog; ALTER FUNCTION public.claim_work SET search_path = public, pg_catalog; ALTER FUNCTION public.find_skill SET search_path = public, pg_catalog; ALTER FUNCTION public.os_reports_update_search_text SET search_path = public, pg_catalog; ALTER FUNCTION public.query_memory SET search_path = public, pg_catalog; ALTER FUNCTION public.search_bge_m3 SET search_path = public, pg_catalog; ALTER FUNCTION public.search_memory_text SET search_path = public, pg_catalog; ALTER FUNCTION public.search_memory_vec SET search_path = public, pg_catalog; ALTER FUNCTION public.search_pos_deep_memory SET search_path = public, pg_catalog; ALTER FUNCTION public.search_pos_memory SET search_path = public, pg_catalog; ALTER FUNCTION public.tma_load_stems SET search_path = public, pg_catalog; ALTER FUNCTION public.tma_load_stems_json SET search_path = public, pg_catalog; ALTER FUNCTION public.tma_load_tracking_json SET search_path = public, pg_catalog; ALTER FUNCTION public.trg_layer_registry_updated_at SET search_path = public, pg_catalog; ALTER FUNCTION public.trigger_embed_agent_message SET search_path = public, pg_catalog; ALTER FUNCTION public.trigger_sync SET search_path = public, pg_catalog; ALTER FUNCTION public.update_coefficient SET search_path = public, pg_catalog; ALTER FUNCTION public.update_skills_registry_updated_at SET search_path = public, pg_catalog; ALTER FUNCTION public.watchdog_check SET search_path = public, pg_catalog; ALTER FUNCTION public.watchdog_daily_report SET search_path = public, pg_catalog; -- search_memory + query_memory on overload-vorm (mitu signatuuri) — peab käsitsi viiteid: -- Kontroll \df+ search_memory ENNE. COMMIT; -- Validatsioon SELECT proname, array_to_string(proconfig, ', ') AS cfg FROM pg_proc p JOIN pg_namespace n ON n.oid=p.pronamespace WHERE n.nspname='public' AND p.proname IN ( 'hypervision_record_api_key_usage','hypervision_verify_api_key','insert_tma', 'set_default_client_id','trigger_embed_message','trigger_red_team_check', 'calculate_coefficient','search_pos_deep_memory','tma_load_stems_json','watchdog_check' ); -- Eeldus: kõik cfg sisaldab 'search_path=public, pg_catalog'
ALTER FUNCTION search_memory ebaõnnestub kui funktsiooni on 2 signatuuri. Vaja täpsustada argumenttüüpe: ALTER FUNCTION search_memory(text, integer) .... Faas 3 PEAB enne apply'i tegema \df+ search_memory tüüpide tuvastamiseks.
spawn_red_team_rls_2026-05-27 · Eirik OS K0 sub-agent · PR #115 audit-jälg + PR #112 Kiht 1 + PR #124 SAMM 12 + PR #81 Red Team verdict mall
Generated 2026-05-27 · Tier 2 Supabase MCP (Tier 1 DEGRADED PR #130)