mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 22:37:28 +00:00
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>
81 lines
2.9 KiB
Markdown
81 lines
2.9 KiB
Markdown
# 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:
|
|
|
|
1. connect as `admin@` (or `sysop@`), **and**
|
|
2. 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 and `pod@` 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
|
|
- `tab` switches between the **admin action log** (every ban, kill, and plugin
|
|
toggle, with who/when) and recent **`agent@` 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.
|
|
- `space` toggles a hub plugin on/off. The change is persisted (`plugin_state`
|
|
table) 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.
|