# How to Set Up the Hermes Sidecar as a Second Front Door to LifeOS

> Learn to set up the Hermes sidecar as a second front door to LifeOS. Mount your existing LifeOS into a separate Hermes process, reusing constitution, identity, and skills without duplication.

- Repository: [Daniel Miessler 🛡️/LifeOS](https://github.com/danielmiessler/LifeOS)
- Tags: how-to-guide
- Published: 2026-08-12

---

**The Hermes sidecar is an optional second entry point that mounts your existing LifeOS installation into a separate Hermes process, re-using the same constitution, identity, and skills without creating a duplicate assistant.**

This guide walks you through installing the Hermes sidecar in danielmiessler/LifeOS—an architecture that adds a terminal-based gateway to your LifeOS brain while keeping secrets protected through a multi-layer guard system. Unlike bots that duplicate prompts and drift, the sidecar supplies only **engine and messaging channels** while LifeOS retains full control over identity, policies, and skills.

## Architecture Overview

The sidecar creates a read-only mount of your LifeOS tree with strict write isolation. Understanding this architecture helps clarify why the setup process works the way it does.

```

LifeOS install (read-only to the sidecar)          Hermes install
├── LIFEOS/HERMES/            ← sidecar code         $HERMES_HOME (default ~/.hermes)
│   ├── Policy.ts            deny-set definition   ├── SOUL.md        ← generated identity
│   ├── RenderSoul.ts        constitution+identity ├── config.yaml    ← patched
│   ├── Mount.ts             installer/sync        ├── .env           ← sandbox env
│   └── plugin/              the guard             └── cron/          ← read by Pulse
├── LIFEOS/USER/             ← user content (never code)
└── skills/                  ← mounted read-only
$HERMES_WORKSPACE (default ~/HermesWorkspace)   ← only writable scratch

```

- **LifeOS tree** — Read-only source of truth that the sidecar references
- **`$HERMES_HOME`** (`~/.hermes`) — Contains generated files: [`SOUL.md`](https://github.com/danielmiessler/LifeOS/blob/main/SOUL.md), guard plugin, and patched [`config.yaml`](https://github.com/danielmiessler/LifeOS/blob/main/config.yaml)
- **`$HERMES_WORKSPACE`** (`~/HermesWorkspace`) — The **only** directory the sidecar may write to; enforced by the guard

### Four Security Controls in the Mount

| Control | Implementation |
|---------|---------------|
| **Read guard (`pre_tool_call`)** | Blocks tool calls touching credential material (`*.env`, [`auth.json`](https://github.com/danielmiessler/LifeOS/blob/main/auth.json), `~/.ssh/**`). Generated by [`Policy.ts`](https://github.com/danielmiessler/LifeOS/blob/main/Policy.ts). |
| **Write sandbox** | `HERMES_WRITE_SAFE_ROOT` restricts writes to `$HERMES_WORKSPACE` + `$HERMES_HOME`. |
| **Typed write API** (planned) | Future writes route through LifeOS memory API with tiered rules. |
| **Provenance tainting** (required before messaging) | Marks inbound text as *tainted*; tainted turns cannot make privileged calls. |

> The guard's deny list is **reconciled**, not merely seeded—preventing stale globs from silently breaking functionality. See [`LifeOS/install/LIFEOS/HERMES/Policy.ts`](https://github.com/danielmiessler/LifeOS/blob/main/LifeOS/install/LIFEOS/HERMES/Policy.ts) for the definitive source.

## Prerequisites

Before starting the Hermes sidecar setup:

- Existing LifeOS installation at `$HOME/.claude` (or custom `$LIFEOS_ROOT`)
- `bun` runtime installed
- `python3` available for guard testing

## Step-by-Step Installation

### 1. Install Hermes (Pinned Version)

Download and run the installer with flags that skip interactive setup and browser installation:

```bash
curl -fsSL https://hermes-agent.nousresearch.com/install.sh -o install.sh

# Review the script, then:

bash install.sh --non-interactive --skip-setup --skip-browser --commit <reviewed-sha>

```

Replace `<reviewed-sha>` with a specific commit hash you've audited. Never install unpinned versions in production.

### 2. Authenticate Hermes with Fresh Device-Code Login

Create a separate credential set—never import tokens from other tools:

```bash
hermes auth add openai-codex --type oauth --no-browser

```

This follows the "secrets are used, never seen" principle: credentials stay in Hermes's environment, not in model context.

### 3. Mount LifeOS into Hermes

Run the idempotent mount script from your LifeOS directory:

```bash
bun LIFEOS/HERMES/Mount.ts

```

This script located at [`LifeOS/install/LIFEOS/HERMES/Mount.ts`](https://github.com/danielmiessler/LifeOS/blob/main/LifeOS/install/LIFEOS/HERMES/Mount.ts) performs four operations:

- Renders [`SOUL.md`](https://github.com/danielmiessler/LifeOS/blob/main/SOUL.md) from your constitution and identity
- Installs the guard plugin to `~/.hermes/plugins/lifeos/`
- Patches [`config.yaml`](https://github.com/danielmiessler/LifeOS/blob/main/config.yaml) with sidecar-specific settings
- Creates the write-sandbox root at `$HERMES_WORKSPACE`

### 4. Verify the Mount (Optional)

Check for configuration drift without making changes:

```bash
bun LIFEOS/HERMES/Mount.ts --check

```

### 5. Run Guard Unit Tests (Optional)

Validate that the read-guard correctly enforces deny rules:

```bash
python3 LIFEOS/HERMES/plugin/test_guard.py

```

### 6. Create and Use the Launcher

The sidecar **must** start from the LifeOS root to see the mounted tree. Create a launcher script on your `$PATH`:

```bash
#!/usr/bin/env bash
set -euo pipefail

LIFEOS_ROOT="${LIFEOS_ROOT:-$HOME/.claude}"

[ -d "$LIFEOS_ROOT" ] || { 
    echo "no LifeOS install at $LIFEOS_ROOT" >&2; 
    exit 1; 
}

[ -f "$HOME/.hermes/plugins/lifeos/policy.json" ] || {
    echo "sidecar guard not installed — run: bun $LIFEOS_ROOT/LIFEOS/HERMES/Mount.ts" >&2; 
    exit 1; 
}

cd "$LIFEOS_ROOT"
exec hermes "$@"

```

Save as `~/.local/bin/<da-name>` (e.g., `~/.local/bin/myda`), make executable, then run:

```bash
myda hermes <your-command>

```

Never invoke `hermes` directly—bypassing the launcher breaks the mount visibility.

## Health Monitoring and Operations

### Check Sidecar Status

Human-readable status:

```bash
bun LIFEOS/HERMES/Health.ts

```

Deterministic status values: `up`, `degraded`, `flapping`, `down`, `absent`.

JSON output for automation:

```bash
bun LIFEOS/HERMES/Health.ts --json

```

### Assert Liveness in Scripts

Exit code 0 only when safe to proceed:

```bash
bun LIFEOS/HERMES/Health.ts --assert-live

```

Prevent crash-loop restarter from masking problems:

```bash
bun LIFEOS/HERMES/Health.ts --assert-no-restarter

```

### Pulse Integration

The sidecar registers as background service `ai.hermes.gateway` in the LifeOS menu bar and Pulse dashboard. The Bunker app monitors the restarter and flapping conditions, paging on critical failures.

## Complete Command Reference

```bash

# Install Hermes (pinned, audited version)

curl -fsSL https://hermes-agent.nousresearch.com/install.sh -o install.sh
bash install.sh --non-interactive --skip-setup --skip-browser --commit a1b2c3d4e5f6

# Authenticate with fresh device-code flow

hermes auth add openai-codex --type oauth --no-browser

# Mount LifeOS (idempotent)

bun LIFEOS/HERMES/Mount.ts

# Verify mount without changes

bun LIFEOS/HERMES/Mount.ts --check

# Health check (human-readable)

bun LIFEOS/HERMES/Health.ts

# Health check (JSON for automation)

bun LIFEOS/HERMES/Health.ts --json

# Run guard unit test

python3 LIFEOS/HERMES/plugin/test_guard.py

# Uninstall sidecar completely

hermes plugins disable lifeos
rm -rf ~/.hermes
rm -rf ~/HermesWorkspace
rm -f ~/.local/bin/<DA_NAME>

```

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`LifeOS/install/LIFEOS/HERMES/Mount.ts`](https://github.com/danielmiessler/LifeOS/blob/main/LifeOS/install/LIFEOS/HERMES/Mount.ts) | Main installer—renders soul, patches config, installs guard, creates sandbox |
| [`LifeOS/install/LIFEOS/HERMES/Health.ts`](https://github.com/danielmiessler/LifeOS/blob/main/LifeOS/install/LIFEOS/HERMES/Health.ts) | Deterministic health probe with `--assert-live` and `--assert-no-restarter` flags |
| [`LifeOS/install/LIFEOS/HERMES/Policy.ts`](https://github.com/danielmiessler/LifeOS/blob/main/LifeOS/install/LIFEOS/HERMES/Policy.ts) | Source of read-guard deny list and shell-deny globs |
| [`LifeOS/install/LIFEOS/HERMES/plugin/guard.py`](https://github.com/danielmiessler/LifeOS/blob/main/LifeOS/install/LIFEOS/HERMES/plugin/guard.py) | Runtime Python guard (installed to `~/.hermes/plugins/lifeos/guard.py`) |
| [`LifeOS/install/LIFEOS/HERMES/RenderSoul.ts`](https://github.com/danielmiessler/LifeOS/blob/main/LifeOS/install/LIFEOS/HERMES/RenderSoul.ts) | Generates [`SOUL.md`](https://github.com/danielmiessler/LifeOS/blob/main/SOUL.md) from constitution + identity |

## Summary

- The **Hermes sidecar** is a read-only mount, not a second assistant—one brain, multiple entry points
- **Four controls** protect secrets: read guard, write sandbox, typed write API, and provenance tainting
- Always use **pinned Hermes versions** with `--commit` and **fresh device-code authentication**
- Run [`Mount.ts`](https://github.com/danielmiessler/LifeOS/blob/main/Mount.ts) from `LifeOS/install/LIFEOS/HERMES/` to render identity, install guard, and create sandbox
- **Never invoke `hermes` directly**—use a launcher that validates guard presence and starts from LifeOS root
- Monitor with [`Health.ts`](https://github.com/danielmiessler/LifeOS/blob/main/Health.ts) and integrate with Pulse for production alerting

## Frequently Asked Questions

### What happens if I run Hermes without the launcher?

The sidecar cannot locate the mounted LifeOS tree, causing skill failures and potential policy violations. The launcher ensures `$LIFEOS_ROOT` is the working directory and confirms the guard plugin exists.

### Why can't the sidecar write to the LifeOS tree?

All writes route through `$HERMES_WORKSPACE` or `$HERMES_HOME` by design. This prevents credential leakage through prompt injection—since the model never sees secrets, it cannot be tricked into exfiltrating them.

### How do I update the sidecar after upgrading Hermes?

Re-run `bun LIFEOS/HERMES/Mount.ts`—it's idempotent. The mount refreshes the guard plugin and regenerated files without touching your LifeOS core. Verify with `--check` before and after.

### Is the sidecar ready for messaging channels like Slack or email?

Not yet—**provenance tainting** must be implemented first. This marks inbound text as tainted and blocks privileged calls from tainted turns. Until then, restrict the sidecar to terminal use only.