Skip to main content

Auditor Session Countdown UI

Status

Implemented in OP-066n.

  • ADR references: ADR-0014 auditor export and redaction controls.
  • Runtime references: OP-057 auditor session enforcement runtime.
  • Task board references: OP-066n auditor session countdown/expiry notice.

Problem Statement

Auditors need visible confirmation that their read-only access is time-boxed. The console also needs to warn as the OP-057 access window nears expiry without confusing that window with JWT/session-token expiry.

Architectural Intent

The backend remains authoritative. /api/v1/session now returns the redaction-safe active_auditor_session summary only after the OP-057 auditor access gate passes. The frontend uses that access-window metadata for the countdown and never derives auditor access from token expires_at.

What Was Implemented

  • Added active_auditor_session to the authenticated session response for auditor requests with an active OP-057 session.
  • Added remaining_seconds to auditor session summaries.
  • Added auditor.session_status.read audit records when auditors read their active session status through /api/v1/session.
  • Added a global console header notice for auditor sessions with active, warning, and expired states.
  • Hid the notice for non-auditor roles even if a malformed fixture includes auditor session metadata.

Components Involved

  • poc/ingest_api/http_routes.py
  • poc/ingest_api/auditor_session_service.py
  • poc/ingest_api/api_models.py
  • frontend/src/lib/api.ts
  • frontend/src/components/app-shell.tsx
  • frontend/src/test/oneprotect-ui.test.tsx
  • tests/test_auditor_session_enforcement.py
  • tests/test_frontend_response_contracts.py

APIs / Events / Schemas

  • GET /api/v1/session
  • specs/openapi.yaml
  • No event payload changes.

Deployment Notes

No Helm, Terraform, AWS, ECR, or docs deployment changes were made. This is a backend contract and console UI update inside the existing application services.

Security / Tenant Isolation

Auditor access still fails closed in the auth layer before protected route handlers run. The UI receives only tenant-scoped, redaction-safe session metadata: session identifiers, auditor actor/name/org, status, validity window, creator, revocation metadata, and remaining lifetime. The response does not include secrets, bearer tokens, raw evidence, or raw export content.

Validation Steps

UI Validation

  1. Sign in or mock a backend session with role = auditor.
  2. Confirm the console header shows the remaining auditor access window.
  3. Confirm the notice changes to an expired state when the access window is no longer active.
  4. Confirm tenant admins, operators, and system admins do not see the auditor countdown.

API Validation

.venv/bin/python -m unittest tests.test_auditor_session_enforcement tests.test_frontend_response_contracts

Smoke Validation

npm --prefix frontend test -- --run
make validate-contracts
make typecheck-python
make lint
make test-sqlite
make docs-build

Known Limitations

  • Tenant settings for auditor duration bounds are still not exposed in the console.
  • Auditor session administration remains the existing API path; this task does not add a session-management UI.
  • Reloading after an already-expired auditor access window still receives the OP-057 fail-closed 403 from the backend.

Follow-Up Work

  • Tenant settings UI for auditor access bounds if scoped separately.
  • Richer auditor session administration table if scoped separately.

Acceptance Criteria Mapping

Acceptance criterionEvidence
Auditor sees remaining session timefrontend/src/components/app-shell.tsx renders active_auditor_session from /api/v1/session
Warning before expiryHeader notice changes styling when remaining lifetime is 15 minutes or less
Expired notice on timeoutHeader notice flips to Auditor access expired when the access window reaches zero
Uses backend access-window metadatafrontend/src/lib/api.ts maps active_auditor_session; docs and skills forbid using JWT expiry for this UX
Backend contract is testedtests/test_auditor_session_enforcement.py and tests/test_frontend_response_contracts.py
Frontend role behavior is testedfrontend/src/test/oneprotect-ui.test.tsx covers auditor, expired, and non-auditor rendering