Kairo-Jinkendo/docs/architecture/Kairo_Tenant_Invariants_v0.1.md
Lars db06af0489
All checks were successful
Deploy Development / deploy (push) Successful in 47s
Test Suite / pytest-backend (push) Successful in 42s
Test Suite / lint-backend (push) Successful in 2s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 18s
Test Suite / playwright-smoke (push) Successful in 12s
AP0.7: Tenant Hardening, Actor Directory und Data Layer Minimum
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 07:25:01 +02:00

63 lines
2.5 KiB
Markdown

# Kairo Tenant-Invarianten v0.1
**Status:** verbindlich für Sprint 0 / AP0.7+
**Stand:** 2026-07-05
---
## Zweck
Dieses Dokument legt Mandanten-Invarianten für Kairo fest, damit fachliche Module tenant-sicher bleiben und Cross-Tenant-Leaks vermieden werden.
Bei Abweichungen: Architecture Decision Proposal.
---
## Invarianten
| # | Invariante | Umsetzung in Kairo |
|---|------------|-------------------|
| 1 | Jede fachliche Tabelle hat `tenant_id`, sofern nicht global | `initiatives`, `actions`, `action_assignments`, `actors` — alle mit `tenant_id` |
| 2 | `tenant_id` kommt aus TenantContext, nicht aus Client-Body | Router nutzen `ctx.tenant_id` aus `require_tenant_context` / `require_capability` |
| 3 | Jede fachliche Query filtert nach `tenant_id` | Services und Data Layer: `WHERE tenant_id = %s` |
| 4 | Fremde Objekt-IDs → `404`, nicht `403` | Initiatives, Actions, Actors: Cross-Tenant-Zugriff liefert 404 |
| 5 | Actor-Zuweisungen nur im selben Tenant | `_actor_in_tenant()` in Services; Assignment-Tests |
| 6 | User ≠ Actor | Human Actor verknüpft via `actors.user_id`; Assignments an `actor_id` |
| 7 | Agenten/Arbeitsgruppen/externe Systeme sind tenant-scoped Actors | `actors.tenant_id` + `actor_type` |
| 8 | Audit Events enthalten mindestens `tenant_id` | `log_audit(..., tenant_id=...)` |
| 9 | Neue fachliche Tabellen: explizite Tenant-Entscheidung | Nummerierte Migration + Doku-Ergänzung |
| 10 | Router ohne eigene Mandantenlogik | Delegation an Services (Write) und Data Layer (Read-Aggregation) |
---
## Geprüfte Bereiche (AP0.7)
| Bereich | Ergebnis |
|---------|----------|
| `initiatives` CRUD | ✓ tenant_id aus Context |
| `actions` CRUD | ✓ tenant_id aus Context |
| `action_assignments` | ✓ tenant_id + Actor-Validierung |
| `actors` Directory | ✓ nur aktiver Tenant |
| `/api/actions/me/open` | ✓ via Data Layer, actor-scoped |
| `/api/workspace/*` | ✓ Data Layer, tenant-scoped |
| Cross-Tenant Tests | ✓ `test_initiatives_actions`, `test_ap07` |
---
## Anti-Patterns (verboten)
- `tenant_id` aus Request-Body übernehmen ohne Membership-Prüfung
- Listen ohne `tenant_id`-Filter
- Cross-Tenant-Existenz via 403 verraten
- User-ID direkt in Assignments statt Actor-ID
- Aggregations-SQL in Routern
- Frontend-Widgets mit fachlicher KPI-Berechnung statt Data-Layer-Endpoints
---
## Referenzen
- `docs/architecture/Kairo_Sprint0_Principle_Gate_v0.1.md` (G-01, G-02, G-03)
- Shinkan: Access Layer / tenant-sichere Queries
- AP0.7 Abschlussbericht: `docs/sprints/Sprint0_AP0_7_Completion_Report_v0.1.md`