diff --git a/skills/social-media/xurl/SKILL.md b/skills/social-media/xurl/SKILL.md index 2fe23ef8575..257e86af34f 100644 --- a/skills/social-media/xurl/SKILL.md +++ b/skills/social-media/xurl/SKILL.md @@ -38,7 +38,7 @@ Critical rules when operating inside an agent/LLM session: - **Never** read, print, parse, summarize, upload, or send `~/.xurl` to LLM context. - **Never** ask the user to paste credentials/tokens into chat. -- The user must fill `~/.xurl` with secrets manually on their own machine. +- The user must fill `~/.xurl` with secrets manually on their own machine. In Docker, this must be the `~` seen by Hermes tool subprocesses; see the Docker note below. - **Never** recommend or execute auth commands with inline secrets in agent sessions. - **Never** use `--verbose` / `-v` in agent sessions — it can expose auth headers/tokens. - To verify credentials exist, only use: `xurl auth status`. @@ -115,6 +115,15 @@ After this, the agent can use any command below without further setup. OAuth 2.0 > **Common pitfall:** If you omit `--app my-app` from `xurl auth oauth2`, the OAuth token is saved to the built-in `default` app profile — which has no client-id or client-secret. Commands will fail with auth errors even though the OAuth flow appeared to succeed. If you hit this, re-run `xurl auth oauth2 --app my-app` and `xurl auth default my-app`. +> **Docker HOME pitfall:** In the official Hermes Docker layout, `/opt/data` is `HERMES_HOME`, but Hermes tool subprocesses use `/opt/data/home` as `HOME`. That means `~/.xurl` resolves to `/opt/data/home/.xurl` for Hermes-run `xurl` commands, not `/opt/data/.xurl`. Run the user setup with the same HOME: +> ```bash +> HOME=/opt/data/home xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET +> HOME=/opt/data/home xurl auth oauth2 --app my-app YOUR_USERNAME +> HOME=/opt/data/home xurl auth default my-app YOUR_USERNAME +> HOME=/opt/data/home xurl auth status +> ``` +> If `HOME=/opt/data xurl auth status` succeeds but `HOME=/opt/data/home xurl auth status` shows no apps or tokens, Hermes tool calls will not see the credentials. + --- ## Quick Reference @@ -402,7 +411,7 @@ xurl --app staging /2/users/me # one-off against staging - **Token refresh:** OAuth 2.0 tokens auto-refresh. Nothing to do. - **Multiple apps:** Each app has isolated credentials/tokens. Switch with `xurl auth default` or `--app`. - **Multiple accounts per app:** Select with `-u / --username`, or set a default with `xurl auth default APP USER`. -- **Token storage:** `~/.xurl` is YAML. Never read or send this file to LLM context. +- **Token storage:** `~/.xurl` is YAML. In Docker, use the Hermes subprocess HOME (`/opt/data/home` in the official image) so tokens land under `/opt/data/home/.xurl`. Never read or send this file to LLM context. - **Cost:** X API access is typically paid for meaningful usage. Many failures are plan/permission problems, not code problems. --- diff --git a/website/docs/user-guide/docker.md b/website/docs/user-guide/docker.md index 381e5da757d..e92ab685dfe 100644 --- a/website/docs/user-guide/docker.md +++ b/website/docs/user-guide/docker.md @@ -123,11 +123,14 @@ The `/opt/data` volume is the single source of truth for all Hermes state. It ma | `sessions/` | Conversation history | | `memories/` | Persistent memory store | | `skills/` | Installed skills | +| `home/` | Per-profile HOME for Hermes tool subprocesses (`git`, `ssh`, `gh`, `npm`, and skill CLIs) | | `cron/` | Scheduled job definitions | | `hooks/` | Event hooks | | `logs/` | Runtime logs | | `skins/` | Custom CLI skins | +Skill CLIs that store credentials under `~` must be initialized against the subprocess HOME, not just the data-volume root. For example, the [xurl skill](./skills/bundled/social-media/social-media-xurl.md) stores OAuth state in `~/.xurl`; in the official Docker layout, Hermes tool calls read that as `/opt/data/home/.xurl`, so run manual xurl auth with `HOME=/opt/data/home` and verify with `HOME=/opt/data/home xurl auth status`. + :::warning Never run two Hermes **gateway** containers against the same data directory simultaneously — session files and memory stores are not designed for concurrent write access. ::: diff --git a/website/docs/user-guide/skills/bundled/social-media/social-media-xurl.md b/website/docs/user-guide/skills/bundled/social-media/social-media-xurl.md index 15ab18eea7f..9bbfffc291f 100644 --- a/website/docs/user-guide/skills/bundled/social-media/social-media-xurl.md +++ b/website/docs/user-guide/skills/bundled/social-media/social-media-xurl.md @@ -52,7 +52,7 @@ Critical rules when operating inside an agent/LLM session: - **Never** read, print, parse, summarize, upload, or send `~/.xurl` to LLM context. - **Never** ask the user to paste credentials/tokens into chat. -- The user must fill `~/.xurl` with secrets manually on their own machine. +- The user must fill `~/.xurl` with secrets manually on their own machine. In Docker, this must be the `~` seen by Hermes tool subprocesses; see the Docker note below. - **Never** recommend or execute auth commands with inline secrets in agent sessions. - **Never** use `--verbose` / `-v` in agent sessions — it can expose auth headers/tokens. - To verify credentials exist, only use: `xurl auth status`. @@ -129,6 +129,15 @@ After this, the agent can use any command below without further setup. OAuth 2.0 > **Common pitfall:** If you omit `--app my-app` from `xurl auth oauth2`, the OAuth token is saved to the built-in `default` app profile — which has no client-id or client-secret. Commands will fail with auth errors even though the OAuth flow appeared to succeed. If you hit this, re-run `xurl auth oauth2 --app my-app` and `xurl auth default my-app`. +> **Docker HOME pitfall:** In the official Hermes Docker layout, `/opt/data` is `HERMES_HOME`, but Hermes tool subprocesses use `/opt/data/home` as `HOME`. That means `~/.xurl` resolves to `/opt/data/home/.xurl` for Hermes-run `xurl` commands, not `/opt/data/.xurl`. Run the user setup with the same HOME: +> ```bash +> HOME=/opt/data/home xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET +> HOME=/opt/data/home xurl auth oauth2 --app my-app YOUR_USERNAME +> HOME=/opt/data/home xurl auth default my-app YOUR_USERNAME +> HOME=/opt/data/home xurl auth status +> ``` +> If `HOME=/opt/data xurl auth status` succeeds but `HOME=/opt/data/home xurl auth status` shows no apps or tokens, Hermes tool calls will not see the credentials. + --- ## Quick Reference @@ -416,7 +425,7 @@ xurl --app staging /2/users/me # one-off against staging - **Token refresh:** OAuth 2.0 tokens auto-refresh. Nothing to do. - **Multiple apps:** Each app has isolated credentials/tokens. Switch with `xurl auth default` or `--app`. - **Multiple accounts per app:** Select with `-u / --username`, or set a default with `xurl auth default APP USER`. -- **Token storage:** `~/.xurl` is YAML. Never read or send this file to LLM context. +- **Token storage:** `~/.xurl` is YAML. In Docker, use the Hermes subprocess HOME (`/opt/data/home` in the official image) so tokens land under `/opt/data/home/.xurl`. Never read or send this file to LLM context. - **Cost:** X API access is typically paid for meaningful usage. Many failures are plan/permission problems, not code problems. ---