Repository navigation
feat: enforce scopeBy in Go and Python services - #169
Merged
Merged
Conversation
With auth configured, a Go or Python service now keeps each caller to its own tenant's rows, matching TypeScript: lists and reads are filtered, a create stores the caller's tenant whatever the body says, an update cannot move a row to another tenant, another tenant's row is a 404, and a caller with no tenant gets 403. Bypass roles and enforceOn are honored. - Go: the auth middleware also stores the caller on the request context; scoped services add a tenant WHERE (compared as text) before the user's filters, which are ANDed. Shared helpers in services/scope.go and handlers/scope.go. - Python: QueryBuilder takes scope conditions; routers pass the caller to the service, which scopes every query and sets the tenant on create. - TypeScript: an update can no longer move a scoped row to another tenant (the scope guard now forces the caller's tenant on update too). - Nested scopeBy paths are still TypeScript only; Go and Python warn. The auth smoke now checks tenant isolation in all three languages, including cross-tenant update and delete and an update that tries to move a row.
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.
Why
Since 0.45, Go and Python services check who's calling but don't filter rows by tenant. In a multi-tenant schema, any signed-in user could read and change every tenant's rows.
What
With auth configured, Go and Python now match TypeScript:
bypassRolesandenforceOnare honored.How each language does it:
WHEREbefore the user's filters, and those filters (including the groupedor) are ANDed with it. The tenant is compared as text, because claims are strings and the column may be an integer or a uuid. Shared helpers live inservices/scope.goandhandlers/scope.go.QueryBuildertakes scope conditions. Routers passrequest.state.authto the service, which scopes every query and sets the tenant on create.PATCHwith another tenant'sorganizationIdmoved the row to that tenant. The scope guard now forces the caller's tenant on update.Nested
scopeBypaths (task.workspaceId) are still TypeScript-only. Go and Python print a warning for them.Tests
orgIdscopes likeorganizationId. It runs for all six provider cases.Locally, every auth check passes in TypeScript, Go and Python.