feat(compliance): add per-provider geo-blocking - #173
Conversation
Operators can block every game of a game provider in a country. Adds the provider_geo_rule table, admin routes to upsert, delete and list provider rules, audited change events, and a provider_block decision in the game geo check. The check now resolves provider and game rules in one query and denies an unknown game.
Null the country code on game_not_found, share the unresolved-country match between the provider and game subqueries, and serialize geo rules through one helper.
|
Blocker: provider-country enforcement can be bypassed by spoofing |
Drop the narrative comment in the game geo check, and assert the persisted audit records for provider geo rule upsert and delete in the lifecycle E2E.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Security findingsAdvisory findings (1)
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: 542abfc76f
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
List game and provider geo rules with page/limit and gameIds[]/providerIds[] filters, returning the shared paginated shape.
Blocking a game or provider in many countries took one request per country.
Add PUT and DELETE /compliance/{game,provider}-geo-rules/bulk taking
countryCodes (1-250) and a reason. Each request is one transaction: bulk
delete fails with 404 and removes nothing if any listed country has no rule.
Every rule still emits its own upserted/deleted event, so audit stays per rule.
Single-country upserts now delegate to the bulk path. withAdvisoryXactLocks
takes all rule locks in one statement, ordered by lock id so overlapping
bulk writes cannot deadlock.
Game and provider geo rules each had a single-country upsert, a delete by
rule id, and separate /bulk routes. Keep one pair per rule type, with the
game or provider id in the path and a list of countries in the body:
PUT|DELETE /compliance/game-geo-rules/{gameId} { countryCodes, reason }
PUT|DELETE /compliance/provider-geo-rules/{providerId} { countryCodes, reason }
To change one country, pass a one-element list.
BREAKING CHANGE: PUT /compliance/game-geo-rules and
DELETE /compliance/game-geo-rules/{id} are removed. Callers move the game
id into the path, send countryCodes instead of countryCode, and remove
rules by country code instead of rule id. Both routes now return an array.
Summary
Operators can now block every game of a game provider in a country. Admin routes under
/compliance/provider-geo-rulesadd, remove and list provider rules. Every change is audited, and new rounds are checked against these rules alongside the existing global and per-game rules.Why
Per-game geo rules (#154) need one rule per game. A provider's licence restriction usually covers its whole catalogue. Blocking it game by game means many rules to maintain and audit, and any game added to the provider later is not blocked.
Alternatives considered
Risks
GameGeoDenialReasongainsprovider_blockandgame_not_found. Consumer code that handles every reason explicitly needs updating.checkGameon the geo-check port (GAME_GEO_CHECK) now denies a game id that does not exist instead of allowing it.startRoundis unaffected because it rejects unknown games first; other callers of the port will see the new denial.