# v0.87.9 - Core Lifecycle Security > **Status:** Planned > **Scope:** 6 person-weeks > **User promise:** *"An owner can manage a stream table without private-schema grants."* > **Blocked by:** [v0.87.8](v0.87.8.md) > **Program:** [Lifecycle security reimplementation](../plans/pg_trickle_lifecycle_security_reimplementation_plan.md) ## Theme Fix issue #941 for create-or-replace, alter, and drop. Public entry points may use a pinned `SECURITY DEFINER` path only after they capture the original caller and resolve caller-controlled names under that caller's context. Privileged phases accept canonical OIDs and quoted catalog-derived identifiers. Create and alter run defining SQL as the stream owner. Drop authorizes the complete dependency plan before the first mutation. ## Scope allocation | Work package | Person-weeks | |---|---:| | Canonical resolution and prepared lifecycle plans | 1.25 | | Create-or-replace and alter hardening | 1.50 | | Atomic cascade and bulk-ready drop planning | 1.00 | | Lifecycle, exploit, rollback, upgrade, and documentation tests | 2.25 | | **Total** | **6.00** | ## Items ### LSEC-7: Canonical caller-context resolution Resolve existing relations through PostgreSQL under the caller role and path. Resolve new targets through the caller's effective schema. After resolution, private phases use only OIDs or one shared qualified-identifier type. Remove ad hoc dotted-name splitting, hard-coded `public`, and definer-context `current_schema()` from the affected paths. ### LSEC-8: Prepared create and alter phases Preflight source `SELECT`, source-schema `USAGE`, target-schema `CREATE`, query validation, and dependency resolution as the caller. Create private state as the definer, transfer storage ownership before population, execute population as owner, and finalize private state last. Alter preserves the exact pre-change owner across every storage recreation. Query migration, partition-key changes, mode changes, and full repopulation remain atomic. ### LSEC-9: Fully authorized drop plans Build a deterministic child-first plan without mutation. Deduplicate targets, detect cycles, and check every affected stream table against the original caller. Reject the complete operation before dropping anything when one target is unauthorized. ## Required tests - Minimal-grant fixtures provide exact function grants and normal source and target privileges, with no private catalog or change-schema grants. - Owner, non-owner, superuser, quoted-name, custom-path, and `$user` cases cover both create and replace branches. - Query-changing, partition-changing, mode-changing, no-op, and failing alter cases verify owner, path, data, catalog, CDC, and frontier state. - Same-owner cascade succeeds. Mixed-owner and injected-failure cascades leave every relation and catalog row intact. - Malicious functions, operators, views, casts, RLS policies, and target names cannot observe or use extension-owner authority. - Fresh install and v0.87.8 upgrade tests verify exact `prosecdef`, `proconfig`, overload identity, and retained ACLs. ## Exit criteria - [ ] The three issue #941 APIs work for an owner with exact public grants. - [ ] The same owner has no direct private-schema access. - [ ] Every caller-controlled name resolves under the original caller context. - [ ] Every recreation preserves the exact storage owner and stored path. - [ ] Unauthorized cascade targets cause zero mutations. - [ ] Security, rollback, upgrade, and full repository CI gates pass.