feat: update docs

This commit is contained in:
Ivan 2026-08-14 11:19:54 -05:00
parent c5a094ddfc
commit 6b3617923f
No known key found for this signature in database
5 changed files with 18 additions and 10 deletions

View file

@ -27,15 +27,19 @@ Denylist (must not be set via `config.set` WS):
- `auth_enabled`
- `auth_password_hash`
When password auth is enabled, WS mutators require an authenticated session. That includes:
When password auth is enabled, WS mutators and reads require an authenticated session. That includes:
- `config.set`
- `rns.link.open|identify|request|send|close`
- Nomad download / archive mutators
- LXMF forwarding rule mutators
- keyboard shortcut set/delete
- Nomad download / archive mutators and archive reads
- LXMF forwarding rule mutators and `lxmf.forwarding.rules.get`
- keyboard shortcut set/delete and `keyboard_shortcuts.get`
Public / read types stay limited. See `WEBSOCKET_PUBLIC_TYPES`, `WEBSOCKET_READ_TYPES`, and `WEBSOCKET_MUTATOR_TYPES` in `websocket_config_guard.py`.
Only `ping` skips the session check. Unknown types require auth.
`/ws` and `/ws/telephone/audio` upgrades also require a same-authority `Origin` (missing Origin is allowed for non-browser clients). Behind a trusted proxy, `X-Forwarded-Host` is accepted as the public authority.
Public / read / mutator classification lives in `WEBSOCKET_PUBLIC_TYPES`, `WEBSOCKET_READ_TYPES`, and `WEBSOCKET_MUTATOR_TYPES` in `websocket_config_guard.py`.
## Dangerous knobs
@ -53,6 +57,6 @@ Public / read types stay limited. See `WEBSOCKET_PUBLIC_TYPES`, `WEBSOCKET_READ_
## Verification
```bash
uv run pytest tests/backend/test_websocket_config_security.py tests/backend/test_websocket_config_guard.py -q --tb=short
uv run pytest tests/backend/test_websocket_config_security.py tests/backend/test_websocket_config_guard.py tests/backend/test_ws_origin_filesync_oracles.py -q --tb=short
pnpm exec vitest run tests/frontend/apiFetchGuard.test.js
```

View file

@ -30,7 +30,8 @@ Plugins are powerful. Treat install and enable as security-sensitive.
2. User consent on declared permissions / network endpoints
3. Enable only after grants are stored
4. Runtime enforces declared + granted hooks / managers / storage / `network:fetch`
5. Integrity hashing after install. Tampered trees disable, they do not silently run
5. Integrity hashing after install. Tampered trees disable, they do not silently run. `invoke` and `dispatch_hook` re-hash before backend execution.
6. Python backends purge `__pycache__` next to the entry file on load so excluded bytecode cannot replace hashed source.
## Hard rules
@ -55,7 +56,7 @@ Plugins are powerful. Treat install and enable as security-sensitive.
## Verification
```bash
uv run pytest tests/backend/test_plugin_manager.py tests/backend/test_plugin_permissions.py tests/backend/test_plugin_signature.py tests/backend/test_plugin_integrity.py tests/backend/test_plugin_security.py -q --tb=short
uv run pytest tests/backend/test_plugin_manager.py tests/backend/test_plugin_permissions.py tests/backend/test_plugin_signature.py tests/backend/test_plugin_integrity.py tests/backend/test_plugin_python_runtime.py tests/backend/test_plugin_security.py -q --tb=short
```
Add focused coverage when changing grant normalization, network endpoint scanning, or invoke paths.

View file

@ -19,7 +19,7 @@ Reference resolve helper: `rns_filesync_handler.py` (`_resolve_manager_path`).
## Hard rules
1. Jail CRUD to the configured `sync_directory` only. The folder picker that _chooses_ a sync root is a different, looser jail (identity storage with reserved tops blocked). Do not reuse the picker jail for tree/upload/delete.
1. Jail CRUD to the configured `sync_directory` only. The folder picker that _chooses_ a sync root is a different, looser jail (identity storage with reserved tops blocked, including `ssl`). Do not reuse the picker jail for tree/upload/delete.
2. Skip and refuse mutation of protocol sidecars (`.rns-filesync*`, `.rns-xfer*`).
3. `announce_interval` must be an integer `>= 10` seconds. Invalid values return `{"ok": False, "error": ...}` rather than throwing 500.
4. Upload cap for in-app manager uploads is `MANAGER_UPLOAD_MAX_BYTES` (64 MiB). That cap is the local control plane, not a mesh payload budget.
@ -39,5 +39,5 @@ Reference resolve helper: `rns_filesync_handler.py` (`_resolve_manager_path`).
## Verification
```bash
uv run pytest tests/backend/test_rns_filesync_security.py tests/backend/test_path_jail_oracles.py -q --tb=short
uv run pytest tests/backend/test_rns_filesync_security.py tests/backend/test_path_jail_oracles.py tests/backend/test_ws_origin_filesync_oracles.py -q --tb=short
```

View file

@ -53,6 +53,9 @@ All notable changes to this project will be documented in this file.
- **UI language**: Persist language changes over the config HTTP API (not WebSocket-only), normalize legacy locale codes, and stop the Reticulum manual language picker from overwriting app UI language.
- **Network visualizer**: WebGL background follows light theme and clears while the WASM scene is still loading. Boot theme removes stale dark class when light is selected. WebGL live layout springs are 200 (me to interface) and 240 (peers) instead of 440/500, repulsion is 1800 instead of 5600, and ticks sleep once a step moves less than 0.15 world units. Planet view keeps nodes on the front-to-back hemisphere (no wrap past the far pole), draws far nodes under near ones, and reloads after an identity switch instead of keeping the previous identity's path table and positions.
- **Electron / Android shell origin allowlists**: Parse URLs before treating them as the local backend. `http://127.0.0.1:9337@example.com` is example.com with userinfo, not loopback. Electron attaches `will-navigate`, `will-redirect`, and `will-frame-navigate` on every `web-contents-created`, denies `data:` and untrusted `blob:` in-window, and no-ops preload `window.electron` IPC unless the page is `file:` loading/crash, `127.0.0.1`/`localhost:9337`, or a trusted blob. Android WebView navigation is the configured backend origin only (not any loopback port), rejects userinfo, and denies `data:` because `MeshChatXAndroid` is injected into every loaded page.
- **WebSocket Origin and read gating**: `/ws` and `/ws/telephone/audio` reject a browser Origin that does not match the request authority (missing Origin still allowed for non-browser clients; `X-Forwarded-Host` only behind a trusted proxy). When password auth is enabled, every WS type except `ping` requires a session, including former read types such as `keyboard_shortcuts.get`.
- **FileSync sync-root picker**: Identity-storage `ssl` (TLS key material) is a reserved top and cannot be chosen as a sync directory.
- **Plugin integrity at invoke**: `invoke` and `dispatch_hook` re-hash the install tree and refuse tampered backends. Python plugin loads delete `__pycache__` next to the entry file so bytecode excluded from the hash cannot replace source.
- **Translator (Landlock)**: On Linux, allow read/execute for user-local pipx CLIs (`~/.local/bin`, `~/.local/share/pipx`) and read-write for Argos Translate data under `~/.local/share/argos-translate`, so argospm language lists and local Argos translation work with the filesystem sandbox enabled.
- **Tests**: Landlock integration probes for subprocess spawn, translator Argos language listing, user-local CLI execution, and home write denial outside RW roots (tests/backend/test_landlock_integration_surfaces.py).
- **Windows desktop**: AppContainer sandboxing is opt-in (set `MESHCHAT_APPCONTAINER=1`) instead of on by default, to avoid extra launcher processes and heavy startup until the path is stable.

Binary file not shown.