Run the module without connecting an identity provider
Download pattern_12.py and test_pattern_12.py. With Python 3.11 or later, macOS commands are python3 -B pattern_12.py and python3 -B -m unittest -v test_pattern_12.py. Windows launcher equivalents are py -3 -B pattern_12.py and py -3 -B -m unittest -v test_pattern_12.py. The code is standard-library only and performs no model or network calls.
The output contains distinct evidence for tenants a and b and cross_tenant_denied set to true. These are synthetic records. A successful run proves the specified local checks under the supplied fixtures; it does not prove authentication, distributed isolation, or protection from a caller who can directly modify the Python process.
Architecture and request sequence
Read the architecture as text
- Principal fixture: Subject, tenant memberships and scopes
- authorize method: Check before any cache access
- Scoped tuple key: Tenant and incident identify record
- Rows and cache: Write invalidates matching cached value
- Principal fixture → authorize method: Validated input
- authorize method → Scoped tuple key: Bounded processing
- Scoped tuple key → Rows and cache: Recorded result
Read the sequence as text
- Caller → Boundary: Supply trusted principal
- Boundary → Store: Authorize scope
- Store → Boundary: Lookup scoped cache
- Caller → Boundary: Update permitted record
- Boundary → Store: Invalidate cached version
Inspect the trusted-principal seam
Principal is an immutable dataclass containing a subject, tenant memberships, and scopes. The store requires an instance with a nonempty subject, then checks membership and the requested scope. This is a deliberately explicit seam for an authentication adapter. A production server would construct the object from verified identity and current policy; it must not deserialize a client-provided object and call that verification.
The example's authorize method distinguishes read and write access. Tests confirm that a read-only principal cannot write and that a plain dictionary is rejected. These checks expose ordering and interface expectations, not cryptographic identity proof. The model adapter belongs downstream of authorization and should receive only the evidence that the verified principal is permitted to use.
Follow a write through quota and invalidation
The write method authorizes first and validates the incident and text. New records consume the tenant's independent count. Updating an existing record does not consume another slot. A full tenant is rejected without preventing another tenant from creating its first record. This is a record-count demonstration, not a complete resource scheduler or billing system.
Every write removes the corresponding cached value. The update test reads an old value into the cache, writes a replacement, and confirms that the next read returns the new value while the count remains unchanged. In a distributed cache, invalidation needs a versioning or delivery strategy and tests under concurrent readers. The local dictionary operation does not establish that broader consistency contract.
Add an API and storage adapter deliberately
A proposed API accepts an incident identifier and an allowed tenant selection, but obtains the principal from middleware. It passes the resolved context to the repository rather than letting a model-generated tool argument override it. Use a single repository interface for retrieval, updates, and exports so scope checks cannot be accidentally skipped by a secondary route. Error responses should avoid revealing whether an unauthorized tenant's incident exists.
For a reference database deployment, represent tenant ownership in persistent keys and enforce database-side policy with an appropriately restricted service role. PostgreSQL's row-security documentation describes role exceptions that the deployment must account for. No PostgreSQL server, container platform, or cloud identity service is installed by this example. The diagram shows the proposed integration boundary, not deployed infrastructure.
Know what the tests leave open
Eight tests exercise identifier collision, unauthorized cached access, scope denial, per-tenant capacity, invalidation, membership change, untrusted input type, and missing records. They do not cover persistence, concurrency, token expiry, impersonation, encrypted storage, or support access. Add those tests when the corresponding adapters exist rather than creating passing placeholders that do not exercise a real boundary.
Before exposing the service, test authorization failures through the actual HTTP entry point and the actual worker identity. Review the cache, log exporter, backup system, and administrative tools as data paths. A repository class can be correct while an alternative endpoint leaks the same information. The operational article turns these broader concerns into failure drills and evidence an owner can review.
Keep authorization decisions distinct from data validation errors so an API adapter can return consistent responses without leaking whether another tenant owns the requested record.