A privileged operator console reached as `ssh admin@host`, gated by route
plus the $AGENTBBS_ADMINS allowlist (admin status is operator-granted only,
never self-assigned in-band). It is a self-contained Bubble Tea model, not a
hub plugin, so it never appears in the public menu.
Sections (PRD §6):
- Users & members: list accounts; b = suspend/ban (operators protected).
Banned accounts are blocked at the hub and pod@ routes.
- Sessions & pods: live in-memory session registry; k = disconnect.
- Moderation & audit: admin action log + agent@ transcripts (tab to switch).
- Config & plugins: runtime snapshot; space = enable/disable a plugin
(persisted; filtered from the hub on next sign-in).
Every privileged action is written to a new admin_actions audit table.
store: + banned column, admin_actions and plugin_state tables, and the
backing methods (ListUsers/SetBanned/RecentSessions/LogAdminAction/
RecentAdminActions/RecentChatsAll/DisabledPlugins/SetPluginDisabled), with
unit tests. auth: admin allowlist helpers + tests. Docs in docs/admin.md;
README M2 flipped to done.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2.9 KiB
Admin console (M2)
The admin console is a privileged operator surface reached over SSH:
ssh admin@bbs.profullstack.com
It is not a hub plugin — it never appears in the public menu. Access is gated by the route plus an operator allowlist, so a curious member who guesses the route still gets nothing.
Who is an admin
Admin status is granted only by the operator, out of band, via an environment variable — it can never be self-assigned in-session:
AGENTBBS_ADMINS="anthony,ops" # comma/space-separated account names
To open the console you must:
- connect as
admin@(orsysop@), and - present the SSH key of an account whose name is in
$AGENTBBS_ADMINS.
Anyone else gets admin@ is restricted to operators. and is disconnected.
Sections
The console is a Bubble Tea TUI. Arrow keys (or j/k) move, enter opens a
section, esc goes back, q quits, r refreshes the current list.
Users & members
Lists accounts (newest first) with kind / premium / verified flags.
b— ban/unban the selected account. Banned accounts are blocked at login on the hub andpod@routes. Operators cannot be banned.
Sessions & pods
The live view of currently-connected SSH sessions (the in-memory registry, distinct from the historical audit trail in the DB).
k— disconnect the selected session (PRD §6 "terminate live sessions"). Your own session is marked(you)and is protected.
Moderation & audit
tabswitches between the admin action log (every ban, kill, and plugin toggle, with who/when) and recentagent@transcripts for review.- Bans are taken from the Users section.
Config & plugins
- Read-only runtime snapshot: host, sandbox mode, pods engine, mail status, admin allowlist.
spacetoggles a hub plugin on/off. The change is persisted (plugin_statetable) and takes effect on each member's next sign-in — disabled plugins are filtered out of the hub menu.
Audit trail
Every privileged action is written to the admin_actions table
(admin, action, target, detail, created_at) and is visible in the
Moderation & audit section. Connection metadata continues to land in the
sessions table as before.
Persistence
| Concern | Where |
|---|---|
| Suspensions | users.banned |
| Plugin enable/disable | plugin_state(id, disabled) |
| Admin action log | admin_actions |
| Session audit trail | sessions (historical) |
| Live sessions | in-memory registry (killable) |
Not yet (future milestones)
- AgentAd ops (creative approval, ledgers) — lands with M5.
- Live operator takeover of an
agent@chat — the transcripts are reviewable here today; interactive takeover is future work. - Per-plugin config editing beyond enable/disable.