Sync the self-hosting stack
This commit is contained in:
@@ -73,6 +73,13 @@ and different accounts on the far end. The choice is made before the shell opens
|
||||
the session and in the audit trail, and every route is held to the same limits: the same idle and
|
||||
duration ceilings, the same recording, the same retention policy.
|
||||
|
||||
**And, on Windows, a screen.** Where the terminal gives you a shell on an enrolled machine, remote
|
||||
desktop gives you what the person sitting at it is looking at. It reuses the terminal's permission
|
||||
model and adds one thing the terminal has no equivalent of: **the person at the machine is always
|
||||
told.** Each organisation chooses a standing banner or a request they must answer, there is no third
|
||||
choice and no way to switch the notice off, and the session ends if the notice cannot be kept in
|
||||
front of them. Nothing of the screen is recorded — see [The agent](#the-agent).
|
||||
|
||||
**Documents.** A conversation accumulates what the assistant writes: reports and runbooks in
|
||||
Markdown, diagrams in Mermaid, tabular data as a workbook. What it writes is always a *source*, and
|
||||
Jarvis renders the file on download — PDF and Word from prose, Excel and CSV from a workbook, HTML
|
||||
@@ -290,14 +297,23 @@ marked installed by a backfill — so you will never see the install screen. Not
|
||||
|
||||
All three are the kind that produce confusing symptoms rather than clean errors.
|
||||
|
||||
- **Forward the WebSocket upgrade.** Two separate sockets ride `JARVIS_PORT`: the chat, on
|
||||
`/socket.io/`, and enrolled agents, on `/api/agents/ws`. Neither falls back to plain HTTP. Without
|
||||
- **Forward the WebSocket upgrade.** Three separate sockets ride `JARVIS_PORT`: the chat, on
|
||||
`/socket.io/`; enrolled agents, on `/api/agents/ws`; and, for remote desktop only, one media
|
||||
connection per live session on `/api/agents/ws/desktop`. None falls back to plain HTTP. Without
|
||||
the upgrade the chat does not lose streaming — it never connects at all, and since the prompt
|
||||
itself travels over that socket, nothing sends. Presence and in-chat approvals go with it, and no
|
||||
agent can connect.
|
||||
itself travels over that socket, nothing sends. Presence and in-chat approvals go with it, no
|
||||
agent can connect, and no screen can be watched. A proxy that forwards `/api/agents/ws` by exact
|
||||
path rather than by prefix will pass the first two and silently fail the third, which reads as
|
||||
"remote terminal works and remote desktop does not".
|
||||
- **Give it a long read timeout** — 300s or so. A reasoning model can go 90+ seconds without emitting
|
||||
a byte, and a 60s default cuts the response mid-stream. The client sees a connection reset rather
|
||||
than a timeout, which reads like a bug in Jarvis.
|
||||
than a timeout, which reads like a bug in Jarvis. The desktop media socket is legitimately silent
|
||||
for far longer than that — a viewer whose tab is hidden pauses the stream, and nothing is sent
|
||||
until the tab comes back — but it does not need a longer timeout, because the api pings it on a
|
||||
beat of its own and a WebSocket ping is traffic as far as your proxy's read timer is concerned.
|
||||
A proxy that drops idle **upgraded** connections on a separate, shorter clock is the one
|
||||
configuration that breaks this; on nginx that is `proxy_read_timeout` and the ping already
|
||||
covers it.
|
||||
- **Let uploads through.** Attaching or uploading a file posts it to `/api/uploads/`, up to 10 MB
|
||||
each, and an image uploaded to a workspace travels with a copy of up to 3 MB prepared for the
|
||||
model. Your proxy must accept request bodies of at least **13,376 KiB** on that path (nginx:
|
||||
@@ -416,16 +432,42 @@ Four things worth knowing about it:
|
||||
recorded by default, encrypted under `VAULT_MASTER_KEY` and deleted on a retention policy you set
|
||||
under **Settings → Organization → Terminal sessions**. Turning recording off stops the transcript,
|
||||
never the audit entry.
|
||||
- **It carries a remote desktop, on Windows.** The same permission model, one level up: a person
|
||||
with the right watches the signed-in session's screen from the browser. **Nobody is ever watched
|
||||
invisibly.** Each organization picks one of two policies under **Settings → Organization → Remote
|
||||
desktop** — a banner that stands on the screen for the whole session, or a prompt the person must
|
||||
answer before anything is captured, which auto-accepts only when nobody is signed in. There is no
|
||||
third option and no way to turn the notice off, which is the one decision in this feature that is
|
||||
not configurable. The session ends the moment the banner cannot be kept visible. Nothing of the
|
||||
screen is stored: there is no recording, no thumbnail and no still, so the audit entry is the
|
||||
whole of the trail. Linux and macOS are not supported yet, and a session opened against one is
|
||||
refused rather than silently downgraded.
|
||||
|
||||
**What an enrolled agent can do.** Inventory the machine, run commands, read, write and fetch files,
|
||||
list and control services, list processes, update itself, and carry that shell. It runs as root on
|
||||
Linux and macOS and as LocalSystem on Windows, deliberately — its purpose is to administer the
|
||||
machine.
|
||||
list and control services, list processes, update itself, carry that shell, and — on Windows — show
|
||||
its screen. It runs as root on Linux and macOS and as LocalSystem on Windows, deliberately: its
|
||||
purpose is to administer the machine. Watching a screen is the one thing it cannot do from there,
|
||||
because a Windows service has no access to the window station a person is signed in to; capture runs
|
||||
in a short-lived helper the service launches into that session, and that helper is also what draws
|
||||
the notice.
|
||||
|
||||
What the **assistant** does with that reach is bounded by the autonomy policy and the approval gates
|
||||
above. **The interactive shell is not.** There is no command to inspect before a shell opens, so the
|
||||
risk ceiling has nothing to weigh; it is gated instead by a permission and a per-machine switch on
|
||||
the grant. Decide who holds those before enrolling anything you care about.
|
||||
above. **The interactive shell and the remote desktop are not.** There is no command to inspect
|
||||
before a shell opens and no command at all behind a screen, so the risk ceiling has nothing to
|
||||
weigh; both are gated instead by a permission and a per-machine switch on the grant, and neither is
|
||||
ever opened by the assistant — a person opens them. Decide who holds those before enrolling anything
|
||||
you care about. The desktop has one protection the shell does not, and it is not a permission: the
|
||||
person sitting at the machine is told, every time, for as long as it lasts.
|
||||
|
||||
**Being told is not the same as being able to stop it, and the difference matters.** The notice is
|
||||
click-through on purpose — it takes no click, it has no menu and it has no keyboard — so that it can
|
||||
never sit between somebody and the work they are doing, and so that it cannot be closed by accident
|
||||
or by a script. The cost of that choice is that the person at the keyboard cannot dismiss the viewer
|
||||
from the notice itself. Their ways out are elsewhere: refusing the prompt under the ask policy,
|
||||
before anything is captured; signing out, which ends the session with it; or an administrator
|
||||
turning the feature off for the instance. What the banner guarantees is that watching is never
|
||||
secret. It does not guarantee consent once it has started, and under the banner policy it is not
|
||||
asking for any.
|
||||
|
||||
## Things worth knowing before you trust it with production
|
||||
|
||||
@@ -468,6 +510,23 @@ These are deliberate and documented rather than surprises waiting to be found.
|
||||
something to watch rather than something to assume. Two API processes have been run together
|
||||
against one database and one Redis, and the manifests are published, but that is not the same
|
||||
thing as your machines depending on it.
|
||||
- **Remote desktop is the newest thing here, and its way out is a switch rather than a rollback.**
|
||||
The api and the web roll back by pinning a digest, but an agent has already replaced its own binary
|
||||
on every machine it runs on by the time you want it back — so the control that matters is
|
||||
**Settings → Platform → Agents → Remote desktop**. Turning it off refuses new sessions and ends
|
||||
every live one within 15 seconds, fleet-wide, without touching the interactive shell or anything
|
||||
else the agent does. Know where it is before you need it. Two consequences worth holding onto: no
|
||||
part of a screen is ever written anywhere, so if an incident needs a record of what was *seen*,
|
||||
this feature cannot produce one after the fact. What the session record does hold is more than a
|
||||
timestamp — who watched, which machine, which Windows session and account, which monitor, which
|
||||
consent policy applied, whether consent was agreed and when, whether it was auto-accepted because
|
||||
nobody was signed in to be asked, whether control was allowed, how many input events were accepted
|
||||
and how many were dropped, and how it ended — so write a staff disclosure from that list rather
|
||||
than from "no recording". Note what is *not* on it: there is deliberately no column saying the
|
||||
banner was drawn. The banner is drawn by the agent on the far side of a websocket and the server
|
||||
never learns whether it went up, so a field answering "was it shown" could only ever hold a guess;
|
||||
what the row holds instead is which policy the session ran under. And it is Windows-only; a session opened against Linux or macOS is
|
||||
refused outright rather than quietly degraded into something weaker.
|
||||
- **There is no rate limiting on sign-in.** No throttler, no account lockout, and authentication
|
||||
events are not audited. Credential stuffing is bounded only by the reverse proxy you put in front,
|
||||
which this repository does not ship. If your proxy can rate-limit one route, make it that one.
|
||||
@@ -544,6 +603,8 @@ wrong on the screen that asks for it.
|
||||
| An answer dies part-way through, every time | The proxy's read timeout is too short. |
|
||||
| Everything works but one kind of thing cannot be created | A limit is full — the community edition's, or your licence's. The message names which. See below. |
|
||||
| An agent installer answers 503 | No agent build is published — the overlay is off. That is a supported state. |
|
||||
| The remote terminal works and remote desktop never connects | The proxy forwards `/api/agents/ws` but not the paths under it. The media socket is `/api/agents/ws/desktop` and needs the upgrade too. |
|
||||
| A remote desktop session opens and ends immediately | Almost always the notice. It ends by design if the banner cannot be kept on top, if the person refuses, or if nobody answers the request within the minute. The end reason on the session says which. |
|
||||
|
||||
The api takes about a minute on first boot, syncing the schema before it listens. `docker compose ps`
|
||||
showing `health: starting` for that long is expected, not a fault.
|
||||
|
||||
Reference in New Issue
Block a user