<!-- Source: https://docs.infraio.xyz/zh-TW/security/api-keys -->
<!-- Last updated: 2026-10-04 -->

# API 金鑰

三種憑證，三種威脅模型。

## `pk_` — Publishable

- 設計上就是要送到瀏覽器。每個已簽章的 B2B 請求都會以
  `X-Client-ID` 標頭帶著它，也會內嵌在 SDK bundle 中，供
  用戶端開啟結帳時使用。
- 可以識別你的帳號；但無法建立 session、讀取其他商家的資料，
  或觸發任何具破壞性的操作。
- publishable key 外洩屬於**低嚴重度**事件。

## `sk_` — Secret（HMAC 簽章金鑰）

- 所有 B2B API 呼叫用的 HMAC-SHA256 簽章金鑰 — 見
  [身分驗證](https://docs.infraio.xyz/zh-TW/api-reference/authentication)。
- 永遠不會在網路上傳輸。只有它衍生出的逐請求簽章會傳輸。所以
  你只需要擔心*儲存*層的外洩（env var、git、log），不用擔心
  傳輸層。
- 僅限伺服端使用。不應該出現在瀏覽器 bundle、公開 repo、
  截圖或聊天訊息中。
- secret key 外洩屬於**高嚴重度**事件。

## `whsec_` — Webhook 簽章密鑰

- 用來驗證我們對你伺服器所做的**入站** webhook 投遞的簽章。見
  [簽章驗證](https://docs.infraio.xyz/zh-TW/webhooks/signature-verification)。
- 每個 webhook 端點各自獨立 — 若你註冊了 3 個端點，就會有 3 組
  不同的 `whsec_` 密鑰。環境編碼在前綴中：`whsec_live_…` /
  `whsec_test_…`。
- 僅限伺服端使用。和 `sk_` 一樣，永遠不會在網路上傳輸 — 只用來
  在本地驗證 HMAC。
- **輪替有 24 小時的寬限視窗。** 點擊 Rotate 後，前一個密鑰在
  24 小時內仍會被接受，與新密鑰並存（投遞會同時帶
  `X-Signature` 與 `X-Signature-Prev`），讓你可以在不中斷流量
  的情況下重新部署驗證器。
- **顯示既有密鑰**的功能是可用的，但需要新的 2FA 驗證並記錄在
  稽核日誌中 — 適用於密鑰遺失、且無法接受輪替的情境。儀表板
  的預設立場是「輪替，而非顯示」。
- webhook 密鑰外洩，會讓攻擊者能對你的 URL 偽造事件。嚴重度為
  **中到高**，取決於你對事件酬載的信任程度。

## Scope

Secret key 是有範圍限定的。儀表板讓你可以用下列其中一種 scope
組合鑄造金鑰：

| Scope | 可以做什麼 | 用於 |
| --- | --- | --- |
| `read` | 列出 / 讀取訂單、session、退款、餘額 | 唯讀整合（分析、BI） |
| `write_order` | 全部 `read` 權限 + 建立 session、建立訂單、取消訂單 | 商店後端 |
| `write_refund` | 全部 `read` 權限 + 建立退款、標記退款已執行 | 客服工具 |
| `webhook_manage` | 全部 `read` 權限 + 管理 webhook 端點 | DevOps 工具 |

預設鑄造的「full access」金鑰會擁有全部四種 scope。鑄造分用途的
金鑰仍然是良好的做法，因為它能記錄意圖，但在把 scope 當成安全邊界之前，請先讀完下面的但書。

> **Warning:**
>
> **Scope 目前尚未強制執行。** 任一 scope 的 `sk_` 金鑰外洩，
> 都能呼叫你商家底下*任何* `/b2b/v1/*` endpoint。`read` 金鑰
> 並不會被阻止建立退款。窄範圍的 scope **目前並不能**降低外洩的
> 損害：在做安全規劃時，請把每一把 secret key 都當成 full access
> 處理，並仰賴快速輪替與撤銷（見下文）來圍堵外洩。

## 輪替

1. **產生新金鑰。** 儀表板 → **Developers → API keys** → **+
   Add key**。選擇 scope。儀表板**只會顯示一次**密鑰 — 請立刻
   儲存下來。
2. **把 env var 換成新值**，套用到所有環境。部署。
3. **驗證流量。** 儀表板會即時顯示逐金鑰的請求數。等舊金鑰的
   請求數降到零。
4. **撤銷舊金鑰。** 同一畫面 → ⋮ 選單 → **Revoke**。

> **Warning:**
>
> **目前沒有自動的重疊視窗** — 一旦你撤銷金鑰，任何用它簽章、
> 仍在傳輸中的請求都會收到 `401`。請據此規劃你的輪替流程：先
> 部署新金鑰，等舊金鑰的流量退乾，再撤銷。

## 緊急撤銷

若金鑰已經外洩（出現在 git 歷史、公開的 bundle、被記錄下來的
stack trace，或合作夥伴的滲透測試報告中）— 請立刻撤銷，即使
會導致部分請求失敗也一樣。與其讓攻擊者持有有效憑證，不如讓
系統明顯地失敗。

步驟：

1. **儀表板 → Developers → API keys → [金鑰] → Revoke now。**
   效果是立即生效的；沒有寬限期。
2. 鑄造一把替代金鑰並部署。
3. 稽核近期活動 — 儀表板會顯示每把金鑰最近 30 天的請求紀錄，
   含 IP 與命中的 endpoint。

若你懷疑外洩範圍不只一把金鑰，請聯絡 contact@lartech.xyz 以：

- 取得你商家帳號完整的稽核日誌匯出
- 批次輪替 webhook 密鑰
- 視需要在調查期間凍結帳號

## 儲存最佳實務

- **只用 env var。** 絕不把密鑰提交進 git，即使是寫著
  「REPLACE ME」的 `.env.example` 也一樣。
- **依環境分金鑰。** 開發 / staging / production 各自使用不同
  的 `sk_test_…` 與 `sk_live_…`，並從你的密鑰管理工具取得
  （AWS Secrets Manager、Vault、Doppler……）。
- **限制 env var 的存取權。** 在 Kubernetes 中，請掛載為
  `Secret`，而不是 `ConfigMap`。在 Vercel / Netlify 中，請使用
  環境變數層級的範圍限定，而非專案層級的全域變數。
- **不要記錄帶有 body 的請求。** 即使是在除錯時也一樣 — 你在
  `X-Signature` 中的 HMAC 簽章雖然是單次使用的，但你的業務
  酬載可能含有個資。

## 目前不支援的功能

- ❌ secret key 的 **IP 允許清單**。
- ❌ **OAuth 風格的逐使用者範圍 token。** 目前的金鑰模型是
  逐商家、而非逐使用者。
- ❌ **自動金鑰輪替**（例如平台強制的每週輪替）。輪替需手動進行。

## 下一步

- [身分驗證](https://docs.infraio.xyz/zh-TW/api-reference/authentication) — B2B 呼叫的
  確切簽章演算法。
- [Webhooks → 簽章驗證](https://docs.infraio.xyz/zh-TW/webhooks/signature-verification)
  — `whsec_` 如何用於入站事件。
