T0-A Result — Security and Authorization Foundation
Exact tree state
| Repo |
Branch |
Base SHA (pre-change HEAD) |
Working tree |
scola-fe-v2 |
develop |
b48ca63859d3d822f22572dc76a08afbe4f2f653 |
dirty — T0-A FE + execution docs uncommitted |
custom_addons_scola/gcgscola |
main |
2ff6ac7cb41810bbc3b66821cdad004b52d1658a |
dirty — T0-A BE uncommitted |
No commit was created in this task (awaiting explicit user request).
Architecture decisions implemented
- Active role is server-enforced acting context (
compute_permissions uses resolve_role_id / scola_role only; no inactive-role union).
- Assigned roles remain eligibility; switch validates authoritative assignment.
- CBT group supplements only when active role ∈
CBT_SUPPLEMENT_ACTIVE_ROLES (fail-closed).
- Route registry uses exact-then-longest-prefix matching; duplicate conflicting prefixes fail validation; unknown registry miss → no capability grant.
- Mail-tracking retained with model/action allowlist, native ACL + company scope before
.sudo(), stable denial payload, audit log line.
- FE
can() / accessContract fallback uses active role only (no multi-role union fallback).
Defect status before → after
| ID |
Before |
After |
Evidence status |
| STAB-007 |
Open (union permissions) |
Code fixed, runtime verification pending |
Unit suite PASS; Golden Tenant multi-role runtime = PENDING T0-B RUNTIME CERTIFICATION |
| STAB-008 |
Open (first-prefix shadow) |
Code fixed, runtime verification pending |
Unit + FE parity PASS; served-bundle registry crawl = PENDING T0-B RUNTIME CERTIFICATION |
| STAB-005 |
Open (arbitrary model+res_id) |
Code fixed, runtime verification pending |
Policy unit PASS; ORM existence-leak / cross-company live = PENDING T0-B RUNTIME CERTIFICATION |
| AUTH-001 |
Open |
Code fixed, runtime pending |
Tied to STAB-007 |
| AUTH-002 |
Open |
Inventory only (not domain-refactored) |
Downstream |
| AUTH-003 |
Open |
Code fixed, unit pending runtime |
Tied to STAB-008 |
| AUTH-004 |
Open |
Partial (resolver deny on miss; full extractor parity open) |
Contained / T1 |
| AUTH-009 |
Open (mail-tracking slice) |
Code fixed for mail-tracking; other elevations open |
STAB-005 slice only |
| AUTH-011 |
Open |
Partial (switch + denial + mail-tracking logs) |
Downstream for universal mutation audit |
| AUTH-012–014 |
Open |
Not closed |
T0-B / T1 |
None of STAB-005/007/008 are Closed with evidence — runtime Golden Tenant certification is absent.
Files changed
Backend (gcgscola)
scola_core/services/auth_capabilities.py
scola_core/controllers/auth.py
scola_core/models/ir_http.py
scola_core/controllers/core_reference_api.py
scola_core/services/mail_tracking_access.py (new)
scola_platform_support/api_route_access.py
scola_core/tests/test_active_role_enforcement_unit.py (new)
scola_core/tests/test_mail_tracking_access_unit.py (new)
scola_core/tests/test_auth_capabilities_unit.py
scola_core/tests/test_auth_payload_contract_unit.py
scola_platform_support/tests/test_api_route_access_unit.py
Frontend (scola-fe-v2)
src/access/apiRouteAccessRegistry.js
src/access/accessContract.js
src/stores/auth.store.js
tests/unit/access/feBackendApiRouteAccessParity.spec.js
docs/release-readiness/execution/* (plan, inventory, this result)
Tests executed
| Suite |
Result |
Count |
test_auth_capabilities_unit.py |
PASS |
73 |
test_active_role_enforcement_unit.py |
PASS |
12 |
test_auth_payload_contract_unit.py |
PASS |
6 |
test_mail_tracking_access_unit.py |
PASS |
10 |
test_api_route_access_unit.py |
PASS |
53 |
| FE vitest access suites (parity/wave2/accessContract/gap01) |
PASS |
41 |
py_compile (changed BE modules) |
PASS |
— |
| FE eslint (changed JS) |
PASS |
— |
npm run check:capability-diff |
PASS |
— |
npm run type-check |
PASS |
— |
| Golden Tenant / live multi-role API |
NOT RUN |
marked pending |
PASS / FAIL / PENDING summary
| Status |
Count (this tranche) |
| PASS (unit/static QC) |
195+ assertions across suites above |
| FAIL |
0 (required security unit tests) |
| PENDING T0-B RUNTIME CERTIFICATION |
STAB-005/007/008 acceptance runtime matrix; AUTH-014 evidence |
Remaining risks
- Odoo ACL group residual: assigned roles still sync all role groups for ORM ACL; controller capability gate is reduced, but model-level ACL may still be broader than active persona until STAB-017 / domain ACL work.
- AUTH-004: unregistered
/api controllers without registry rows still skip capability gate (resolve → None). Fail-closed only for registered mismatches / unknown after registration policy.
- Optional-domain
.view/.manage collapse unchanged (inventory → downstream).
- Concurrent tabs: one
scola_role on user record — last switch wins globally; FE store in other tabs can be stale until refresh (backend still authoritative).
- Mail-tracking allowlist may need expansion when product wires more AuditLogViewer models — prefer explicit allow over silent reopen.
Deferred
| Item |
To |
| Golden Tenant + fresh multi-role runtime matrix |
T0-B |
| Package suite separation / install topology |
T0-C / T0-U05–U06 |
| Domain capability atomicization (payroll, counseling, …) |
T1+ domain tranches |
| Universal mutation audit (AUTH-011 full) |
T1 |
| W01/W02/W05 |
Out of scope (not started) |
| Navigation redesign |
Out of scope |
Adversarial self-review
| Attack / failure mode |
Mitigation in T0-A |
Residual |
| Privilege escalation via inactive role union |
Permissions from active role only; FE fallback no longer unions roles |
ORM ACL residual |
| Stale-role authority after switch |
DB scola_role + recompute on every ir.http gate |
Stale FE menu until refresh |
| Route shadowing (fee-enrollments, modul-ajar) |
Longest-prefix resolver + regression tests |
Method-level rules still TBD |
| Cross-company mail-tracking |
Company scope check before elevation |
Live ORM proof pending T0-B |
| Arbitrary model/res_id |
Allowlist + native ACL + identical denial |
Allowlist maintenance |
| False-green tests |
Required unit tests not skipped; runtime cases marked PENDING not PASS |
Must not claim release-ready |
Doc compliance
- Mode: server
- Workspace root:
/home/scola/odoo
- Repos:
scola-fe-v2, custom_addons_scola/gcgscola
- Docs read: release-readiness 04/08/09/10 (T0), AI guidelines development/governance/architecture-api