chore: v2.8.15 — Oh My Pi login sharing, omp --allow-home, Markdown Preview default, first-login password
- omp-share.js: an admin's switch (S3) runs omp's own auth broker + gateway as the host on loopback; a member's omp pane reaches it as a scoped client keyed by its pane token (clients file = live omp panes only), runs on --model agenthub/<model>, never holds a credential. - omp catalog: --allow-home, so a workspace at the account's home keeps its sessions there (they were recorded under a temp dir and dropped). - Settings → Appearance → Open Markdown as: Preview (default) or Raw, for Files/Changes, the config viewer and a chat's file panel. - First-login password change and password rules, avatar URLs, Artifacts "Mine" includes installed shared skills/plugins, a member's own hook pages.
This commit is contained in:
+69
-5
@@ -155,6 +155,10 @@ Workspaces made before server mode, or by the host account, have none.
|
||||
- An **admin** or **analyst** sees everything. Each time one of them opens a
|
||||
session a developer owns (its page, transcript, events or cost), the read is
|
||||
written to the audit log: `agenthub users audit`, or `GET /api/users/audit`.
|
||||
Entries are kept `AGENTHUB_AUDIT_DAYS` days (default 180; `0` keeps them
|
||||
all) — older ones are deleted as new ones are written, at most once an hour.
|
||||
An account's last login is kept in `users.last_login_at`, so it still shows
|
||||
after the login itself has ended.
|
||||
- `GET /api/users` (admin/analyst) lists every account with its workspaces,
|
||||
sessions, and the tokens and $ it used in the last 7 and 30 days — the
|
||||
**Administration** page in the sidebar (`/admin`; the old `/users` link
|
||||
@@ -264,7 +268,22 @@ settings file that lacks the variable falls back to `USERS_ROOT` in
|
||||
- A login lasts 30 days in the httpOnly, `SameSite=Strict` cookie
|
||||
`agenthub_sid`. Only the token's SHA-256 is stored. Logging out, a password
|
||||
change and disabling the user each end it.
|
||||
- Passwords are stored as scrypt hashes; any non-empty password is accepted (no minimum length).
|
||||
- Passwords are stored as scrypt hashes. Two bars:
|
||||
- A password an admin **gives** someone — **Add user**, a reset on the Edit
|
||||
form, `agenthub users add` — may be anything non-empty (`123` included).
|
||||
The account is then flagged `must_change_password`: after signing in it
|
||||
sees only a "Choose your own password" page, the server answers every
|
||||
other request with `403 EPWCHANGE` (only `/auth/*`, the `/me` reads and
|
||||
`POST /api/me/password` pass) and no WebSocket opens. A pane token is not
|
||||
held back — agents started before a reset keep running.
|
||||
- A password an account **picks for itself** (that page, Settings → Account,
|
||||
an admin's own on the Edit form) must pass every rule: at least 8
|
||||
characters, a lower-case and an upper-case letter, a digit, a symbol, not
|
||||
containing the username, and not the current password (`400
|
||||
EWEAKPASSWORD`, with the failed `rules`). The form ticks each rule as it is
|
||||
typed (`client/src/lib/passwordRules.ts` mirrors `passwordProblems` in
|
||||
`server/lib/auth.js`). `agenthub users passwd` and the first admin of
|
||||
`agenthub server setup` set no flag.
|
||||
Every login attempt counts before its password is checked, so attempts sent
|
||||
in parallel count too. After 10 failed logins from one address, or 30 for one
|
||||
username, in 15 minutes, further logins answer `429 ETOOMANY` until the
|
||||
@@ -307,7 +326,10 @@ everywhere". Every field is checked before any is written, so a bad email or
|
||||
a workspace the user does not own changes nothing. Every change asks for the admin's OWN
|
||||
password again — the server refuses without it (`EREAUTH`, and `ETOOMANY`
|
||||
after 10 wrong tries in 15 minutes) — an admin can never demote or disable
|
||||
themselves (`ESELF`), and each change is written to the audit log. In local
|
||||
themselves (`ESELF`), no path (the CLI included) may demote, disable or
|
||||
delete the last enabled admin (`ELASTADMIN`), and each change is written to
|
||||
the audit log. A row says **New password due** while the account still has a
|
||||
password an admin gave. In local
|
||||
mode these routes refuse (`ELOCALMODE`): there is no login to check.
|
||||
|
||||
Wherever the dashboard names a person — the sidebar's sign-out tooltip, the
|
||||
@@ -335,10 +357,10 @@ The same from the host's shell:
|
||||
|
||||
```bash
|
||||
agenthub users list
|
||||
agenthub users add <name> [--role admin|analyst|developer]
|
||||
agenthub users add <name> [--role admin|analyst|developer] # they choose their own password at first login
|
||||
agenthub users passwd <name> # ends that user's logins
|
||||
agenthub users role <name> <role>
|
||||
agenthub users disable <name> # ends that user's logins; users are never deleted
|
||||
agenthub users role <name> <role> # never the last enabled admin (ELASTADMIN)
|
||||
agenthub users disable <name> # ends that user's logins; never the last enabled admin
|
||||
agenthub users enable <name>
|
||||
agenthub users assign <workspace id> <name> # give a pre-server-mode workspace an owner
|
||||
agenthub users audit [--limit N] # who read which developer's session
|
||||
@@ -507,6 +529,48 @@ agenthub accounts pin team-key mia --tool codex # pins work as for Claude
|
||||
> **Ceiling:** a pane can read its own account's key (`$AGENTHUB_POOL_KEY`) or
|
||||
> `auth.json`, like the Claude pool's token.
|
||||
|
||||
## Oh My Pi login sharing
|
||||
|
||||
With one Linux user per account, a member's omp has its own `~/.omp` and no
|
||||
login. An admin can let every member's omp run on the HOST account's omp
|
||||
logins instead: **Settings → AI tools → Oh My Pi login sharing** (off by
|
||||
default; `PUT /api/ai-tools/omp-sharing`, audited). It uses omp's own auth
|
||||
broker and gateway (`server/lib/omp-share.js`):
|
||||
|
||||
```bash
|
||||
# as the host account: the logins to share (omp's built-in providers only)
|
||||
omp login # e.g. anthropic
|
||||
```
|
||||
|
||||
- While it is on, the dashboard runs, as the host and on loopback only,
|
||||
`omp auth-broker serve --bind=127.0.0.1:4826` over the host's `~/.omp` store
|
||||
and `omp auth-gateway serve --bind=127.0.0.1:4827 --clients=<data dir>/omp-share/clients.json`
|
||||
(ports: `AGENTHUB_OMP_BROKER_PORT`, `AGENTHUB_OMP_GATEWAY_PORT`; logs in
|
||||
`<data dir>/omp-share/`). Both tokens stay in the host's 0700 home; the
|
||||
broker's reaches only the gateway's env. A crashed daemon restarts with a
|
||||
back-off; the server stops both on shutdown, and kills ones a previous
|
||||
server left (by pid file and argv) before starting its own.
|
||||
- A member's omp pane gets one provider `agenthub` in its
|
||||
`~/.omp/agent/models.yml` (written as the member; the rest of the file is
|
||||
kept, a file that is not a YAML mapping is left alone), pointing at the
|
||||
gateway with `apiKey: AGENTHUB_PANE_TOKEN` — the NAME of the env var holding
|
||||
its pane token — and `OMP_SKIP_SETUP=1`. It runs on `--model agenthub/<model>`:
|
||||
the model picked in AgentHub, else the host's own `modelRoles.default`
|
||||
(`~/.omp/agent/config.yml`) — left to itself omp would take the provider's
|
||||
first listed model, a retired one the API answers 404 for. The clients file lists the SHA-256
|
||||
of each LIVE omp pane's token (rewritten every 15 s; the gateway re-reads it
|
||||
every 10 s), so a token stops working shortly after its pane ends, and
|
||||
turning sharing off empties it at once.
|
||||
- A scoped client token calls models only: it cannot read a credential, the
|
||||
gateway's usage or credential health, and refresh tokens never leave the
|
||||
broker. Host panes use the host's login directly and get nothing new.
|
||||
- A custom provider in the host's own `models.yml` (a 9Router, say) is not
|
||||
shared — the gateway serves omp's built-in providers.
|
||||
|
||||
> **Ceiling:** an agent can SPEND through the shared logins while its pane
|
||||
> runs; it cannot carry a login away. A member who edits the `agenthub`
|
||||
> provider out of their `models.yml` gets it back at their next omp pane.
|
||||
|
||||
## One Linux user per account
|
||||
|
||||
Every pane of a user, an agent's shell included, runs as that user's own Linux
|
||||
|
||||
Reference in New Issue
Block a user