Document Claude terminal security and persistence

This commit is contained in:
Alexandre
2026-07-10 14:22:15 +02:00
parent 69b323a16b
commit b1536c4a6a

View File

@@ -21,9 +21,9 @@ currently does not include Computer Use or dictation.
## Architecture
Claude Desktop and Claude Code run as separate clients inside the same add-on.
They share the persistent home directory, Git credentials, repositories, Claude
Code configuration, Headroom storage, and RTK configuration, but they do not
share or hand off a conversation.
They share the configured persistent home directory, Git credentials,
repositories, Claude Code configuration, Headroom storage, and RTK
configuration, but they do not share or hand off a conversation.
- **Claude Desktop** uses Headroom through its MCP tools.
- **Claude Code** uses Headroom's supported `headroom wrap claude` integration.
@@ -37,8 +37,8 @@ share or hand off a conversation.
- Official Claude Code stable package installed in the same image.
- Optional authenticated `ttyd` web terminal on port `7681`.
- Persistent `tmux` session shared by reconnecting terminal clients.
- Persistent `$HOME` under `/data/data`, preserving Desktop and Claude Code
sign-in state across restarts.
- Persistent `$HOME` at the configured `data_location` (default `/data/data`),
preserving Desktop and Claude Code state across restarts.
- Optional runtime Claude Desktop updates from Anthropic's apt repository.
- Optional extra apt and pip package installation.
- Baked-in `git`, GitHub CLI (`gh`), `ripgrep`, and terminal tooling.
@@ -49,15 +49,17 @@ share or hand off a conversation.
## Claude Code terminal setup
The terminal is enabled in the add-on configuration but remains unavailable
until authentication is configured. Port `7681` is not mapped by default.
The terminal service is enabled in the add-on configuration but remains
unavailable until authentication is configured. Port `7681` is not mapped by
default.
1. Set `terminal_password`, or set the existing `PASSWORD` option as a fallback.
1. Set a unique `terminal_password`. The existing `PASSWORD` option is accepted
only as a compatibility fallback.
2. Optionally set `terminal_username` and `terminal_workspace`.
3. Map container port `7681` to a host port in the add-on **Network** section.
4. Restart the add-on.
5. Open `http://<home-assistant-host>:7681` and sign in with the configured
terminal credentials.
5. Reach `http://<home-assistant-host>:7681` only through an encrypted VPN or an
HTTPS reverse proxy, then sign in with the configured terminal credentials.
The terminal opens in a persistent tmux session. Closing the browser detaches
from tmux rather than terminating commands that are already running.
@@ -68,9 +70,10 @@ Start the optimized Claude Code path with:
claude-headroom
```
This invokes `headroom wrap claude`, which starts or reuses the local Headroom
proxy and launches Claude Code with the required routing. The RTK hook remains
active through the shared `~/.claude/settings.json` configuration.
This reuses the supervised Headroom proxy on `127.0.0.1:8787` and launches
Claude Code with the required routing. Headroom is told not to install RTK
because the add-on already maintains the RTK hook in
`~/.claude/settings.json`.
To bypass Headroom for troubleshooting, run:
@@ -80,28 +83,55 @@ claude-direct
Running `claude` directly is equivalent to the direct path. The first Claude
Code launch may require its own account authentication; Desktop and Claude Code
store separate client credentials even though both live under the same
store separate client credentials even though both use the configured
persistent home directory.
Do not expose the terminal port directly to the public internet. Prefer a VPN,
Tailscale, or another trusted private network in addition to ttyd authentication.
### Multiple concurrent clients
Every browser connection attaches to the same tmux session. Concurrent clients
therefore see the same terminal, keystrokes, and resize events. This is useful
for reconnecting to one long-running session, but it is not an isolated
multi-user terminal.
### Terminal user and permissions
The service drops privileges to the LinuxServer `abc` account before starting
ttyd. The effective numeric UID and GID follow the configured `PUID` and `PGID`.
Using `PUID: 0` can provide root-equivalent access inside the add-on; use a
non-zero UID/GID where your storage permissions allow it.
The configured workspace must resolve to the persistent home directory or a
subdirectory of `/share`, `/media`, `/mnt`, `/data`, or `/config`. Existing
directories are never re-owned by the terminal service and must already be
readable, writable, and searchable by `abc`.
### Terminal security
The direct ttyd endpoint uses HTTP Basic Authentication without TLS.
Credentials and terminal traffic are unencrypted on the network. ttyd also
receives its Basic Authentication credential as a process argument, so it is
visible to processes with sufficient access inside the container.
Do not expose port `7681` directly to the public internet. Use a VPN such as
WireGuard or Tailscale, or place the endpoint behind an HTTPS reverse proxy.
Use a unique `terminal_password` rather than reusing the Selkies `PASSWORD`.
## Options
| Option | Default | Description |
| ------ | ------- | ----------- |
| `PUID` / `PGID` | `0` / `0` | User and group used for persistent data ownership. |
| `PUID` / `PGID` | `0` / `0` | Numeric user and group applied by the LinuxServer initialization. |
| `TZ` | | Optional timezone, for example `Europe/Brussels`. |
| `KEYBOARD` | | Optional Selkies keyboard layout. |
| `PASSWORD` | | Optional password for direct Selkies ports and fallback terminal password. |
| `PASSWORD` | | Optional password for direct Selkies ports and compatibility fallback for terminal authentication. |
| `DRINODE` | | Optional GPU device override for Selkies. |
| `DNS_server` | `8.8.8.8` | DNS server used by the standard DNS module. |
| `auto_update` | `true` | Upgrade `claude-desktop` from Anthropic's apt repository at startup. |
| `enable_terminal` | `true` | Enable the supervised Claude Code web-terminal service. |
| `terminal_username` | `claude` | Username used by ttyd basic authentication. |
| `terminal_password` | | Terminal password; falls back to `PASSWORD`. The service idles when neither is set. |
| `terminal_username` | `claude` | Username used by ttyd Basic Authentication. |
| `terminal_password` | | Dedicated terminal password. The service idles when this and `PASSWORD` are empty. |
| `terminal_workspace` | | Initial directory; defaults to `<data_location>/workspace`. |
| `install_headroom` | `true` | Enable Headroom MCP for Desktop and the local proxy used by `claude-headroom`. |
| `install_headroom` | `true` | Enable Headroom MCP for Desktop and the supervised local proxy reused by `claude-headroom`. |
| `install_rtk` | `true` | Configure RTK's Claude Code `PreToolUse` hook. |
| `install_caveman` | `true` | Install the Caveman Claude Code plugin in the persistent Claude home. |
| `install_github_cli` | `true` | Enable setup checks for the baked-in `git` and `gh` commands. |
@@ -110,14 +140,12 @@ Tailscale, or another trusted private network in addition to ttyd authentication
| `github_email` | | Optional global Git author email. |
| `ha_smart_context` | `true` | Enable Home Assistant smart context support for Claude tooling. |
| `enable_ha_mcp` | `true` | Enable Home Assistant MCP support for Claude tooling. |
| `dangerously_skip_permissions` | `false` | Expose Claude Code's dangerous permission-skip option. |
| `dangerously_skip_permissions` | `false` | Reserved compatibility option; it is not applied by the terminal launcher. |
| `additional_apps` | | Comma-separated Debian apt packages to install at startup. |
| `additional_pip` | | Comma-separated pip packages installed with `--break-system-packages`. |
| `data_location` | `/data/data` | Persistent home directory for both Claude clients and tooling. |
| `env_vars` | `[]` | Additional environment variables exported inside the container. |
Standard SMB and local-disk options from the repository are also available.
## Headroom behavior
When `install_headroom` is enabled, the add-on registers `headroom mcp serve` in
@@ -126,7 +154,8 @@ Claude Desktop and starts a supervised local Headroom backend. Desktop can use
Claude Desktop overrides `ANTHROPIC_BASE_URL`, so it is deliberately launched
without proxy injection. The web terminal instead provides `claude-headroom`,
which uses Headroom's supported Claude Code wrapper.
which reuses the supervised proxy through Headroom's `--no-proxy` mode. RTK
setup remains owned by the add-on through Headroom's `--no-rtk` mode.
The Headroom dashboard remains available at:
@@ -134,7 +163,8 @@ The Headroom dashboard remains available at:
http://<home-assistant-host>:8787/dashboard
```
when the `8787/tcp` port is mapped.
when the `8787/tcp` port is mapped. Treat this endpoint as sensitive and do not
expose it directly to the public internet.
## Custom scripts
@@ -145,7 +175,8 @@ the image.
## Data and cache locations
Persistent state is stored in `data_location`:
Persistent state is stored in the configured `data_location` (default
`/data/data`):
- Claude Desktop sign-in: `~/.config/Claude`
- Claude Code settings, hooks, sessions, and plugins: `~/.claude`
@@ -157,4 +188,4 @@ Volatile cache data is redirected to `/tmp/cache` through `$XDG_CACHE_HOME` and
[aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg
[amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg
[maintenance-shield]: https://img.shields.io/maintenance/yes/2026.svg
[maintenance-shield]: https://img.shields.io/maintenance-yes-2026.svg