Accounts, Roles & Audit
Every request to the test runner goes through the gateway, which owns authentication, role enforcement, and the audit trail. This page covers logging in, the three roles, the admin Users tab, the Activity audit log, and how cases are attributed to their author.
|
At a glance
|
Auth is provided by the gateway (Environments & the Gateway). The store is a
SQLite file (scripts/auth_db.py → run-reports/test_runner.db) on the
persistent volume, so accounts and the audit log survive redeploys.
|
Logging In
On first load the SPA shows a full-screen login overlay (everything else is
hidden until isAuthed). Submitting the form calls POST /api/auth/login:
-
On success the server returns a
tokenplus the user record; the SPA stores the token and sends it asAuthorization: Bearer <token>on every subsequent call. -
Sessions use a sliding TTL — each authenticated request refreshes
last_seen; an idle session past the TTL is pruned and returns401. -
Logout (
POST /api/auth/logout) deletes the server-side session. -
GET /api/auth/meechoes the current identity (username + role).
|
Login is rate-limited: after 5 failed attempts within 60s (keyed by
|
Bootstrap Account — Rotate It
On first boot the gateway seeds a single admin from config
(admin / admin by default). This is a convenience for the very first login
and is a known weak default on production deployments.
Change the bootstrap password (or replace the account) before
exposing the runner. Log in as admin, create your own admin via the
Users tab, then reset or delete the default. There is no forced password
change on first login.
|
Roles & Capabilities
The role is stored on the user row and constrained at the schema level
(role IN ('admin','editor','viewer')). Capabilities:
| Capability | admin | editor | viewer |
|---|---|---|---|
Log in; view Dashboard, Tests, Runner, Notes, Learning |
✓ |
✓ |
✓ |
Open a case in the Editor (read YAML) |
✓ |
✓ |
✓ |
Run a test / batch ( |
✓ |
✓ |
— |
Create / edit / delete cases; regenerate, reimport |
✓ |
✓ |
— |
Import from TestRail / upload YAML |
✓ |
✓ |
— |
Assign cases to a project |
✓ |
✓ |
— |
Settings tab |
✓ |
— |
— |
Users tab (manage accounts) |
✓ |
— |
— |
Workers tab (stands / profiles) |
✓ |
— |
— |
Activity tab (audit log) |
✓ |
— |
— |
In the SPA this maps to two guards: canRun() (true for admin + editor)
gates every run/edit/import/delete button, and isAdmin() gates the four
admin-only tabs. A viewer sees the data tabs with no action buttons —
pure read/observe. The admin tabs and their endpoints are additionally
server-enforced via require_role("admin").
New users default to the editor role when none is supplied.
|
Users Tab (admin)
The Users tab lists every account (GET /api/users) and exposes full
lifecycle management:
| Action | Endpoint |
|---|---|
Create user (username, password, role) |
|
Change role / enable / disable |
|
Reset password |
|
Delete user |
|
-
Disable flips the
disabledflag and clears the user’s sessions (immediate logout) without losing the account. Enable restores access. -
Delete removes the account and its sessions outright.
|
Last-admin guard
You cannot delete the final active admin — The guard covers deletion only. Demoting or disabling the last admin is not blocked, so rotate the bootstrap account by adding a new admin first, then removing the old one. |
Activity Audit Log
The Activity tab (admin-only) reads GET /api/activity — a reverse-chronological
feed backed by the activity table. Each row captures
ts, username, role, action, method, path, target, detail, ip, status.
Filter by username or action (query params), with limit / offset
paging. Auditing is best-effort and never blocks the request path; the table
is bounded (oldest rows pruned past a retention cap).
Recorded actions include:
action |
Logged on |
|---|---|
|
Successful, rejected, and rate-limited sign-ins (with |
|
A single run, a batch, or a pasted-XML run is triggered ( |
|
Account management from the Users tab |
|
Admin maintenance actions |
Case Attribution & History
Separately from the activity feed, each YAML case carries authorship metadata
in the case_meta table (created_by / created_at, edited_by / edited_at)
plus an append-only case_history log. The runner records an event on every
case mutation:
-
created/importedset the original author once (preserved on later edits). -
edited/reimportedupdateedited_by+edited_atand append history. -
deletedappends history but does not overwrite the creator.
The Editor surfaces the Author and last-editor on each case, so you can see who created or last touched a YAML and trace its full edit history — useful when a converted case behaves unexpectedly after a manual edit.
See Also
-
Environments & the Gateway — the gateway that terminates auth and routes to stands.
-
Settings — admin-only environment configuration.
-
REST API — full endpoint reference, including the auth and user routes.