fix(db): stop game read policies recursing through game_players - #29
Merged
Merged
Conversation
Signed-in reads of game_players, games, domain_events and rooms failed with 'infinite recursion detected in policy for relation game_players': the game_players SELECT policy queried game_players, and the games SELECT policy queried game_players back. Migration 20260914000002 adds is_game_participant(game_id), a SECURITY DEFINER check with an empty search_path that reads game_players as its owner, and rewrites both SELECT policies to use it. Access is unchanged, and the domain_events and rooms policies work again as written. pgTAP covers a seated player, an outsider, an anonymous client, AI seats, waiting and spectator-enabled games, and the function's definer and grant shape. The migration applies alone after 20260914000001, before or after 20260913000002. Roadmap section 1 drops the finished step and the release applies 20260914000001 and 20260914000002.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Roadmap section 1 step 2: game read policies no longer recurse.
Reproduced locally as a signed-in user:
selectongame_players,games,domain_eventsandroomseach failed withinfinite recursion detected in policy for relation "game_players". Thegame_playersSELECT policy queriedgame_players, and thegamesSELECT policy queriedgame_playersback. Game history, game details and analysis in the web app would have failed as soon as games started saving (#28).supabase/migrations/20260914000002_game_access_policies.sql:public.is_game_participant(game_id):SECURITY DEFINER,STABLE,search_path = ''. It is true whenauth.uid()holds a human seat in the game.EXECUTEis revoked fromPUBLICand granted toanon,authenticatedandservice_role, because policies run with the caller's privileges.game_playersandgamesSELECT policies are rewritten to use it, with the same access rules: participants, waiting games, and spectator-enabled games in the listed statuses.domain_eventsandroomswork again unchanged.supabase/tests/game_access_policies.sql(15 tests):domain_eventsandroomssucceed;20260914000001and20260914000002.The spectator clauses still name a
playingstatus that thegamescheck never allows. That is preserved as-is here; the roadmap's Supabase minimization removes the spectator policies.No migration applied, nothing deployed.
Verification
supabase test dbpasses with the new file.000001,20260914000001, this migration, without000002): applies cleanly, and the new test file passes.node scripts/check-docs.mjs,git diff --check, the public-safety scan, pre-pushpnpm validate:ci, and CI and CodeQL on this PR.