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:
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:
~/.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:
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_CHATSauthorizes specific groups at group scope.TELEGRAM_ALLOWED_CHATScan additionally restrict which group chats the bot responds in.TELEGRAM_REQUIRE_MENTION=truemakes the bot respond only when explicitly addressed in groups.TELEGRAM_OBSERVE_UNMENTIONED_GROUP_MESSAGES=truelets 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:
platform_toolsets:
telegram:
- browser
- clarify
- code_execution
- cronjob
- delegation
- file
- image_gen
- messaging
- terminal
- todo
- tts
- vision
- web
Intentionally omitted:
memory
session_search
skills
computer_use
Rationale:
memorymay expose or mutate durable operator facts.session_searchmay retrieve private historical conversations.skillsmay expose private procedures or allow skill modification.computer_usecan 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:
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:
# 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:
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:
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:
- Add the bot to the group.
- Disable BotFather privacy if normal chatter should be visible.
- Stop the Hermes gateway temporarily.
- Send a message in the group mentioning the bot.
- Call Telegram
getUpdatesto capture the groupchat.id. - Add that ID to
TELEGRAM_GROUP_ALLOWED_CHATSandTELEGRAM_ALLOWED_CHATS. - 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:
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
/workspacevolume. - [ ]
docker_forward_envis 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
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_searchenabled. 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.