docs(acl): threat model and conventions say app commands are ACL-gated

Task 2 already closed the risk (build.rs declares a Tauri AppManifest and
gates every app command per window); this task brings the docs in line so
the threat model of record no longer claims app commands are ungated or
that any local window can call any app command.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-22 22:38:32 -07:00
co-authored by Claude Opus 5.5
parent 1401369ffa
commit bc4980e014
6 changed files with 29 additions and 10 deletions
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{
"identifier": "file-viewer",
"description": "The terminal file viewer windows (`file-viewer-<n>`, opened by `open_file_viewer` on the app's own `viewer.html`). Same rules as `default.json`: app commands need no entry here and are gated by label inside `commands/file_viewer_commands.rs`; this file is the plugin-command surface a compromised viewer webview could reach, and it is the smallest one that lets the window work. `core:event:allow-listen`/`allow-unlisten` are for `file-viewer-goto` (Rust → this window; the viewer subscribes through `getCurrentWindow().listen`, because a bare `listen()` in *any* window receives an `emit_to`). `core:window:allow-destroy` is not optional: `getCurrentWindow().onCloseRequested` in @tauri-apps/api 2.11 makes Rust `prevent_close()` whenever a JS listener exists and then calls `destroy()` itself, so without this grant the window's X button does nothing once the unsaved-changes guard is installed. `allow-close` is deliberately absent — nothing calls it, and `destroy` is the only exit. No `set-title`/`set-focus`/`unminimize`: those are done from Rust when a second click targets an already-open file. `core:webview:allow-internal-toggle-devtools` is the same dev-only convenience `default.json` carries.",
"description": "The terminal file viewer windows (`file-viewer-<n>`, opened by `open_file_viewer` on the app's own `viewer.html`). Same rules as `default.json`. The five bare `allow-viewer-*` grants are the only app commands a viewer window can invoke: `build.rs` declares the AppManifest that makes tauri enforce that, and refuses any other bare grant in this file. The label gate inside `commands/file_viewer_commands.rs` is still what stops window A acting on window B's registry entry, because the ACL only decides which window may call. The rest of this file is the plugin-command surface a compromised viewer webview could reach, and it is the smallest one that lets the window work. `core:event:allow-listen`/`allow-unlisten` are for `file-viewer-goto` (Rust → this window; the viewer subscribes through `getCurrentWindow().listen`, because a bare `listen()` in *any* window receives an `emit_to`). `core:window:allow-destroy` is not optional: `getCurrentWindow().onCloseRequested` in @tauri-apps/api 2.11 makes Rust `prevent_close()` whenever a JS listener exists and then calls `destroy()` itself, so without this grant the window's X button does nothing once the unsaved-changes guard is installed. `allow-close` is deliberately absent — nothing calls it, and `destroy` is the only exit. No `set-title`/`set-focus`/`unminimize`: those are done from Rust when a second click targets an already-open file. `core:webview:allow-internal-toggle-devtools` is the same dev-only convenience `default.json` carries.",
"windows": ["file-viewer-*"],
"permissions": [
"core:event:allow-listen",
File diff suppressed because one or more lines are too long
+4
View File
@@ -3,6 +3,10 @@
//! Every window is a `file-viewer-<n>` label registered in [`registry::ViewerRegistry`];
//! the commands in `commands/file_viewer_commands.rs` gate on the label and act only on
//! the caller's own entry, which is why nothing here takes a path from a window.
//!
//! `file-viewer-*` is also the `windows` glob of `capabilities/file-viewer.json`, which grants
//! exactly the five `viewer_*` commands and nothing else. Labels are minted only here; a window
//! created anywhere else with a matching label would inherit those grants.
pub mod poll;
pub mod registry;