feat: tenant isolation Phase 3 — audit_logs, tree_shares, remaining RLS #135
Reference in New Issue
Block a user
Delete Branch "feat/tenant-isolation-phase-3"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
audit_logs: Addedaccount_id NOT NULL(FK →accounts), backfilled fromuser_id → users.account_id. Updatedlog_audit()with optionalaccount_idparam + auto-lookup fallback so all ~40 call sites remain unchanged.tree_shares: Addedaccount_id NOT NULL(FK →accounts), backfilled fromtree_id → trees.account_id(notcreated_by → users.account_id— shares must live in the tree owner's tenant so RLS covers them after cross-tenant super-admin shares). Fixed write path intrees.pyto usetree.account_id, notcurrent_user.account_id.ALTER TABLE ... ENABLE ROW LEVEL SECURITY+FORCE ROW LEVEL SECURITY+ standardaccount_id = current_setting(...)::uuidpolicy onstep_ratings,step_usage_log,target_lists,session_shares,audit_logs,tree_shares(6 tables).target_lists: Droppedteam_idcolumn (superseded byaccount_idfrom Phase 2). Endpoint and schema updated to useaccount_idthroughout.test_rls_isolation.py(one per Phase 3 table). Updatedtest_tree_sharing.py,test_target_lists.py,test_phase1_migrations.pyfor model changes.Migration chain
Key correctness note
tree_shares.account_idis derived fromtree.account_id(the tree owner's tenant), not fromcurrent_user.account_id(the actor). A super admin in tenant A sharing tenant B's tree must produce a share row visible to tenant B's RLS context.Test plan
pytest tests/test_rls_isolation.py— all Phase 3 isolation tests passpytest tests/test_tree_sharing.py— share account_id matches tree ownerpytest tests/test_target_lists.py— cross-account isolation enforcedalembic upgrade headon clean DB — migrations apply cleanly🤖 Generated with Claude Code
🚅 Deployed to the resolutionflow-pr-135 environment in selfless-grace