fix: make profile subprocess HOME policy explicit
This commit is contained in:
@@ -109,6 +109,7 @@ terminal:
|
||||
backend: local # local | docker | ssh | modal | daytona | singularity
|
||||
cwd: "." # Gateway/cron working directory (CLI always uses launch dir)
|
||||
timeout: 180 # Per-command timeout in seconds
|
||||
home_mode: auto # auto | real | profile — subprocess HOME policy
|
||||
env_passthrough: [] # Env var names to forward to sandboxed execution (terminal + execute_code)
|
||||
singularity_image: "docker://nikolaik/python-nodejs:python3.11-nodejs20" # Container image for Singularity backend
|
||||
modal_image: "nikolaik/python-nodejs:python3.11-nodejs20" # Container image for Modal backend
|
||||
@@ -137,6 +138,54 @@ terminal:
|
||||
backend: local
|
||||
```
|
||||
|
||||
By default, local tool subprocesses keep your real OS-user `HOME`. This lets
|
||||
external CLIs such as `git`, `ssh`, `gh`, `az`, `npm`, Claude Code, and Codex
|
||||
find the credentials and config they already use in your normal shell. Hermes
|
||||
state is still profile-scoped through `HERMES_HOME`; `HOME` is not how profiles
|
||||
select config, memory, sessions, or skills.
|
||||
|
||||
Hermes does **not** change your system-wide `HOME`, your shell startup files, or
|
||||
the operating system account home. This setting only controls the environment
|
||||
passed to subprocesses that Hermes launches through tools such as `terminal`,
|
||||
background terminal processes, `execute_code`, and ACP helper processes.
|
||||
|
||||
#### `terminal.home_mode`
|
||||
|
||||
| Mode | Host installs | Containers | Tradeoff |
|
||||
|---|---|---|---|
|
||||
| `auto` | Keep the real OS-user `HOME` | Use `{HERMES_HOME}/home` | Recommended default. Host CLIs keep working; container state persists. |
|
||||
| `real` | Force the real OS-user `HOME` | Force the real OS-user `HOME` if visible | Useful if a parent process accidentally started with `HOME` pointed at a profile home. |
|
||||
| `profile` | Use `{HERMES_HOME}/home` when it exists | Use `{HERMES_HOME}/home` when it exists | Strict per-profile CLI config isolation, but normal `~/.ssh`, `~/.gitconfig`, `~/.azure`, `~/.config/gh`, Claude/Codex auth, npm state, etc. will not be visible unless you initialize or link them inside the profile home. |
|
||||
|
||||
The downside of the default is that host profiles share the same normal
|
||||
user-level CLI credentials/config under `~`. If you need a profile with a
|
||||
separate git identity, SSH keys, GitHub CLI login, npm config, or cloud CLI
|
||||
login, use `home_mode: profile` and initialize those tools inside that profile
|
||||
home deliberately.
|
||||
|
||||
If you intentionally want strict per-profile tool-config isolation, set:
|
||||
|
||||
```yaml
|
||||
terminal:
|
||||
home_mode: profile
|
||||
```
|
||||
|
||||
In that mode tool subprocesses use `{HERMES_HOME}/home` as `HOME`. Hermes also
|
||||
sets `HERMES_REAL_HOME` so scripts can still locate the actual user home when
|
||||
they need it. Container backends keep using `{HERMES_HOME}/home` in `auto` mode
|
||||
because that directory lives on the persistent Hermes data volume.
|
||||
|
||||
Scripts that need to distinguish profile state from the real user home should
|
||||
prefer `HERMES_HOME` for Hermes data and `HERMES_REAL_HOME` for the account home:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
hermes_home = Path(os.environ["HERMES_HOME"])
|
||||
real_home = Path(os.environ.get("HERMES_REAL_HOME", os.environ["HOME"]))
|
||||
```
|
||||
|
||||
:::warning
|
||||
The agent has the same filesystem access as your user account. Use `hermes tools` to disable tools you don't want, or switch to Docker for sandboxing.
|
||||
:::
|
||||
|
||||
@@ -273,6 +273,32 @@ Profiles use the `HERMES_HOME` environment variable. When you run `coder chat`,
|
||||
|
||||
This is separate from terminal working directory. Tool execution starts from `terminal.cwd` (or the launch directory when `cwd: "."` on the local backend), not automatically from `HERMES_HOME`.
|
||||
|
||||
On host installs, tool subprocesses keep your real OS-user `HOME` by default so
|
||||
existing CLI credentials under `~` keep working across profiles. Profile data is
|
||||
isolated by `HERMES_HOME`, not by changing `HOME`. Container backends still use
|
||||
`{HERMES_HOME}/home` for persistent tool state, and host users who need strict
|
||||
per-profile tool config can opt in with `terminal.home_mode: profile`.
|
||||
|
||||
This means two things that are easy to mix up:
|
||||
|
||||
- `HERMES_HOME` is the profile boundary. It controls Hermes config, `.env`,
|
||||
memory, sessions, skills, logs, cron jobs, gateway state, and other Hermes
|
||||
data.
|
||||
- `HOME` is the operating-system/user home that external CLIs expect. On host
|
||||
installs, Hermes keeps it as the real user home by default so tools like
|
||||
`git`, `ssh`, `gh`, `az`, `npm`, Claude Code, and Codex find the same
|
||||
credentials they use in your normal shell.
|
||||
|
||||
The tradeoff is that host profiles share normal user-level CLI state by default.
|
||||
If you need separate CLI identities per profile, set `terminal.home_mode:
|
||||
profile` in that profile's `config.yaml`. In that mode Hermes launches tool
|
||||
subprocesses with `HOME={HERMES_HOME}/home`; you then need to initialize or link
|
||||
the profile-specific `~/.ssh`, `~/.gitconfig`, `~/.config/gh`, cloud CLI auth,
|
||||
Claude/Codex auth, npm state, and similar files inside that profile home.
|
||||
|
||||
Hermes also exposes `HERMES_REAL_HOME` to subprocesses so scripts can still find
|
||||
the actual account home when `home_mode: profile` is active.
|
||||
|
||||
The default profile is simply `~/.hermes` itself. No migration needed — existing installs work identically.
|
||||
|
||||
## Sharing profiles as distributions
|
||||
|
||||
Reference in New Issue
Block a user