Repository navigation
feat(tenancy): route each signed-in request to its tenant's schema (M2b, #93) - #100
Merged
Merged
Conversation
…2b, #93) A request with a bearer session runs in schema tenant_<slug>: its file registry, audit log and uploaded tables live there, so another tenant cannot list, read, delete or collide with them, and duplicate detection becomes per tenant. Requests without a session keep the API-key gate and the default schemas. An invalid session is 401, never a fallback. The schema is a context variable set by the async tenant_scope dependency; services read it through uploads_schema()/te_schema(). Tenant schemas get the per-tenant migrations (0004 is shared-only) when created by scripts/create_tenant_admin.py and at every startup. T&E mode for a tenant returns 409 until per-tenant T&E tables (#99). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019YPoXzBSj89ZHgw7nfTmbB
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.
Fixes #93. This is part 2 of ART Milestone 2 (BR-36; decision 6: schema per tenant).
Behaviour
Authorization: Bearer <session>tenant_<slug>(registry, audit log, uploaded tables)AuthorizationheaderWhat this means for each tenant:
How
api/tenancy.py. The tenant schema is held in a context variable. Services read it throughuploads_schema()andte_schema(); the 23 direct reads ofsettings.UPLOADS_SCHEMAandsettings.TE_SCHEMAin services and routers now go through these functions.tenant_scopereplacesrequire_api_keyon the csv, T&E and audit routers. It's async on purpose: only an async dependency sets the variable in the context that the endpoint's worker thread copies.0004(the shared control schema) is skipped for tenant runs. A tenant's schema is migrated whenscripts/create_tenant_admin.pycreates it, and every existing tenant is brought to head at startup ("migrations run across N schemas", decision 6). Migrating a tenant swaps a setting under a lock, so it's restricted to startup and the CLI, never a request.Evidence
All runs are against local PostgreSQL 16.
scripts/test_report.py --strict)tests/test_tenant_isolation.pytenant_scopescripts/lint.shtenant_<slug>exists → its admin signs in, uploads, and sees only that fileNot in this PR
Generated by Claude Code