---
title: "出版簽章金庫 Vault 現況 (FR-173)"
brand: "Guidant AI · **FR-173** 出版管線定稿"
eyebrow: "FR-173 · 現況 · 192.168.50.172"
h1: "Vault 現況"
subtitle: "172 上現在裝了什麼、設成什麼樣、還差什麼；怎麼裝見架設手冊"
lede: "這一頁只寫**現在的狀態**，狀態變了就改這裡。**不含任何祕密**：解封鑰匙、root token、jedi 密碼都不在這裡，只寫它們存在哪一類地方。公鑰與 kid 是公開資訊，客戶主機就是拿它們驗章。"
chips: [
  {text: "簽章鑰已建、可簽可驗", kind: ok},
  {text: "快照、防火牆、GitLab 串接未做", kind: warn},
  {text: "祕密不進這份文件", kind: crit},
]
footer: "FR-173 Vault 現況 · 怎麼裝與日常維運見 vault-setup-runbook.md"
---

## 一句話 {#summary nav="一句話"}

Vault 已經在 192.168.50.172 跑起來，Ed25519 簽章鑰匙建好且拿不出來，試簽在 Vault 外驗過、客戶端驗章程式不用改。還沒做的是每日快照、防火牆、GitLab 串接與建置期祕密，這些等 FR-173 開卡時做。開發 FR-171／172 用不到 Vault。

---

## 主機與服務 {#host nav="主機"}

| 項目 | 現況 |
|---|---|
| 主機 | `192.168.50.172`，主機名 `hashicorp-vault`，Ubuntu 26.04.1 LTS，4 vCPU、15 GB、磁碟 48 GB |
| 安裝 | HashiCorp 官方 apt 套件，systemd 服務 `vault`，開機自動起；不用 docker |
| 版本 | Vault 2.2.1 Community（BSL 授權，原廠內部出版使用免費） |
| 儲存 | 內建 Raft，單節點，`/opt/vault/data` |
| 封印 | Shamir，5 把解封鑰匙、任 3 把解封；**主機每次重開機都要解封** |
| TLS | 內網自簽 CA（10 年）＋伺服器憑證（2 年，SAN 含 IP 與主機名）；CA 公開憑證放 `/etc/vault.d/vault-ca.pem` 給 CLI 用 |
| swap | 已關（防止私鑰被換頁寫到磁碟） |
| 防火牆 | **未開**（決策者 2026-11-01 裁先不管）。目前同網段可連 8200，無帳號密碼什麼都做不了，但登入頁看得到 |
| 稽核 log | `file/` → `/var/log/vault/audit.log`，每次簽章誰簽、何時簽都記錄 |
| 網頁介面 | `https://192.168.50.172:8200/ui`，登入方式選 **Username** |

---

## 簽章鑰匙 {#key nav="簽章鑰"}

| 項目 | 值 |
|---|---|
| 位置 | `transit/keys/guidant-release` |
| 類型 | Ed25519（與現行 Mac 發布章同一種，客戶端驗章零改動） |
| 拿得出來嗎 | **不行**：`exportable` false、`allow_plaintext_backup` false |
| 刪得掉嗎 | 不行：`deletion_allowed` false |
| 用途 | 只有 `digital-signature` |
| 版本 | v1，建立於 2026-11-01 12:58 UTC |
| 公鑰 v1（base64） | `LrkT7UIsUb8COEXmdoxR1d6gDIhUwFjK5UrPqc17eCM=` |
| kid | `05086455d42ca0d6`（公鑰 32 bytes 的 sha256 前 16 hex，與 LC、更新站 CLI 同規則） |
| 簽名格式 | `vault:v1:<base64 64 bytes>`；串進蓋章 CLI 時要剝掉 `vault:v1:` 前綴，剩下的就是標準 Ed25519 簽名 |
| 驗證紀錄 | Vault 簽 `hello` 的簽名，在 Vault 外用標準 Ed25519 函式庫驗過；改一個字就驗不過 |

公鑰已在 BE `scripts/installer/release-keys/05086455d42ca0d6.pub` 與 `PROD_KIDS`，隨主系統安裝包裝到客戶機 `/etc/guidant/release-keys/`。190 已有（1.28.x 起）。

---

### 測試章（只給 190）

| 項目 | 值 |
|---|---|
| 位置 | `transit/keys/guidant-test`，Ed25519，三個 false，v1 建立於 2026-11-03 10:59 UTC |
| kid | `128cfec6fc9877b8` |
| 公鑰放哪 | 只放 190 `/etc/guidant/release-keys/`（2026-11-03 已放）；不進安裝包，188、189 不放 |

---

## 帳號與權限 {#access nav="帳號"}

| 項目 | 現況 |
|---|---|
| 登入方式 | `userpass/`（帳號密碼）；`token/`（內建） |
| 帳號 | `jedi`（政策 `release-admin`，稽核 log 記成 `userpass-jedi`）；`release-dev`（政策 `release-sign-dev`：只能簽測試章、讀兩把公鑰，不能簽正式章；token 1 小時；給 V-1 本機開發用，密碼在 update-center `.env`） |
| 政策 `release-admin` | `sys/*`、`auth/*` 全權；`transit/keys/*` 讀與更新（含輪換）；`transit/sign/*`、`transit/verify/*`；`kv/*` 讀寫 |
| root token | **已撤銷**，目前沒有任何有效的 root token。要用時拿 3 把解封鑰匙跑 `vault operator generate-root` 重新產生，用完馬上撤銷 |
| 有效 token | 只有 jedi 登入產生的那一個（768 小時、可續） |

---

## GitLab CI 怎麼拿權限 {#ci nav="CI 權限"}

CI 每個 job 拿 GitLab 發的短效身分證來登入（`auth/jwt/`，認 `https://gitlab.com`），Vault 依身分證上的專案、tag／branch、按按鈕的人，決定給哪個角色。人的帳號只有 `jedi`、`release-dev` 兩個，CI 不用帳號密碼。

| 角色 | 誰拿得到 | 能做什麼 |
|---|---|---|
| `fe-ci` | FE 專案任何 job | 讀 `kv/ci/nexus` |
| `release-ci` | BE、Agent 專案，受保護 `v*` tag，且 `user_id`＝21126655（決策者）按的 | 簽正式章、讀 `kv/ci/*` |
| `test-ci` | BE、Agent 專案任何 branch，且 `user_id`＝21126655 按的 | 簽測試章、讀 nexus／harbor／license-center |
| `classifier-ci` | jedi 套件專案（`commonservice3/jedi-python-package`）任何 ref，且 `user_id`＝21126655 按的 | 只讀 `kv/ci/harbor`，不能蓋章 |

原則：**每個 repo 的 CI 一個自己的角色**，權限只開它需要的；要蓋正式章的只有 `release-ci`。新 repo 接 Vault 另建角色，不塞進既有角色。

加人：把他的 GitLab `user_id` 加進 `release-ci`、`test-ci`、`classifier-ci` 的 `user_id` 陣列，照手冊 14.6、14.6b 重寫角色。

KV 五筆（`kv/ci/`）：`nexus`、`r2`、`harbor`、`update-site`、`license-center`，2026-11-03 放入，除 `update-site.ci_token`（新建）外逐欄與 188 現用值比對一致。188 上的原檔與 BE 專案 GitLab 變數仍在，第二批 CI 驗完後清除（STATE §3）。

---

## 誰信任這張 CA {#trust nav="信任 CA"}

| 機器 | 位置 | 何時裝 |
|---|---|---|
| 188（CI 跑在這） | 系統信任清單 `/usr/local/share/ca-certificates/guidant-release-vault.crt` | 2026-11-03 |
| 決策者 Mac | `~/.config/guidant/vault-ca.pem`（update-center `.env` 的 `VAULT_CACERT` 指這裡） | 2026-11-03 |

沒信任的機器連 Vault 會報 `curl: (60) SSL certificate problem`。

---

## 祕密存在哪（只寫位置類型，不寫值） {#custody nav="祕密保管"}

| 祕密 | 存放 |
|---|---|
| 解封鑰匙 5 把 | 決策者 Apple「密碼」3 把；離線紙本 2 把（家裡、公司各一） |
| jedi 帳號密碼 | 決策者 Apple「密碼」 |
| `vault-ca.key`（簽伺服器憑證用） | 仍在 172 `/opt/vault/tls/`；建議複製到保管處後從主機刪除（手冊第 2 段） |

**只有一個管理員的風險**：決策者的 Apple ID 單獨就湊得滿 3 把解封鑰匙；Apple ID 要開雙重認證。有第二個管理員時，Apple「密碼」改放 2 把、分 1 把給他，並替他另開一個 Vault 帳號（不共用 `jedi`）。

---

## 還沒做的 {#pending nav="未做"}

| 項目 | 為什麼要做 | 什麼時候做 |
|---|---|---|
| 每日快照＋異地備份 | 鑰匙拿不出來，**快照是唯一的備份**；172 壞掉又沒快照，這把章就沒了（還有 Mac 備用章，但要出一版換 kid） | 正式拿來出版前；決策者裁先開發 |
| 防火牆（只放 188 與決策者 Mac） | 目前同網段看得到登入頁 | 正式拿來出版前 |
| 稽核 log 輪替 | log 會一直長大 | FR-173 D-1 |
| 鑰匙交接程序 | 決策者離開或長期不在時，誰能解封與簽章 | 有第二個管理員時 |

---

## 這份文件的定位 {#refs nav="相關"}

| 你想知道 | 看哪份 |
|---|---|
| 172 現在是什麼狀態 | 本頁 |
| 怎麼從零裝一台、重開機怎麼解封、怎麼換憑證 | [架設手冊](vault-setup-runbook.md) |
| 為什麼選自架 Vault、不選雲端 KMS 或 GitLab | [設計](design.md) §1 D1、D2 |
| CI 什麼時候、怎麼跟 Vault 串 | [設計](design.md) §2、§3 與拆卡表 |
