Skip to content

feat: build operational access audit console (#589)#601

Open
DeborahOlaboye wants to merge 9 commits into
StellaBridge:mainfrom
DeborahOlaboye:feature/operational-access-audit-console
Open

feat: build operational access audit console (#589)#601
DeborahOlaboye wants to merge 9 commits into
StellaBridge:mainfrom
DeborahOlaboye:feature/operational-access-audit-console

Conversation

@DeborahOlaboye

@DeborahOlaboye DeborahOlaboye commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR implements the Operational Access Audit Console as described in issue #589. The feature adds a dedicated admin interface for reviewing operator permissions, tracking access changes, inspecting active sessions, and exporting audit data.


What was built

Backend — backend/src/api/routes/operationalAccessAudit.ts

A new Fastify route module registered at /api/v1/admin/access-audit with five endpoints:

Endpoint Method Description
/entries GET Paginated, filterable access audit log (actor, action, severity, date range, flagged-only)
/stats GET Aggregate counts by severity and action, active admin count, 24-hour recent count
/roles GET Admin member list with roles and recent permission rotation events
/sessions GET User session list with filters by user ID and status (active / expired / revoked)
/export GET Full CSV export of the access audit log (streams response with Content-Disposition header)

Access control:

  • Read endpoints require admin:audit scope
  • Export requires both admin:audit and admin:config scopes
  • All endpoints return 401 if the x-api-key header is absent, 403 if scopes are insufficient

Flagging logic:
The following actions are automatically flagged as requiring review:

  • admin.user_permission_changed
  • admin.config_changed
  • admin.retention_policy_changed
  • auth.api_key_revoked

Any entry with warning or critical severity is also surfaced as flagged regardless of action type.

Reuses existing services — no new DB migrations needed:

  • AuditService — queries the existing audit_logs table (TimescaleDB hypertable)
  • AdminRotationService — reads admin members and rotation events
  • SessionService — reads user_sessions and session_audit_log tables

Frontend — frontend/src/pages/OperationalAccessAudit.tsx

A full admin page at /admin/access-audit structured into three tabs:

Tab 1 — Access Changes

  • Filter bar: actor ID, action type (dropdown of all 8 access actions), severity, flagged-only toggle
  • Paginated entry list (50 per page) with before/after diff viewer (collapsible <details>)
  • Flagged entries highlighted with amber border
  • Severity badges (critical → red, warning → amber, info → blue)
  • CSV export button triggers an authenticated fetch download

Tab 2 — Roles & Permissions

  • Admin member cards showing name, address, email, role badges, active/inactive status, and who added them
  • Show/hide inactive toggle
  • Recent permission rotation events list (role changes and removals highlighted in amber)

Tab 3 — Sessions

  • Filter by user ID and session status
  • Session cards showing device info, IP address, creation time, last active time, expiry, and revocation reason
  • Paginated (50 per page)

UX details:

  • Reuses all existing design tokens: stellar-blue, stellar-dark, stellar-card, stellar-border, stellar-text-secondary
  • Consistent with the existing ApiKeys and AlertRoutingAdmin page patterns
  • Admin token is persisted to localStorage under the shared bridge-watch:admin-api-key:v1 key — no separate login needed if the user is already authenticated on another admin page
  • Empty states and loading indicators match the rest of the admin UI

Types — frontend/src/types/index.ts

New exported interfaces:

  • AccessAuditEntry — mirrors AuditEntry from the backend service
  • AccessAuditStats — stats shape returned by /stats
  • AdminMember — admin account with roles and activation state
  • AdminRotationEvent — role change / add / remove event
  • AccessSession — user session record
  • Supporting union types: AccessAuditAction, AccessAuditSeverity, AdminMemberRole, AccessSessionStatus, AdminRotationEventType

API service — frontend/src/services/api.ts

Five new exported functions:

  • getAccessAuditEntries(apiKey, options)
  • getAccessAuditStats(apiKey, from?)
  • getAccessAuditRoles(apiKey, activeOnly?)
  • getAccessAuditSessions(apiKey, options)
  • exportAccessAudit(apiKey, options) — uses fetch + URL.createObjectURL to trigger a real file download with the API key sent as a request header (not a query param)

Routing & navigation

  • frontend/src/App.tsx: lazy-loaded OperationalAccessAudit component at /admin/access-audit
  • frontend/src/components/MobileNav/navigation.ts: "Access Audit" added to the Operations nav group with description "Review operator roles, permissions, and access history"
  • backend/src/api/routes/index.ts: route registered at /api/v1/admin/access-audit

Closes #589

Adds a full-stack admin console for reviewing operator permissions,
access history, and sensitive administrative actions. Closes StellaBridge#589.

- Backend: new /api/v1/admin/access-audit route with /entries,
  /stats, /roles, /sessions, and /export endpoints; restricted to
  admin:audit scope; flags privilege-escalation actions (permission
  changes, config edits, key revocations)
- Frontend: OperationalAccessAudit page with three tabs — Access
  Changes (filterable, paginated audit log with diff viewer and
  flagging), Roles & Permissions (admin members + recent rotation
  events), and Sessions (active/expired/revoked user sessions)
- Export: CSV download via authenticated fetch (x-api-key header)
- Wired into App.tsx routing (/admin/access-audit) and Operations
  nav group
@DeborahOlaboye DeborahOlaboye force-pushed the feature/operational-access-audit-console branch from 19467c6 to 6f463a3 Compare June 17, 2026 20:55
@Mosas2000

Copy link
Copy Markdown
Contributor

Good work so far, try to fix the Cl checks

@DeborahOlaboye

Copy link
Copy Markdown
Contributor Author

Good work so far, try to fix the Cl checks

@Mosas2000 , Thank you. I'd work on that.

0xApana and others added 8 commits June 18, 2026 11:48
Correlates price, liquidity, supply, and bridge-health signals to surface
anomalies. Supports configurable thresholds per asset and bridge, tracks
anomaly history with duplicate suppression, and exposes explainable
detection output through API endpoints.

Closes StellaBridge#587
Closes StellaBridge#590

Adds a safe sandbox where operators can test alert routing rules
against synthetic data before enabling them in production.

Backend:
- POST /api/v1/admin/alert-routing/simulate dry-runs the routing
  evaluation logic for all active rules without dispatching anything.
  Returns per-rule match results with human-readable reasons and a
  summary (wouldDispatch, effectiveChannels, suppressionWindow).

Frontend:
- AlertSimulationSandbox page at /alert-sandbox with a two-panel layout.
- Left panel: admin token input, six scenario presets (critical bridge
  failure, token exploit, TVL anomaly, reserve drift, gas spike,
  maintenance), and a full parameter form (severity, assetCode,
  sourceType, metric, triggered value, threshold, owner, run label).
- Right panel: Results tab showing summary cards, effective channels,
  per-rule breakdown with match/no-match indicators and condition
  explanations, inactive-rule disclosure; History tab listing past runs
  stored in localStorage (up to 20), clickable to restore.
- useAlertSimulation hook manages API calls, error state, and
  localStorage persistence of simulation history.
- Nav entry added to the Operations group in MobileNav navigation.ts
  and route registered in App.tsx.
Adds a full-stack admin console for reviewing operator permissions,
access history, and sensitive administrative actions. Closes StellaBridge#589.

- Backend: new /api/v1/admin/access-audit route with /entries,
  /stats, /roles, /sessions, and /export endpoints; restricted to
  admin:audit scope; flags privilege-escalation actions (permission
  changes, config edits, key revocations)
- Frontend: OperationalAccessAudit page with three tabs — Access
  Changes (filterable, paginated audit log with diff viewer and
  flagging), Roles & Permissions (admin members + recent rotation
  events), and Sessions (active/expired/revoked user sessions)
- Export: CSV download via authenticated fetch (x-api-key header)
- Wired into App.tsx routing (/admin/access-audit) and Operations
  nav group
- Remove extra closing brace at lib.rs:5783 that prematurely closed the
  impl BridgeWatchContract block, causing unexpected delimiter error at 8670
- Fix pool_events composite primary key (id, time) so TimescaleDB
  hypertable creation on the time column succeeds without index conflict
- Lowercase github.repository in release-dry-run.yml Docker image tags
  to satisfy OCI registry requirement for lowercase image names
- Remove leftover git conflict marker (>>>>>>>) at lib.rs:1066 that was
  blocking Rust compilation
- Fix search_analytics composite primary key (id, time) to satisfy
  TimescaleDB hypertable partitioning constraint in migration 006
- Reformat relay_contract_fuzz.rs to match rustfmt style: fix loop body
  indentation, expand inline if-else arms, wrap long method chains
- Remove stray brace and conflict marker from contracts/soroban/src/lib.rs
- Run cargo fmt --all to fix formatting across all Rust source files
- Fix TimescaleDB composite primary keys in migrations 007, 008, 017, 020, 022
- Update E2E mockApi with correct bridge names, wider globs, and catch-all route
@DeborahOlaboye DeborahOlaboye force-pushed the feature/operational-access-audit-console branch from 7984c6b to e557c27 Compare June 18, 2026 10:56
@Mosas2000

Copy link
Copy Markdown
Contributor

Good implementation, fix the conflict.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build Operational Access Audit Console

4 participants