gate: fresh session per plugin activation to isolate RLS errors

This commit is contained in:
Agent Zero
2026-07-31 09:43:29 +02:00
parent ab8d878bc7
commit fa96466a50
+11 -13
View File
@@ -220,26 +220,24 @@ async def lifespan(app: FastAPI):
logger.info(f"Plugin {name} is inactive — skipping activation") logger.info(f"Plugin {name} is inactive — skipping activation")
continue continue
# Activate plugin with tenant context set for each tenant # Activate plugin with a FRESH session per plugin to avoid RLS state leakage
# RLS fail-closed requires app.current_tenant_id for tenant-table writes. # RLS fail-closed requires app.current_tenant_id for tenant-table writes.
# Plugin activation may fail on duplicate cron job inserts — this is # Plugin activation may fail on duplicate cron job inserts — this is harmless
# harmless since cron jobs already exist from previous startups. # since cron jobs already exist from previous startups.
try: plugin_activated = False
for tenant_id in all_tenant_ids: for tenant_id in all_tenant_ids:
try: try:
await set_tenant_context(db, tenant_id) async with async_session() as plugin_db:
await plugin.on_activate(db, container, event_bus) await set_tenant_context(plugin_db, tenant_id)
await db.flush() await plugin.on_activate(plugin_db, container, event_bus)
await plugin_db.flush()
await plugin_db.commit()
plugin_activated = True
except Exception as exc: except Exception as exc:
logger.warning(f"[STARTUP] Plugin {name} activation issue for tenant {tenant_id}: {exc}") logger.warning(f"[STARTUP] Plugin {name} activation issue for tenant {tenant_id}: {exc}")
await db.rollback()
db.expunge_all() # Clear pending objects from failed INSERT
break break
except Exception as exc:
logger.warning(f"[STARTUP] Plugin {name} activation failed: {exc}")
await db.rollback()
db.expunge_all()
if plugin_activated:
plugin_record.status = "active" plugin_record.status = "active"
logger.info(f"[STARTUP] Activated plugin: {name}") logger.info(f"[STARTUP] Activated plugin: {name}")