ช่วงนี้ผมเล่น Hermes แต่เจอปัญหามันชอบแอบอ่าน .env ของตัวเอง ซึ่งมี API Keys ของ AI Model Provider เพียบ ถึงจะเปิด redact_pii: true แต่ค่าจริงก็ยังรั่วออกไปบางครั้ง ผลคือต้อง Rotate Keys ทุกรอบที่หลุด ซึ่งเสียเวลามาก
Hermes มี Built-in Integration กับ Bitwarden Secrets Manager อยู่แล้ว และส่วนตัวผมก็ใช้ Bitwarden เป็น Password Manager หลักอยู่แล้วด้วย
ยังไม่รู้จักกับ Bitwarden Secrets Manager? สามารถไปอ่านก่อนได้ที่ Bitwarden Secrets Manager: Key Concepts and Getting Started
ได้อะไร ไม่ได้อะไร
ได้:
- API Keys หลายสิบตัวอยู่ใน BWS แทน Plaintext ใน
~/.hermes/.env - Rotate ที่ vault.bitwarden.com แล้ว Restart Hermes — ไม่ต้องแก้ File บน Server
ไม่ได้:
- BWS ไม่ ทำให้ Agent อ่าน File ไม่ได้ — Agent ที่มี Shell User เดียวกันยัง
cat ~/.hermes/.envได้ (แต่เหลือแค่ BWS Access Token 1 ตัว)
Architecture (Hermes)

ใน Diagram นี้ Hermes คือฝั่ง Your Application (Gateway / CLI)
ตอน Start ใช้ BWS_ACCESS_TOKEN ใน ~/.hermes/.env ดึง Secrets จาก BWS เข้า Memory — ไม่เขียน API Keys กลับลง Disk
Prerequisites
- Hermes Agent Run อยู่แล้ว
- มี
~/.hermes/.envที่เก็บ API Keys (ที่จะย้ายไป Bitwarden Secrets Manager) - Bitwarden Account + Secrets Manager (Free Tier)
Step 1: สร้าง Project บน BWS
- Log in vault.bitwarden.com → Secrets Manager → Projects → New → Project
- ตั้งชื่อ
Hermes→ Save - จด Project ID (UUID) จากหน้ารวม Projects
Step 2: สร้าง Machine Account
- ปุ่ม New → Machine account → ตั้งชื่อ
Hermes-Server→ Save
- แถบ Projects → เลือก Project
Hermesจากนั้นกด Add
- ในตารางด้านล่าง เลือก Permission Can read, write → Save
- Tab Access tokens → Create access token → ตั้งชื่อ Token → Create → Copy — Bitwarden ไม่สามารถแสดง Token ให้ดูซ้ำได้
หมายเหตุ: Access token ที่คุณสร้างเองห้ามแชร์หรือส่งต่อให้ผู้อื่น
Step 3: ติดตั้ง bws ผ่าน Hermes
hermes secrets bitwarden setup เป็น wizard — Hermes ติดตั้ง bws ให้เอง ไปที่ ~/.hermes/bin/bws แล้ว Hermes จะถามเพิ่มเติมเอง (Access Token, Project ฯลฯ)
ถ้าอยากลง bws เอง โดยไม่ผ่าน Hermes ก็ทำได้เช่นกัน อ่านเพิ่มเติมที่ ติดตั้งและทดสอบ CLI ใน Bitwarden Secrets Manager: Key Concepts and Getting Started
hermes secrets bitwarden setup
Hermes วาง bws ที่ ~/.hermes/bin/ — โฟลเดอร์นี้ไม่อยู่ใน PATH เริ่มต้น ของ Shell ทำให้พิมพ์ bws ตรง ๆ แล้วได้ command not found ต้องเพิ่มเข้า PATH ก่อน
ทดสอบใน session ปัจจุบัน:
export PATH="$HOME/.hermes/bin:$PATH"
bws --version
เปิด terminal ใหม่แล้ว PATH หาย — ใส่บรรทัดเดียวกันใน ~/.zprofile หรือ ~/.zshrc แล้ว source ไฟล์นั้น (หรือเปิด session ใหม่):
export PATH="$HOME/.hermes/bin:$PATH"
รายละเอียด Option อื่น ๆ อยู่ใน Hermes Bitwarden Secrets Manager
Step 4: Dump Keys จาก ~/.hermes/.env
ข้อควรระวัง: Secret Name ใน Bitwarden ต้องตรงกับชื่อ Env Var ทุกตัวอักษร (DISCORD_BOT_TOKEN, OPENAI_API_KEY, …) — ถ้าชื่อไม่ตรง Hermes จะ inject ไม่เจอ ค่านั้นจะไม่ถูกโหลดเข้า environment
Set ค่าก่อนรัน (session ใหม่ต้อง export ใหม่ รวม PATH จาก Step 3):
export PATH="$HOME/.hermes/bin:$PATH"
export BWS_ACCESS_TOKEN="0.xxxxx..." # Token ที่ Copy ไว้
export HERMES_PROJECT_ID="<project-uuid>"
สร้างทีละตัว
ถ้ามี Keys ไม่กี่ตัว สร้างด้วย bws โดยตรงได้เลย — pattern คือ bws secret create <name> <value> <project-id>:
bws secret create OPENAI_API_KEY "sk-..." "$HERMES_PROJECT_ID"
bws secret create DISCORD_BOT_TOKEN "MTEy..." "$HERMES_PROJECT_ID"
Pitfall:
bws secret createใช้ Positional Args ตามลำดับname,value,project-id— ไม่มี flag--project-id
สร้างผ่าน Web UI ก็ได้เช่นกัน ถ้าคุณสะดวกมากกว่า
สร้างเป็น Script (Keys เยอะ)
ถ้า Keys เยอะ เขียน Script อ่านจาก .env แล้ว loop สร้างทีเดียวง่ายกว่า:
#!/usr/bin/env bash
while IFS='=' read -r key value; do
[[ -z "$key" || "$key" =~ ^# ]] && continue
[[ "$key" == "BWS_ACCESS_TOKEN" ]] && continue
value="${value%\"}"; value="${value#\"}"
echo "create $key"
bws secret create "$key" "$value" "$HERMES_PROJECT_ID"
done < ~/.hermes/.env
Step 5: Verify แล้วลดสิทธิ Machine Account
ตรวจว่า Secrets ขึ้นครบก่อนลดสิทธิ์ — เลือกวิธีใดวิธีหนึ่ง:
วิธีที่ 1 — Web UI: เปิด Project Hermes ใน vault.bitwarden.com แล้วนับรายการ Secrets เทียบกับ Keys ที่มีใน .env
วิธีที่ 2 — CLI: ดึงรายการ Secrets ออกมาดูได้โดยตรง:
export PATH="$HOME/.hermes/bin:$PATH"
bws secret list
จากนั้นกลับไป Web Vault เปลี่ยน Permission ของ Machine Account Hermes-Server เป็น Can read — Token เดิมยังใช้ได้แต่แก้ค่าใน Vault ไม่ได้
Step 6: เหลือแค่ BWS_ACCESS_TOKEN ใน ~/.hermes/.env
ลบ API Keys ทั้งหมดออก เหลือแค่ BWS_ACCESS_TOKEN:
# ~/.hermes/.env
BWS_ACCESS_TOKEN=0.xxxxx...
Step 7: กัน Hermes เขียน Cache กลับลง Disk
แม้ .env จะเหลือแค่ Token แล้ว Hermes ยังแอบเขียน Cache ลง ~/.hermes/cache/bws_cache.json — และมีโอกาสอ่านกลับจากไฟล์นี้ได้เหมือนกัน กันไว้ด้วยการเปลี่ยน Path นั้นให้เป็น Directory ว่าง แทนที่จะเป็นไฟล์:
# 1. ลบไฟล์เดิม ถ้ามีไฟล์
rm ~/.hermes/cache/bws_cache.json
# 2. สร้าง Directory ชื่อเดิม
mkdir ~/.hermes/cache/bws_cache.json
# 3. chmod 500 = Permission Read+Execute เฉพาะ User แต่ Write ไม่ได้
chmod 500 ~/.hermes/cache/bws_cache.json
Hermes พยายามเขียน JSON ทับ Path นี้จะล้มเหลว — Secrets ไม่กลับไปอยู่บน Disk อีก โดยยอมเสีย Feature cache ไป แต่ดีกว่า Secret หลุด เพราะผมหลุดมาแล้ว
Step 8: Sync และ Restart Gateway
ลอง fetch Secrets จาก Bitwarden ดูก่อน — sync โดย Default เป็น Dry-run แค่ Report ว่าจะ Inject อะไรบ้าง ยังไม่เปลี่ยนอะไรจริง:
hermes secrets bitwarden sync
ถ้าเห็น Secrets ครบแล้ว Restart Gateway ได้เลย — Hermes ดึง Secrets จาก BWS อัตโนมัติทุกครั้งเอง
hermes gateway restart
ถ้ารัน Gateway ผ่าน systemd (user unit):
systemctl --user restart hermes-gateway
รายละเอียด systemd อ่านเพิ่มที่ Remote Access: Auto-start After Reboot with systemd (2/3)
Troubleshooting
| อาการ | สาเหตุ | วิธีแก้ |
|---|---|---|
404 ตอน bws secret create | Machine Account เป็น Read-only (Bitwarden ตอบ 404 ไม่ใช่ 403) | เปลี่ยน Account เป็น Read/Write ชั่วคราว |
BWS_ACCESS_TOKEN is not set | ไม่มีใน ~/.hermes/.env | ใส่ Token ใน .env แล้ว restart Gateway |
Rotate ครั้งต่อไป
แก้ค่าที่ vault.bitwarden.com แล้ว Restart:
hermes gateway restart
ไม่ต้องแตะ File บน Server — ยกเว้น Rotate BWS_ACCESS_TOKEN เอง ซึ่งต้องแก้ใน ~/.hermes/.env แล้ว Restart