Make Wayland capture honest and replace the broad input group with least privilege
Template tests / tests (pull_request) Failing after 33s
Template tests / tests (pull_request) Failing after 33s
Phase 3 of the improvement plan (PR 10 of the sequence): honest Wayland behavior and a least-privilege alternative to the broad `input` group the audit flagged as a keylogging surface. Least-privilege input access: - packaging/linux/common/60-stepforge-input.rules grants the ACTIVE session read access to MOUSE devices only (ID_INPUT_MOUSE, excluding ID_INPUT_KEYBOARD) via a systemd uaccess ACL — session-scoped, device- scoped, and never keyboards. This replaces `usermod -aG input`, which grants every input device (keyboards included) to the user permanently. - scripts/linux/enable-click-capture.sh installs it opt-in: it prints the exact rule, requires confirmation, and documents the security tradeoff. It never runs the broad-group command. Honest trigger reporting: - New chooseCaptureTrigger() (app/platform/linux/diagnostics.js, re-exported from app/platform/index.js) maps a capability profile to the real trigger: per-click with a marker on X11+xinput; per-click WITHOUT coordinates or a marker on Wayland evdev (the platform exposes no pointer position); and an honest hotkey/interval fallback otherwise. It never promises per-click capture with coordinates on Wayland. - platform:capabilities now includes the active trigger for the machine and the user's fallback setting, for the diagnostics UI. Docs: - GETTING_STARTED_WITH_LINUX.md no longer instructs every Wayland user to join the `input` group; it presents that as a warning, documents the least- privilege script, corrects the capability table (per-click is opt-in, mice only; hotkey/interval is the default Wayland trigger), and points at Settings → Diagnostics. Tests: trigger decisions for X11/xinput, Wayland evdev (no coordinates/marker), Wayland fallback (interval/hotkey with an honest note), the platform facade wiring, Windows; the udev rule (mouse-only, excludes keyboards, uaccess); the opt-in enable script (confirms, installs the rule, never runs usermod -aG input as a command); and docs guards. 289 unit tests pass; startup smoke and click self-test unchanged (stream, markers 3/3, burst 8/8). Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
@@ -13,10 +13,11 @@ difference, how to get the best experience, and how to enable per-click capture.
|
||||
|
||||
| | **X11 / "Ubuntu on Xorg"** | **Wayland (default on Ubuntu)** |
|
||||
|---|---|---|
|
||||
| Screenshot per click | ✅ Yes | ✅ Yes (needs `input` group) |
|
||||
| Screenshot per click | ✅ Yes | ⚙️ Optional (least-privilege mouse rule) |
|
||||
| Red circle on the click | ✅ Yes | ❌ No (Wayland hides the cursor position) |
|
||||
| "Share your screen" prompt | Never | Once per recording session |
|
||||
| Setup needed | None | Add yourself to the `input` group |
|
||||
| Default trigger | Per click | Global hotkey or timed interval |
|
||||
| Setup needed | None | None (per-click is opt-in, mice only) |
|
||||
|
||||
**If you want the full Windows-like experience (click capture *with* the red
|
||||
marker), use an Xorg session — see [Option A](#option-a-best-experience--use-xorg).**
|
||||
@@ -67,27 +68,30 @@ stream stays open until you stop recording.
|
||||
> If you never see steps appear, make sure you actually picked a screen and
|
||||
> clicked **Share** in that dialog.
|
||||
|
||||
### Per-click capture (requires the `input` group)
|
||||
### Per-click capture (optional, least-privilege)
|
||||
|
||||
By default on Wayland, StepForge cannot see your clicks, so it falls back to
|
||||
**capturing a screenshot every few seconds** (timed capture).
|
||||
By default on Wayland, StepForge cannot see your clicks, so it uses a **global
|
||||
hotkey or a timed interval** to capture (see below). This is the recommended,
|
||||
no-extra-permissions path.
|
||||
|
||||
To get a screenshot **on every click** instead, give your user read access to
|
||||
the mouse devices by joining the `input` group:
|
||||
If you want a screenshot **on every click**, you can grant StepForge read
|
||||
access to your **mouse** devices. Do **not** use `sudo usermod -aG input`:
|
||||
joining the `input` group grants your user access to *all* input devices —
|
||||
**including keyboards** — permanently, on every session. That is a keylogging
|
||||
surface StepForge does not need.
|
||||
|
||||
Instead, install the least-privilege udev rule, which grants your active
|
||||
session read access to **mouse devices only** (never keyboards), scoped to
|
||||
whoever is physically logged in:
|
||||
|
||||
```bash
|
||||
sudo usermod -aG input "$USER"
|
||||
bash scripts/linux/enable-click-capture.sh
|
||||
```
|
||||
|
||||
Then **log out and log back in** (group membership only applies to new sessions).
|
||||
Verify it took effect:
|
||||
|
||||
```bash
|
||||
groups | tr ' ' '\n' | grep input # should print: input
|
||||
```
|
||||
|
||||
Now StepForge reads mouse buttons directly from the kernel (`/dev/input`) and
|
||||
captures a screenshot on each click.
|
||||
It shows you the exact rule and asks for confirmation before installing. Under
|
||||
the hood it uses a systemd `uaccess` ACL restricted to `ID_INPUT_MOUSE`
|
||||
devices — see [packaging/linux/common/60-stepforge-input.rules](../packaging/linux/common/60-stepforge-input.rules).
|
||||
Re-log in (or replug a USB mouse) for it to apply.
|
||||
|
||||
> **No red marker on Wayland.** Even with per-click capture working, Wayland
|
||||
> does not tell apps *where* the pointer is, so StepForge cannot draw the circle
|
||||
@@ -114,10 +118,16 @@ On launch StepForge chooses the best available click source:
|
||||
1. **Windows** — low-level mouse hook (position + timing).
|
||||
2. **X11** — `xinput` (position + timing → full red marker).
|
||||
3. **Linux evdev** (`/dev/input`) — button presses on X11 *and* Wayland, no
|
||||
position on Wayland. Used when `xinput` can't see clicks (i.e. Wayland), if
|
||||
you're in the `input` group.
|
||||
4. **Timed capture** — the always-works fallback (a screenshot every N seconds)
|
||||
when no click source is available.
|
||||
position on Wayland. Used when `xinput` can't see clicks (i.e. Wayland) and
|
||||
only if you opted into the least-privilege mouse rule
|
||||
(`scripts/linux/enable-click-capture.sh`).
|
||||
4. **Hotkey / timed capture** — the always-works fallback (the Capture hotkey,
|
||||
or a screenshot every N seconds) when no click source is available. On
|
||||
Wayland this is the default, and StepForge reports it honestly instead of
|
||||
pretending clicks are captured.
|
||||
|
||||
Open **Settings → Diagnostics** to see the detected session type, portal/
|
||||
PipeWire status, and the active capture trigger for your machine.
|
||||
|
||||
Screen frames come from a single long-lived capture stream per recording, so
|
||||
clicks/timer ticks never re-open the screen-share dialog.
|
||||
@@ -149,7 +159,9 @@ STEPFORGE_CAPTURE_LOG=1 npm start
|
||||
|
||||
- `[stepforge] screen-capture stream active …` — the stream is up.
|
||||
- `[stepforge] per-click capture via evdev on N device(s) …` — clicks are wired up.
|
||||
- `[stepforge] no readable mouse input devices …` — you need the `input` group (see above).
|
||||
- `[stepforge] no readable mouse input devices …` — per-click capture is not
|
||||
enabled; run `scripts/linux/enable-click-capture.sh` for the least-privilege
|
||||
mouse rule, or just use the hotkey/interval trigger.
|
||||
|
||||
**Harmless console noise.** Lines like `vaInitialize failed`, `Frame latency is
|
||||
negative`, and `StatusNotifierItem … already exported` come from Chromium/GNOME,
|
||||
|
||||
Reference in New Issue
Block a user