Search code examples
sqlpostgresqlkubernetesrow-level-security

Does recreating an RLS policy in a transaction expose data?


Say I have an RLS policy on a table, and I realize I goofed and forgot a command in the policy, so can't ALTER it; it must be DROP/CREATEed. I'm using rolling updates in k8s, and my DB migrations happen in an init container. I deploy my new application version that DROPs the policy and CREATEs the new one with the correct set of commands. Is there a window, however brief between CREATE and DROP, where the still running old pod now has access to everything? Intuition says "definitely", but testing a fraction of a second race condition is hard. Can I prevent this window by wrapping the DROP/CREATE in a transaction? Are there other methods to make this safe?

Real world, the correct answer is "your deployed version has a security vulnerability. Scale to 0 and deploy the correct version", but I'm trying to think through the vulnerabilities this set up brings, and others doing the deploy in the future may not be so careful.

My current setup is running 9.6, but there's a plan in the medium-term to work it up to 15.1, so answers for either version are welcome.


Solution

  • A row level security policy allows a role to do something, so dropping the policy will reduce what the user can do. If you are worried that this can cause errors or bad results for concurrent queries, wrap the DROP POLICY and CREATE POLICY` statements in a single transaction, then all concurrent queries get blocked. That shouldn't be a problem, because both statements are fast.