a plugin websocket targets a sidecar, never a port a manifest picked
The fixed-port form shipped this morning and lasted about an hour. The owner asked
whether declaring a port was safe, and it is not: nothing stopped a manifest naming
a port it does not own, so `websocket: { port: 5432 }` plus a grant would have been
a raw TCP relay onto Postgres — authenticated by the platform, available to anyone
that plugin was granted to. Port 22 and officer's own port are the same sentence.
The relay checked that the HOST was loopback and I mistook that for having checked
anything about the port. They are different questions and only the second one
matters: loopback is exactly where everything worth reaching already is.
So the only form is `{ sidecar }`. A sidecar's port is trustworthy for a reason a
declaration can never be — the platform watched it arrive at registration, so the
association between a port and a plugin is observed rather than asserted. The same
distinction that decides the delegation problem in todo/agent-coordination: a claim
is not evidence, whoever is making it.
The cost is that a plugin wanting a socket needs a sidecar. That is not ceremony,
it is the thing that makes the port mean anything. It was added as a shortcut for
Minesweeper, whose x11vnc listens on a known port — which is precisely the case
that looked harmless and generalised into a hole.
Nothing had used it. Minesweeper is still whole in the platform and its extraction
had not started.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
@@ -294,14 +294,26 @@ export type PluginManifest = {
|
||||
* There is deliberately no separate socket permission: granting the plugin grants its socket, and nothing
|
||||
* can drift out of step because there is only one decision.
|
||||
*
|
||||
* `{ port }` for a fixed loopback port the plugin's own service listens on. `{ sidecar }` when the target
|
||||
* is a sidecar, whose port is ephemeral and announced at registration — a manifest cannot know that
|
||||
* number, which is the whole reason the indirection exists.
|
||||
* The target is a SIDECAR, always, and never a port number a manifest picked.
|
||||
*
|
||||
* A fixed-port form existed for about an hour and was removed before it shipped anywhere. The hole is
|
||||
* total: nothing stops a manifest naming a port it does not own, so `{ port: 5432 }` plus a grant is a
|
||||
* raw TCP relay onto Postgres, authenticated by the platform, for anyone that plugin is granted to. `:22`
|
||||
* and officer's own port are the same sentence. Checking that the HOST was loopback — which the relay
|
||||
* does — is not the same as checking the PORT belongs to the plugin, and only the second one matters.
|
||||
*
|
||||
* A sidecar's port is trustworthy for a reason a declaration can never be: the platform watched it
|
||||
* arrive. The sidecar binds an ephemeral port and announces it at registration, so the association
|
||||
* between "this port" and "this plugin" is something the platform observed rather than something a
|
||||
* manifest asserted. Provenance, not a claim.
|
||||
*
|
||||
* The cost is that a plugin wanting a socket needs a sidecar. That is not ceremony — it is the thing
|
||||
* that makes the port mean anything.
|
||||
*
|
||||
* The host is always loopback and cannot be set. A plugin naming an arbitrary host would be a
|
||||
* request-forgery primitive reachable by anyone the plugin is granted to.
|
||||
*/
|
||||
websocket?: { port: number } | { sidecar: string };
|
||||
websocket?: { sidecar: string };
|
||||
osDependencies?: OsDependency[];
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user