Skip to main content

> Jitrak Blog

>_Migrate Hermes API Keys to Bitwarden Secrets Manager

#เอา API Keys ออกจาก .env Default ของ Hermes ด้วย Bitwarden Secrets Manager และ Hermes Built-in Integration

@Yosapol Jitrak|29 Jun 2026 03:58

ช่วงนี้ผมเล่น 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)

BWS Architecture

ใน 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

  1. Log in vault.bitwarden.comSecrets ManagerProjectsNewProject
  2. ตั้งชื่อ HermesSave
  3. จด Project ID (UUID) จากหน้ารวม Projects
สร้าง Project ชื่อ Hermes Project Hermes — จด Project ID จากรายการ

Step 2: สร้าง Machine Account

  1. ปุ่ม NewMachine account → ตั้งชื่อ Hermes-ServerSave
สร้าง Machine account ชื่อ Hermes-Server
  1. แถบ Projects → เลือก Project Hermes จากนั้นกด Add
เลือก Project Hermes แล้วกด Add
  1. ในตารางด้านล่าง เลือก Permission Can read, writeSave
Project Hermes — Permission Can read, write
  1. Tab Access tokensCreate access token → ตั้งชื่อ Token → Create → Copy — Bitwarden ไม่สามารถแสดง Token ให้ดูซ้ำได้
สร้าง Access token — ตั้งชื่อและวันหมดอายุ Copy Access token ก่อนปิดหน้าต่าง — 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
setup เสร็จ — test fetch แสดง Secrets ที่จะ inject

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 ไม่ได้

ลดสิทธิ Machine Account — Project Hermes เป็น Can read

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 createMachine 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

Credits

— EOF —

Post feedback

~/feedback

Comments

~/shortcuts

> Keyboard shortcuts

  • Toggle this help?H
  • Back to topT
  • Hold to scroll downJ
  • Hold to scroll upK
  • Forward (newer post or next page)F
  • Back (older post or previous page)B
  • Close helpEsc

Navigation

  • Blog (post list)L
  • AboutA
  • PlayP
  • Tags,