diff --git a/README.md b/README.md index 17e666f..abc1ec8 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,7 @@ that app directory: | Inside the sandbox | Stored on the host | Contents | Mechanism | |---|---|---|---| | `~/.t3` | `~/.var/app/com.t3tools.t3code/.t3` | T3 Code settings, keybindings, threads (`state.sqlite`), login tokens, secrets, worktrees | `--persist=.t3` | +| `~/.pi` | `~/.var/app/com.t3tools.t3code/.pi` | Pi settings, sessions, and provider credentials (including `agent/auth.json`) | `--persist=.pi` | | `~/.codex` | `~/.var/app/com.t3tools.t3code/.codex` | Codex CLI config and auth | `--persist=.codex` | | `~/.claude` | `~/.var/app/com.t3tools.t3code/.claude` | Claude Code config, including `.claude.json` | `--persist=.claude` + `CLAUDE_CONFIG_DIR` | | `~/.ssh` | `~/.var/app/com.t3tools.t3code/.ssh` | sandbox-local SSH configuration and verified `known_hosts`; not the host SSH directory | `--persist=.ssh` | @@ -107,10 +108,13 @@ that app directory: | `$HISTFILE` | `~/.var/app/com.t3tools.t3code/.local/state/bash/history` | terminal shell history | launcher sets `HISTFILE` | | `$XDG_CONFIG_HOME`, `$XDG_DATA_HOME`, `$XDG_CACHE_HOME` | `~/.var/app/com.t3tools.t3code/{config,data,cache}` | Electron profile, OpenCode, npm globals and cache | Flatpak default | -The app-specific state is separate from the host's `~/.t3`, `~/.codex`, -`~/.claude`, `~/.ssh`, and `~/.gitconfig`. Host credential and tool directories -are not exposed. If you grant `--filesystem=home`, Flatpak ignores `--persist` -and uses the host home directly. +The app-specific state is separate from the host's `~/.t3`, `~/.pi`, +`~/.codex`, `~/.claude`, `~/.ssh`, and `~/.gitconfig`. Host credential and tool +directories are not exposed. If you grant `--filesystem=home`, Flatpak ignores +`--persist` and uses the host home directly. From a terminal opened on a +project, `cd .pi` looks for a `.pi` directory inside that project; use +`cd ~/.pi/agent` to inspect Pi's sandbox-local data. On the host, that data is +stored under `~/.var/app/com.t3tools.t3code/.pi/agent`. T3 Code worktrees live under `~/.t3/worktrees` inside the sandbox. Host-side git sees those worktree paths as missing, so `git worktree prune` on the host diff --git a/com.t3tools.t3code.yml b/com.t3tools.t3code.yml index e3c6006..8516119 100644 --- a/com.t3tools.t3code.yml +++ b/com.t3tools.t3code.yml @@ -31,6 +31,7 @@ finish-args: # on exit. Map app state dirs that ignore XDG onto persistent app storage. # SSH configuration and known_hosts are app-private, not host mounts. - --persist=.t3 # T3 Code settings, state DB, auth tokens, secrets, worktrees + - --persist=.pi # Pi settings, sessions, and provider credentials - --persist=.codex # Codex CLI - --persist=.claude # Claude Code (startt3code points CLAUDE_CONFIG_DIR here) - --persist=.ssh # sandbox-local SSH configuration and verified host keys diff --git a/docs/flatpak-security.md b/docs/flatpak-security.md index 3878637..5a74199 100644 --- a/docs/flatpak-security.md +++ b/docs/flatpak-security.md @@ -8,9 +8,10 @@ not a security isolation boundary; its binaries and libraries inherit the application's effective filesystem, bus, network, and user override grants. Keep app state persistent using Flatpak's XDG app directories, and preserve -`--persist=.t3`, `--persist=.codex`, `--persist=.claude`, and `--persist=.ssh` if the launcher -and application require those paths. Allow individual projects by explicit -per-directory overrides, not `home` or `host` defaults. +`--persist=.t3`, `--persist=.pi`, `--persist=.codex`, `--persist=.claude`, and +`--persist=.ssh` if the launcher and application require those paths. Allow +individual projects by explicit per-directory overrides, not `home` or `host` +defaults. For SSH remotes, prefer the documented [opt-in SSH-agent access](../README.md#optional-ssh-agent-access). It lets all diff --git a/tests/check-ssh-boundary.sh b/tests/check-ssh-boundary.sh index 59e31dc..b790c63 100644 --- a/tests/check-ssh-boundary.sh +++ b/tests/check-ssh-boundary.sh @@ -52,7 +52,9 @@ p.read(sys.argv[1]) context = p['Context'] sockets = context.get('sockets', '').split(';') assert 'ssh-auth' not in sockets, 'SSH agent must be opt-in' -assert '.ssh' in context.get('persistent', '').split(';'), 'App-private SSH state must persist' +persistent = context.get('persistent', '').split(';') +assert '.ssh' in persistent, 'App-private SSH state must persist' +assert '.pi' in persistent, 'App-private Pi credentials must persist' filesystems = context.get('filesystems', '').split(';') for grant in filesystems: path = grant.split(':', 1)[0] diff --git a/tests/test_flatpak_security.py b/tests/test_flatpak_security.py index 4459443..b58657f 100644 --- a/tests/test_flatpak_security.py +++ b/tests/test_flatpak_security.py @@ -72,6 +72,7 @@ def test_safe_yaml_and_app_private_persistence_remain_allowed(self): 'finish-args:\n' ' - *network\n' ' - --persist=.ssh\n' + ' - --persist=.pi\n' ' - --persist=.codex\n' ' - --persist=.claude\n' ' - --persist=.t3\n'