fix(auth): deny Operator statistics and enforce default authentication for every route #197
Labels
No labels
blocked
bug
enhancement
high-priority
low-priority
needs-info
needs-triage
ready-for-agent
ready-for-human
referenced
research
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gabogg/hikcentral#197
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Production reproduction (2026-09-30)
An authenticated Operator can press F5 and open the Statistics deck; the deck loads data. A read-only production check confirmed that an Operator session receives HTTP 200 with records from
GET /api/statistics/periods?granularity=day&limit=1. The same endpoint returns 401 without a session. The immediate defect is missing role authorization, not anonymous access to this endpoint.Separate read-only requests without a session returned 200 from
/openapi.json,/docs,/api-docs, and/health.POST /api/event/webhookhas no authentication dependency in the current code; it was not called in production because that would mutate door state.Code path
app/static/js/app.js:KEY_DECK_MAP.F5 = 'statistics',ROLE_ALLOWED_DECKS.operatorincludesstatistics, and the Operator UI configuration shows that deck. Shortcut checks andswitchTab()therefore allow F5 intentionally under the current client policy.app/controllers/statistics_controller.py: statistics endpoints depend onrequire_auth, which accepts any authenticated role.app/dependencies.py: the app-wideenforce_viewer_role_boundaryrestricts only Viewer sessions; it does not reject an anonymous request or restrict Operators. Per-route dependencies are therefore easy to omit on newly added routes.app/main.py: documentation routes and/healthare currently public;app/controllers/webhook_controller.pyaccepts a callback without a visible credential check.Required solution
switchTab('statistics')paths. UI hiding is only presentation; the server must decide./api/auth/me, logout, docs/OpenAPI, health, and all other routes unless a documented integration contract requires a different authenticated mechanism. The HikCentral webhook must use an independently verified machine credential/signature or equivalent trusted transport; do not rely on a browser login cookie for it.Acceptance criteria
/api/statistics/*requests; direct data requests return 403.Related: #188 Operator workspace scope, #189 Supervisor access, #72 door-command RBAC. Keep this cross-cutting access-control issue separate from those UI/features unless triage makes it a milestone prerequisite.
Joined milestone Focused operator and supervisor door operations as a prerequisite (maintainer decision, 2026-10-03). The Operator and Supervisor workspaces (#187, #188, #189) depend on correct per-role route authorization. It is still
needs-triageandhigh-priority, and since it is a live authorization gap in production it can land before the rest of the milestone.