Context
PR #2000 closed wave-3 critical findings C6 (AuditTrailController::index/show) and C7 (SearchTrailController::index/show) by restricting them to the admin group. That is the safer default and is what should ship now.
However, admin-only is too blunt for two legitimate use cases:
- AVG/GDPR Article 30 review — a privacy officer / DPO usually has to read the verwerkingsregister + audit trail for compliance reviews, without being granted server administrator rights.
- Incident response — a security analyst reviewing search-trail patterns (who searched for what) does not need admin write rights on the rest of OpenRegister.
Proposal
Allow admins to grant a configurable group (default name auditors) read-only access to the gated audit-trail and search-trail surfaces:
AuditTrailController::index, show, verwerkingsregister, inzageverzoek, verify
SearchTrailController::index, show, statistics, popularTerms, activity, registerSchemaStats, userAgentStats
Write/destructive surfaces (clearAll, export) stay strict-admin.
Implementation sketch
- Add a
auditor_group setting in lib/Settings/Admin.php + DI-readable via IAppConfig (default: auditors).
- Extend
requireAdmin() to requireAuditorOrAdmin() on the read surfaces; pass through the same 401/403 contract.
- Reuse the existing
NotificationHistoryController group-membership pattern.
- Tests: add
IsAuditorButNotAdmin cases to the unit suites.
Out of scope
Per-schema scoping (auditor-X can only see schema-Y) — that is Option B from the wave-3 triage and would require RBAC layer changes; track separately.
Refs: PR #2000, wave-3 triage findings C6 + C7.
Context
PR #2000 closed wave-3 critical findings C6 (
AuditTrailController::index/show) and C7 (SearchTrailController::index/show) by restricting them to the admin group. That is the safer default and is what should ship now.However, admin-only is too blunt for two legitimate use cases:
Proposal
Allow admins to grant a configurable group (default name
auditors) read-only access to the gated audit-trail and search-trail surfaces:AuditTrailController::index,show,verwerkingsregister,inzageverzoek,verifySearchTrailController::index,show,statistics,popularTerms,activity,registerSchemaStats,userAgentStatsWrite/destructive surfaces (
clearAll,export) stay strict-admin.Implementation sketch
auditor_groupsetting inlib/Settings/Admin.php+ DI-readable viaIAppConfig(default:auditors).requireAdmin()torequireAuditorOrAdmin()on the read surfaces; pass through the same 401/403 contract.NotificationHistoryControllergroup-membership pattern.IsAuditorButNotAdmincases to the unit suites.Out of scope
Per-schema scoping (auditor-X can only see schema-Y) — that is Option B from the wave-3 triage and would require RBAC layer changes; track separately.
Refs: PR #2000, wave-3 triage findings C6 + C7.