Prerequisites
- Hermes Agent installed (see macOS guide)
- At least one API key from a model provider (see model provider guide)
- Terminal access to the machine running Hermes
- ~10 minutes for initial secure setup
Step 1: Store keys in ~/.hermes/.env with strict permissions
Hermes Agent reads credentials from ~/.hermes/.env. This file should never be world-readable. Create it with restricted permissions:
# Create the .env file if it doesn't exist touch ~/.hermes/.env # Restrict permissions — owner read/write only (chmod 600) chmod 600 ~/.hermes/.env # Verify permissions ls -la ~/.hermes/.env # Should show: -rw------- 1 you staff ... .env
Add your API keys to this file, one per line:
# ~/.hermes/.env # Model providers OPENROUTER_API_KEY=sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxx ANTHROPIC_API_KEY=sk-ant-api03-xxxxxxxxxxxxxxxxxxxxxxxxxxxx OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxx # Gateways (if using) TELEGRAM_BOT_TOKEN=1234567890:xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Never paste API keys directly into config.yaml or any file that might be committed to version control. Always reference them via environment variables.
Step 2: Reference keys via environment variables — never hardcode
In your ~/.hermes/config.yaml, use environment variable substitution instead of hardcoded values:
# ✅ DO THIS — reference environment variables
provider: openrouter
model: anthropic/claude-sonnet-4
gateway:
telegram:
enabled: true
token: ${TELEGRAM_BOT_TOKEN}# ❌ DON'T DO THIS — hardcoded secrets in config files provider: openrouter model: anthropic/claude-sonnet-4 api_key: sk-or-v1-abc123def456 # NEVER hardcode keys!
The ${VARIABLE_NAME} syntax tells Hermes to read the value from the environment (which it loads from .env). This keeps secrets out of your config file — which is especially important if you ever share or back up your configuration.
.env file.Step 3: Establish a key rotation schedule
API keys should be rotated regularly — treat them like passwords. A quarterly rotation schedule is a good baseline:
- Every 90 days: Generate a new API key from your provider's dashboard
- Update
~/.hermes/.envwith the new key - Revoke the old key from the provider dashboard immediately after confirming the new key works
- Test: Run
hermesand send a test prompt to confirm the new key is active
Set a recurring calendar reminder. Many providers let you create multiple keys — you can generate the new key ahead of time, test it, and then revoke the old one with zero downtime.
Rotate immediately (don't wait for the schedule) if:
- A team member who had access leaves the organization
- You suspect a key may have been exposed (pasted in a chat, included in a screenshot, committed to a repo)
- Your machine is lost, stolen, or compromised
- A provider notifies you of a security incident
Step 4: Use 1Password CLI for team environments
If you're managing Hermes across multiple machines or on a team, storing secrets in a plain .env file isn't ideal. 1Password CLI provides a more robust approach:
# Install 1Password CLI brew install --cask 1password-cli # Sign in (requires 1Password account) op signin # Retrieve a secret and inject it into the environment export OPENROUTER_API_KEY=$(op read "op://Private/OpenRouter/API Key")
For a more seamless setup, create a wrapper script that fetches keys at startup:
#!/bin/bash # ~/.hermes/load-secrets.sh # Source this before running Hermes to populate API keys from 1Password export OPENROUTER_API_KEY=$(op read "op://Private/OpenRouter/API Key" 2>/dev/null) export ANTHROPIC_API_KEY=$(op read "op://Private/Anthropic/API Key" 2>/dev/null) export OPENAI_API_KEY=$(op read "op://Private/OpenAI/API Key" 2>/dev/null) # Then run: source ~/.hermes/load-secrets.sh && hermes
Benefits of 1Password CLI over a plain .env file:
- Encrypted at rest: Secrets are stored in 1Password's encrypted vault, not in a plaintext file on disk
- Audit trail: Track who accessed which credential and when
- Shared vaults: Securely share API keys with team members without pasting them into Slack or email
- Revocation: Remove a team member's vault access and they lose access to all keys instantly
Step 5: Understand provider-specific key formats
Each provider uses a distinct API key format. Knowing the patterns helps you identify which key goes where and spot potential exposure:
| Provider | Key prefix | Example pattern |
|---|---|---|
| OpenRouter | sk-or-v1- | sk-or-v1- + alphanumeric string |
| Anthropic | sk-ant-api03- | sk-ant-api03- + alphanumeric string |
| OpenAI | sk-proj- or sk- | sk-proj- + alphanumeric string |
| Telegram | Numeric ID + colon | 1234567890:AA + alphanumeric string |
This is useful for grep-based leak detection — you can scan your codebase for these patterns to catch accidentally committed keys.
Security checklist
Use this checklist to audit your Hermes credential security. Every item should be a "yes":
- Never commit
.env: Ensure~/.hermes/.envis in your global.gitignore(or better, Hermes lives outside any git repo). If you version-control your Hermes config, add.envto.gitignoreimmediately. - Use restricted API keys: Most providers let you create keys with usage limits, IP restrictions, or project scoping. Create a dedicated Hermes key with only the permissions Hermes needs — not your account's master key.
- Set spending limits: Both OpenRouter and OpenAI allow you to set monthly spending caps per API key. Set a reasonable limit that matches your expected usage — this is your last line of defense against runaway costs.
- Monitor usage: Check your provider's usage dashboard at least weekly. Unexpected spikes can indicate a key leak or a misconfigured automation.
- Rotate quarterly: Every 90 days, generate new keys and revoke old ones. Set a calendar reminder.
- Audit
.envpermissions: Runls -la ~/.hermes/.env— it must show-rw-------(600). If it's anything else, fix it withchmod 600 ~/.hermes/.env. - Don't share keys in plaintext: Never paste API keys into Slack, email, chat apps, or commit messages. Use 1Password shared vaults or a secrets manager for team distribution.
- Revoke unused keys: If you experimented with a provider and no longer use it, revoke the key. Unused keys are forgotten keys — and forgotten keys are a liability.
- Separate dev and prod keys: If you run Hermes on multiple machines (laptop + server), use different API keys. A compromised laptop key shouldn't affect your production automations.
- Check for leaks: Run
grep -r "sk-" ~/.hermes/ --include="*.yaml" --include="*.json" --include="*.md"periodically to catch hardcoded keys that shouldn't be there.
What to do if a key is compromised
- Revoke immediately: Log in to the provider dashboard and revoke the compromised key. This is the single most important step — do it first.
- Check usage history: Review recent API calls to assess what the attacker may have accessed or spent.
- Generate a new key: Create a replacement key and update your
.envfile. - Identify the leak: Determine how the key was exposed — git commit, chat paste, screenshot, stolen machine — and fix the root cause.
- Notify if required: If the key accessed personal information, consider whether breach notification obligations apply under PIPEDA or your provincial privacy legislation.
Next steps
- Set up scheduled automations — use separate, restricted API keys for unattended jobs
- Run local models — eliminate API keys entirely for your most sensitive workflows
- Configure model providers with your newly secured keys
- Self-host Hermes on a dedicated server with isolated credentials