Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Dormouse is a terminal, so users trust it with shells, source trees, credentials

Dormouse Pocket lets a phone attach to a terminal running on the user's laptop, so the pairing stack is the one part of the product that takes input from the network. An authorized Client is deliberately equivalent to a person sitting at that laptop's keyboard — `terminal.write` is raw keystroke injection into a live PTY, and protocol-v1 has no notion of a restricted session. The entire trust model therefore exists to make *authorized* hard to reach, and impossible to reach by accident.

The design lives in [`docs/specs/remote-security-model.md`](docs/specs/remote-security-model.md), the deployment in [`docs/specs/server.md`](docs/specs/server.md), and the operator runbook in [`SELF_HOST.md`](SELF_HOST.md). This section does not restate them: it names the properties that are load-bearing enough to audit, and the risks we have accepted rather than closed. Two deployment modes are defined (`docs/specs/remote-api.md` → "Server deployment modes"); everything below is **self-hosted**, the only one that ships today. Cloud-hosted is [staged](#cloud-hosted-mode-staged).
The design lives in [`docs/specs/remote-security-model.md`](docs/specs/remote-security-model.md), the deployment in [`docs/specs/server.md`](docs/specs/server.md), and the operator runbook in [`SELF_HOST.md`](SELF_HOST.md). This section does not restate them: it names the properties that are load-bearing enough to audit, and the risks we have accepted rather than closed. Two deployment modes are defined (`docs/specs/remote-api.md` → "Transport"); everything below is **self-hosted**, the only one that ships today. Cloud-hosted is [staged](#cloud-hosted-mode-staged).

### Trust boundary

Expand Down Expand Up @@ -103,7 +103,7 @@ Web Push is the one path where the Server makes an outbound request to an addres

These are the two real gaps in the shipped model, and they are gaps rather than accepted risks — we intend to close them.

**Revocation has no mechanism.** `HostAcl.revokeDevice` / `revokePasskey` exist and have no callers; no relay frame carries a revocation; there is no management UI. Revoking a lost phone means hand-editing JSON on the Host, and it takes effect at that Client's next `authorizeConnection` — an already-established session survives it, and the operator's only lever is stopping the Host. Server-pushed revocation propagation is staged in `docs/specs/remote-security-model.md` → Future.
**Revocation has no mechanism.** `HostAcl.revokeDevice` / `revokePasskey` exist and have no callers; no relay frame carries a revocation; there is no management UI. Revoking a lost phone means hand-editing JSON on the Host **and restarting it**: `RemoteHostService.#startHost` reads the store once and hands the `RemoteHost` a snapshot for its whole lifetime, so an edit alone changes nothing that is running. The restart is the whole lever — it reloads the ACL and, by dropping the relay socket, ends every established session. Server-pushed revocation propagation is staged in `docs/specs/remote-security-model.md` → Future.

**There is no audit trail.** The ACL records `approvedAt` / `approvedBy` for a pairing, and nothing records connects, attaches, denials, or writes. A self-hoster cannot answer "did anyone connect to my laptop last night", which also means an ACL entry added by any of the paths above would be invisible after the fact.

Expand Down
15 changes: 9 additions & 6 deletions canopy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ The `UpstreamVsFork` story renders identical content through three renderers
stacked: pristine upstream `@xterm/addon-webgl`, the fork with `sdf: false`
(isolates the instance-layout/shader changes), and the fork with `sdf: true`
(isolates the SDF glyph path). The upstream pin must be the same commit as the
fork base — the addon's beta counter is offset from core's (addon
`0.20.0-beta.298` == core `6.1.0-beta.301` == commit `8c9b9fdb`); re-derive it
with `npm view @xterm/addon-webgl@<ver> gitHead` when the fork rebases, or let
`node scripts/xterm-bump.mjs --canopy <forkVersion>` pick the matching addon.
fork base — the `@xterm/*` beta counters are independent, so the numbers never
match (addon `0.20.0-beta.298` == core `6.1.0-beta.301` == commit `8c9b9fdb`);
re-derive it with `npm view @xterm/addon-webgl@<ver> gitHead` when the fork
rebases, or let `node scripts/xterm-bump.mjs --canopy <forkVersion>` pick the
matching addon.

Story content writes PUA glyphs (powerline chevrons etc.) as `\uE0BX` escapes,
never literal characters — the literals are invisible in editors and were once
Expand All @@ -53,8 +54,10 @@ silently dropped in a file rewrite, which presented as a rendering regression.
cd canopy && pnpm link ~/projects/xterm.js/addons/addon-webgl
```

`pnpm link` writes only into `node_modules`, so nothing accidental gets
committed; a later `pnpm install` restores the release tarball.
CAUTION: pnpm 11's link also writes persistent residue — a `link:` dependency in
the ROOT `package.json` and an `overrides:` entry in `pnpm-workspace.yaml` —
which silently keeps resolving the link. Revert both and `pnpm install` before
trusting a tarball verification.

## Roadmap

Expand Down
2 changes: 1 addition & 1 deletion canopy/src/GlTerminal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Terminal } from '@xterm/xterm';
import { WebglAddon } from '@diffplug/xterm-addon-webgl-sdf';
// The pristine upstream addon, pinned to the exact commit the fork's sdf branch is based on
// (addon 0.20.0-beta.298 and core 6.1.0-beta.301 share gitHead 8c9b9fdb) — the regression
// baseline for the RendererComparison story.
// baseline for the UpstreamVsFork story. canopy/README.md records the same triple.
import { WebglAddon as UpstreamWebglAddon } from '@xterm/addon-webgl';
// Read the two versions rather than restating them, so the on-screen labels cannot drift from
// the pins the way a hand-typed version does.
Expand Down
Loading