Engineering notes / 03 — Open-source tool
TenantCheck
Make tenant boundaries testable.
Explicit authorization matrices for multi-tenant HTTP APIs, with state verification for denied writes and CI-ready reports.
- Python
- pytest
- HTTP APIs
- YAML
- JSON
- JUnit
The engineering problem
A forbidden response alone does not prove that a denied write left data unchanged. Authorization tests also need to cover the combinations teams forget: anonymous users, other tenants, ownership, and role differences.
Follow the request.
- 01
Declare policy
Identities, tenants, resources, actions, outcomes
- 02
Expand the matrix
Require exactly one expectation per case
- 03
Probe & observe
HTTP requests plus authorized before/after reads
- 04
Report failures
CLI, pytest, JSON, and JUnit output
02 / Design decisions
Where the architecture earns its keep.
Policy must be explicit
TenantCheck expands declared identities, resources, and actions into test cases. Gaps, overlapping rules, and unmatched cases are configuration errors; the tool never infers intended policy from API responses.
Check the business state
For denied writes, verify_unchanged compares selected JSON pointers through an authorized observer before and after the request. That catches handlers that mutate state and then return a denial.
Bound the test runner
Targets use explicit allowed origins, redirects are refused, and credentials use environment references. Finite deadlines and response limits bound requests; writes run sequentially.
03 / Verification & scope
Failure is part of the specification.
The example compares a correctly isolated API with an intentionally broken cross-tenant implementation. Reports distinguish failed assertions from configuration and transport failures so CI can surface the right diagnosis.