Scope Security activity to the signed-in Gitea identity #1462

Closed
opened 2026-08-27 07:52:52 +00:00 by timmy · 0 comments
Owner

Problem

Security activity is authenticated but globally listed. After the dashboard is used by a different upstream Gitea identity, that identity can see the previous principal’s device labels and destructive-action targets. Sessions, passkeys, devices, and push state are already principal-scoped; the journal is not.

Slice

Persist immutable principal_id ownership on journal events, pass it through every authenticated writer, and filter list/cursor pagination by the current session principal. Existing unattributed rows must remain invisible rather than being claimed by a future identity. Failed pre-authentication token alerts remain global.

Acceptance

  • Interleaved events for two principals never cross list or cursor boundaries.
  • Switching upstream identity and reauthenticating cannot reveal prior security events.
  • Every authenticated journal writer records the immutable principal ID.
  • Legacy rows without a principal are invisible to authenticated principals.
  • Encryption, reservation/finalization, retention, authentication, and no-store behavior remain green.

Evidence

src/security_event_store.py has no principal column or list predicate; GET /api/v1/security-events calls the global list. No open/closed issue title or recent commit implements journal principal ownership; #493 created the journal, #1118 encrypted it, #1372 bound sessions, and #1454 scoped device revocation only.

## Problem Security activity is authenticated but globally listed. After the dashboard is used by a different upstream Gitea identity, that identity can see the previous principal’s device labels and destructive-action targets. Sessions, passkeys, devices, and push state are already principal-scoped; the journal is not. ## Slice Persist immutable `principal_id` ownership on journal events, pass it through every authenticated writer, and filter list/cursor pagination by the current session principal. Existing unattributed rows must remain invisible rather than being claimed by a future identity. Failed pre-authentication token alerts remain global. ## Acceptance - Interleaved events for two principals never cross list or cursor boundaries. - Switching upstream identity and reauthenticating cannot reveal prior security events. - Every authenticated journal writer records the immutable principal ID. - Legacy rows without a principal are invisible to authenticated principals. - Encryption, reservation/finalization, retention, authentication, and no-store behavior remain green. ## Evidence `src/security_event_store.py` has no principal column or list predicate; `GET /api/v1/security-events` calls the global list. No open/closed issue title or recent commit implements journal principal ownership; #493 created the journal, #1118 encrypted it, #1372 bound sessions, and #1454 scoped device revocation only.
timmy self-assigned this 2026-08-27 07:52:52 +00:00
timmy closed this issue 2026-08-27 08:22:11 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stackchain/stackchain-dashboard#1462
No description provided.