[[
wikihub
]]
Search
⌘K
Explore
People
For Agents
Sign in
Explore
People
For Agents
Sign in
×
@jacobcole / Knowledge Publishing Architecture / wiki/hermes-multi-tier-bot-architecture.md
Suggest edit
Cancel
Submit suggestion
Title
Name
Note
--- title: Privacy-Preserving Multi-Tier Hermes Bot Architecture visibility: public --- # Privacy-Preserving Multi-Tier Hermes Bot Architecture A reference architecture for running multiple Hermes Agent bots for different audiences—private, close friends, friends, and public—without leaking the operator's private memory, sessions, files, credentials, or home machine access. The core idea is simple: **do not expose your real private Hermes instance to other people.** Instead, create separate Hermes profiles with separate bot credentials, separate memory/session stores, and sandboxed tool access. Treat each audience tier as a separate security boundary. ## Goals - Friends can message a useful Hermes-powered bot. - The operator's private Hermes memory, conversations, files, and credentials remain isolated. - Higher-trust groups can get more capabilities than public users. - Bots can build small projects, but only inside a sandboxed workspace. - Any bot-initiated outbound messaging uses an approval queue, not direct unsupervised access to the operator's accounts. ## Threat model Assume that any non-private bot may receive: - Prompt-injection attempts. - Requests to reveal system prompts, memory, sessions, environment variables, or files. - Attempts to use tools to escape its intended workspace. - Attempts to send messages as the operator. - Accidental private context pasted by friends. Therefore, isolation should not rely only on a friendly system prompt. Use process, profile, filesystem, credentials, and tool boundaries. ## Tier model | Tier | Audience | Example capabilities | Isolation posture | |---|---|---|---| | Private | Only the operator | Full personal assistant; private memory; normal local tools | Main Hermes profile; not exposed to friends | | Close friends | Small trusted group | Chat, research, lightweight coding/building, shared project workspace | Separate Hermes profile; separate bot token; Docker terminal; no private session search | | Friends | Larger friend group | Similar but less personal context and stricter approval | Separate profile; separate bot token; Docker terminal; public/shared context only | | Public | Internet / website / public bot | Answer docs, create small artifacts, maybe API-backed web chat | Separate profile; strongest sandbox; no private memory; no direct secrets in client-side code | ## Profile-per-tier pattern Use Hermes profiles as the first isolation layer: ```bash hermes profile create close-friends-bot --clone default hermes profile create friends-bot --clone default hermes profile create public-bot --clone default ``` Then strip each non-private profile down to only the tools and credentials that tier needs. Do **not** reuse the private profile's messaging bot token. Suggested profile layout: ```text ~/.hermes/ config.yaml # private/default Hermes profile .env # private/default credentials profiles/ close-friends-bot/ config.yaml .env # only this tier's bot token + non-private keys sessions/ state.db friends-bot/ config.yaml .env public-bot/ config.yaml .env ``` Each profile has its own session database, memory files, skills, cron jobs, and gateway config. This prevents friend-facing sessions from automatically seeing the operator's private conversations. ## Use separate messaging bot credentials Create a separate Telegram/Discord/etc. bot identity for each non-private tier. Do **not** point friends at the same bot token used by your private assistant. Example `.env` shape for a Telegram-based friend bot: ```dotenv TELEGRAM_BOT_TOKEN=<bot-token-for-this-tier-only> TELEGRAM_ALLOWED_USERS=<comma-separated-user-ids-if-using-DM-allowlist> TELEGRAM_GROUP_ALLOWED_CHATS=<comma-separated-group-chat-ids> TELEGRAM_ALLOWED_CHATS=<comma-separated-group-chat-ids> TELEGRAM_REQUIRE_MENTION=true TELEGRAM_OBSERVE_UNMENTIONED_GROUP_MESSAGES=true TELEGRAM_HOME_CHANNEL=<operator-dm-or-admin-channel-id> TELEGRAM_HOME_CHANNEL_NAME=<human-readable-name> ``` Notes: - `TELEGRAM_GROUP_ALLOWED_CHATS` authorizes specific groups at group scope. - `TELEGRAM_ALLOWED_CHATS` can additionally restrict which group chats the bot responds in. - `TELEGRAM_REQUIRE_MENTION=true` makes the bot respond only when explicitly addressed in groups. - `TELEGRAM_OBSERVE_UNMENTIONED_GROUP_MESSAGES=true` lets the bot use normal group chatter as context while staying quiet until mentioned. - If using Telegram BotFather privacy mode, disable privacy for tiers that need to observe normal group chatter. With privacy on, the bot typically only receives commands, replies, and direct mentions. ## Toolset hardening For friend/public profiles, remove access to private-context tools and host-control tools unless they are explicitly needed. Recommended removals for non-private Telegram profiles: ```yaml platform_toolsets: telegram: - browser - clarify - code_execution - cronjob - delegation - file - image_gen - messaging - terminal - todo - tts - vision - web ``` Intentionally omitted: ```text memory session_search skills computer_use ``` Rationale: - `memory` may expose or mutate durable operator facts. - `session_search` may retrieve private historical conversations. - `skills` may expose private procedures or allow skill modification. - `computer_use` can interact with the operator's desktop and should not be friend-facing. Adjust this list based on your risk tolerance. The important principle is that every exposed tool should be safe under hostile prompts. ## Docker sandbox for terminal and file tools For any tier that can run shell commands or write files, use a container backend and mount only a dedicated shared workspace. Example Hermes `config.yaml` / equivalent terminal config: ```yaml terminal: backend: docker cwd: /workspace docker_image: nikolaik/python-nodejs:python3.11-nodejs20 docker_volumes: - /path/to/shared/workspace/close-friends-bot:/workspace docker_mount_cwd_to_workspace: false docker_forward_env: [] docker_run_as_host_user: false container_cpu: 2 container_memory: 4096 container_persistent: true lifetime_seconds: 300 ``` Security properties to verify: ```bash # From inside that profile's Hermes terminal tool/session: pwd # should be /workspace printenv | sort # should not include bot tokens or API server keys ls /workspace # should show only the shared workspace ``` The important details are: - `docker_forward_env: []` so gateway secrets do not enter the container. - A single explicit volume for the workspace. - No mount of the operator's home directory. - CPU/memory limits so public use cannot exhaust the host. ## Approval-based outbox for sending messages Do not give friend/public bots direct unsupervised access to send messages as the operator. Use an outbox pattern: ```text workspace/ outbox/ drafts/ # bot can create proposed messages here approved/ # operator moves reviewed messages here sent/ # sender moves successfully delivered messages here rejected/ # optional: operator or sender moves rejected drafts here ``` A separate trusted script or cron job watches `approved/` and sends messages. The bot can draft, but the human approves. This pattern is especially important for: - iMessage/SMS. - Email. - Posting to group chats. - Any account that has the operator's real identity. ## Group-chat behavior A useful group configuration is: ```dotenv TELEGRAM_REQUIRE_MENTION=true TELEGRAM_OBSERVE_UNMENTIONED_GROUP_MESSAGES=true ``` This gives the group a natural UX: - Ordinary chatter is ingested as context. - The bot does not interrupt every message. - The bot responds when mentioned, replied to, or invoked with a command. Operational steps for Telegram: 1. Add the bot to the group. 2. Disable BotFather privacy if normal chatter should be visible. 3. Stop the Hermes gateway temporarily. 4. Send a message in the group mentioning the bot. 5. Call Telegram `getUpdates` to capture the group `chat.id`. 6. Add that ID to `TELEGRAM_GROUP_ALLOWED_CHATS` and `TELEGRAM_ALLOWED_CHATS`. 7. Restart the gateway. Use placeholders in documentation; never publish real group IDs. ## Public website bot pattern For a website-facing public bot, do not put the Hermes API key in browser JavaScript. Use: ```text browser → your backend/proxy → Hermes API server ``` The backend can: - Hold the API key server-side. - Rate-limit requests. - Add abuse detection. - Restrict tools and prompts. - Log only public-safe metadata. A public bot profile should have the smallest possible toolset and only public documentation/context. ## Capability ladder One way to think about tiers: ### Level 0 — Answer-only - No terminal. - No file writes. - Public docs only. - Good for websites and unknown users. ### Level 1 — Shared context assistant - Web/search tools allowed. - No shell or filesystem. - Useful for group Q&A. ### Level 2 — Sandboxed builder - Terminal/file tools allowed only inside Docker `/workspace`. - No private memory/session search. - Approval outbox for external side effects. - Good for close friends building small artifacts. ### Level 3 — Trusted collaborator - More tools and context, but still a separate profile. - Consider manual approvals for dangerous commands. - Still avoid private profile credentials unless truly intended. ### Level 4 — Private operator assistant - Full personal memory and host tools. - Not exposed to friends or public users. ## Verification checklist Before inviting anyone: - [ ] The tier uses a separate Hermes profile. - [ ] The tier uses a separate messaging bot token. - [ ] The bot token is stored only in that profile's `.env`. - [ ] Gateway starts with the intended profile, not default/private. - [ ] Group/DM allowlists are configured. - [ ] Private-memory tools are removed from friend/public platform toolsets. - [ ] Terminal backend is Docker, not local. - [ ] Docker has only the intended `/workspace` volume. - [ ] `docker_forward_env` is empty or strictly allowlisted. - [ ] A test shell inside the sandbox cannot see Telegram tokens or API keys. - [ ] Outbound messaging uses an approval queue. - [ ] Public website integrations keep API keys server-side. - [ ] Logs and published docs use placeholders, not real IDs, tokens, usernames, phone numbers, or paths. ## Sanitized example structure ```text shared-workspaces/ close-friends-bot/ README.md projects/ outbox/ drafts/ approved/ sent/ rejected/ friends-bot/ README.md outbox/ drafts/ approved/ sent/ public-bot/ README.md public-context/ ``` ## Common pitfalls - **Using the private bot token for friends.** This collapses the identity boundary. - **Leaving `session_search` enabled.** This can expose private conversations. - **Mounting the home directory into Docker.** This defeats much of the sandbox. - **Forwarding all environment variables into Docker.** Tokens become tool-visible. - **Putting a Hermes API key in frontend JS.** Anyone can copy it. - **Assuming Telegram group messages arrive with privacy mode on.** Disable BotFather privacy if normal chatter must be observed. - **Letting the bot send messages directly as the operator.** Use an approval outbox. ## Summary The safest pattern is not “one bot with a careful prompt.” It is **many small Hermes profiles, one per trust tier**, each with its own credentials, memory, tools, and workspace. Use profile isolation for context, separate bot credentials for identity, Docker for command execution, allowlists for group membership, and a human-approved outbox for side effects. That gives friends a useful bot while keeping the private assistant private.