Safety Patterns: Composing Restrictions

+15 Mana ✨

Introduction

The individual layers are useful. The patterns are what make a deployment defensible. A safety pattern is a small recipe combining toolset, approval, isolation, and authorization decisions for a specific kind of deployment. Recognizing the pattern saves you from designing from scratch every time.

Key Concepts

  • Safety pattern: A reusable combination of restrictions for a recurring deployment shape.
  • Composition: Stacking multiple layers so each one covers a different failure mode.
  • Recipe: A short, opinionated config that solves a class of problem (research bot, dev assistant, family chatbot).

Real World Context

Most real Hermes deployments fall into one of three or four patterns. Naming them turns design into selection. I am building a public research bot is the question. Use the public-research pattern is the answer.

Deep Dive

Four safety patterns that cover most cases:

Pattern 1: Local Power User (you on your machine).

  • Toolset: hermes-cli (full dev).
  • Approvals: smart or manual (your preference).
  • Container: none (you are working on your own files).
  • Authorization: none (no gateway).

Good for development. The only realistic threat is yourself; the layers protect against typos and confused agent moves.

Pattern 2: Personal Chat Bot (you on Telegram, plus a few friends).

  • Toolset: safe plus memory plus any narrow integrations you trust.
  • Approvals: manual (because you cannot review every command in real time on chat).
  • Container: optional, recommended if the bot touches anything sensitive.
  • Authorization: GATEWAY_ALLOWED_USERS set to specific user IDs, or DM pairing.

Good for chat with my Hermes from my phone. Approvals over chat are awkward, so the better lever is a narrow toolset that does not include dangerous commands at all.

Pattern 3: Public Research Bot (strangers can talk to it).

  • Toolset: safe (and only safe).
  • Approvals: manual (or off only if the toolset cannot do anything destructive anyway).
  • Container: yes. Use terminal.backend: docker even if the toolset omits terminal, as defense for any future loosening.
  • Authorization: allowlist is impossible (it is public). Rely on the narrow toolset instead.

Good for here is a Discord bot that answers questions about our docs. The toolset is the whole defense; everything else is backup.

Pattern 4: Production Gateway (your team plus customers).

  • Toolset: platform preset tightened to the bare minimum.
  • Approvals: manual.
  • Container: yes, with explicit resource limits (container_cpu, container_memory, container_disk).
  • Authorization: per-platform allowlists, DM pairing for new users.
  • Plus: website blocklist, Tirith pre-exec scanning enabled, MCP credential filtering audited.

Good for we run a Hermes-based assistant for our customers. Every layer is on. Document which ones are active and why.

The meta-principle: layer choices should be deliberate. If a layer is off, that is a decision, not an oversight. Write it down.

Common Pitfalls

  1. Mixing patterns without thinking: Pulling pieces from Local Power User into a gateway config is how surface trust assumptions break.
  2. Treating the pattern as final: Patterns are starting points. As the deployment grows (more users, more sensitive data), revisit and tighten.

Best Practices

  1. Pick a pattern, then justify deviations: Start from a named pattern, document any change in a comment, and re-audit when you change them.
  2. Re-audit when the trust level changes: A new platform, a new MCP, a new user group is all triggers for a fresh look.

Summary

  • Safety patterns are reusable combinations of restrictions for common deployment shapes.
  • Four useful patterns: Local Power User, Personal Chat Bot, Public Research Bot, Production Gateway.
  • Start from a pattern, then document deviations.
  • Defense in depth is most reliable when the combination is deliberate.

Code Examples

yaml
# Pattern: Public Research Bot
# - safe toolset is the entire capability surface
# - container backend just in case the toolset is loosened later
# - approvals stay manual even though terminal is not loaded
# - allowlist is intentionally omitted: this is public

approvals:
  mode: manual

terminal:
  backend: docker

toolsets:
  - safe

security:
  website_blocklist:
    enabled: true
  tirith_enabled: true
✓ Completed