Deferred finding from the PR #234 access-control audit (internal/plans/pr234-dci-access-audit-findings.md, Finding 1). Re-verified live on 19.0 on 2026-07-24 — the "another PR" expected to cover this never materialized, so filing it for tracking.
Finding
spp_cel_domain/security/ir.model.access.csv:2 revokes base.group_user read on the entire spp.data.value cache (0,0,0,0), not just DCI-sensitive rows. read_values() (spp_cel_domain/models/data_value.py:433) runs a plain self.search(domain) with no .sudo(), so it executes under the caller's ACL.
DRIMS has store=True KPI computes that call read_values() in the operating user's context:
spp_drims/models/hazard_incident.py — _compute_drims_kpis (~173/193), _compute_drims_stock_kpis (~217/238/243), _compute_drims_return_kpis (~391/405).
DRIMS groups (spp_drims/security/groups.xml) imply no cel_domain group and ship no ACL on model_spp_data_value. Impact: a DRIMS-only officer editing a donation/picking/return triggers a stored KPI recompute → AccessError → core DRIMS write workflow breaks. Users who also hold a programs role get cel_domain_viewer and are unaffected, so severity depends on whether DRIMS-only roles exist in a deployment.
Not caught by tests (DRIMS tests run as superuser). Wider blast radius to sweep: spp_drims/models/donation_line.py:159, returns.py:327,479, donation.py:538, stock_picking.py:317.
Design decision needed
- Option A (preferred in the audit) — scope the protection: revert the blanket revoke; protect only DCI-sensitive rows via a record rule / dedicated group keyed on DCI-backed
variable_name/source_type. Matches the original goal (hide disability/health values) without nuking PMT scores, household size, eligibility features, DRIMS KPIs.
- Option B — sudo the readers:
.sudo() the DRIMS cache reads (precedent: spp_studio_api_v2/services/variable_value_service.py:87,150; spp_cel_domain/models/data_cache_invalidation.py:85,132,198). Smaller diff but leaves the blanket revoke, so every base-user ORM reader must be audited forever.
Also: if the blanket revoke stays, docs/principles/access-rights.md:60-77 (documents spp.data.value as readable by all internal users) must change too. A with_user(group_drims_*) regression test should be added.
Source: internal/plans/pr234-dci-access-audit-findings.md. Related: #234, #235.
Deferred finding from the PR #234 access-control audit (
internal/plans/pr234-dci-access-audit-findings.md, Finding 1). Re-verified live on19.0on 2026-07-24 — the "another PR" expected to cover this never materialized, so filing it for tracking.Finding
spp_cel_domain/security/ir.model.access.csv:2revokesbase.group_userread on the entirespp.data.valuecache (0,0,0,0), not just DCI-sensitive rows.read_values()(spp_cel_domain/models/data_value.py:433) runs a plainself.search(domain)with no.sudo(), so it executes under the caller's ACL.DRIMS has
store=TrueKPI computes that callread_values()in the operating user's context:spp_drims/models/hazard_incident.py—_compute_drims_kpis(~173/193),_compute_drims_stock_kpis(~217/238/243),_compute_drims_return_kpis(~391/405).DRIMS groups (
spp_drims/security/groups.xml) imply no cel_domain group and ship no ACL onmodel_spp_data_value. Impact: a DRIMS-only officer editing a donation/picking/return triggers a stored KPI recompute →AccessError→ core DRIMS write workflow breaks. Users who also hold a programs role getcel_domain_viewerand are unaffected, so severity depends on whether DRIMS-only roles exist in a deployment.Not caught by tests (DRIMS tests run as superuser). Wider blast radius to sweep:
spp_drims/models/donation_line.py:159,returns.py:327,479,donation.py:538,stock_picking.py:317.Design decision needed
variable_name/source_type. Matches the original goal (hide disability/health values) without nuking PMT scores, household size, eligibility features, DRIMS KPIs..sudo()the DRIMS cache reads (precedent:spp_studio_api_v2/services/variable_value_service.py:87,150;spp_cel_domain/models/data_cache_invalidation.py:85,132,198). Smaller diff but leaves the blanket revoke, so every base-user ORM reader must be audited forever.Also: if the blanket revoke stays,
docs/principles/access-rights.md:60-77(documentsspp.data.valueas readable by all internal users) must change too. Awith_user(group_drims_*)regression test should be added.Source:
internal/plans/pr234-dci-access-audit-findings.md. Related: #234, #235.