---
title: "讓應用的交易金鑰與 Secret 不落在伺服器的磁碟上"
description: "erpc worker 將應用的交易金鑰與 Secret 保存在 1Password、作業系統鑰匙圈或加密的金鑰庫中，並在記憶體中交給應用。"
canonical: "https://erpc.global/zh-tw/doc/erpc-cli/worker-secrets/"
locale: "zh-tw"
---

# 讓應用的交易金鑰與 Secret 不落在伺服器的磁碟上

`erpc worker` 將應用的交易金鑰與 Secret 保存在 1Password、您的鑰匙圈或加密的金鑰庫中，並在記憶體中交給應用，絕不寫入伺服器的磁碟。

本頁說明 ERPC CLI `v0.1.0-rc.4`，這是發行前版本。

## 交易金鑰如何送達應用

具有錢包的應用會在啟動時經由管道取得金鑰。伺服器上沒有 `wallet.json`、沒有 `.env`，也沒有副本。erpc 不會將未加密的金鑰寫入任何磁碟：它唯一放入金鑰的檔案是金鑰庫的檔案，位於您的機器上，並以您的通行片語加密。

- **保存位置**：當 `erpc login` 將工作階段保存在 1Password 時，`erpc worker key new` 會在該處建立金鑰；否則在鑰匙圈中建立，再否則在金鑰庫中建立。`erpc.toml` 會記錄金鑰的參照及其公鑰。
- **在伺服器上**：erpc worker agent 只在記憶體中保存金鑰。它會使自身無法被傾印，並鎖定自己的記憶體，再透過檔案描述元將金鑰交給應用；應用讀取後會將其清除。
- **重啟之後**，worker 會以鎖定狀態重新上線：在 `erpc worker start` 再次傳送金鑰之前，應用不會執行。失敗或被終止的 agent 會由 systemd 再次啟動，並同樣以鎖定狀態重新上線。
- **套件更新不會重新啟動 worker**。`deploy` 會告知 `needrestart` 不要動 worker 單元：在自動模式下，它會延後處理這些單元；在終端機中詢問時，它對這些單元的預設回答為「否」，因此無人值守的安全性更新不會重新啟動應用。若無法寫入這條規則，部署會說明這一點並繼續進行，此時 worker 就會在沒有這項保護的情況下執行。

交易金鑰只由 `[wallet]` 指定，不由其他任何項目指定，而且只有在有人於終端機前操作時，erpc 才會讀取它：不會為 AI 工具讀取，也不會透過 1Password 服務帳戶讀取。指定 `[wallet]` 參照的 `[secrets]` 行，或以 `.wallet` 結尾的 `keychain:` 或 `keystore:` 帳戶，都會被拒絕。在金鑰庫中，以金鑰形式保存的項目不會以 Secret 的形式開啟。在 1Password 中，以及在其他名稱的鑰匙圈帳戶下，沒有任何東西會標記金鑰：沒有 `[wallet]` 的 `erpc.toml` 若在 `[secrets]` 下指定此類項目，該項目就會被當作 Secret 讀取。

## 選擇值的保存位置

1Password 是選用的。除非以 `--store` 指定（`--store 1password --vault <id>`、`--store keychain`、`--store keystore`），`erpc worker key new` 與 `erpc worker secret put` 會將收到的值保存在下列第一個適用的位置：

1. **1Password**，當 `erpc login` 將工作階段保存在該處，或指定了 `--vault` 時。
2. **作業系統鑰匙圈**，在它能於重啟後仍保留值的環境中：macOS、Windows，以及在已登入的工作階段中具有桌面金鑰環的 Linux。
3. **erpc 的金鑰庫**，用於沒有此類金鑰環的 Linux 機器：無圖形介面的伺服器、WSL、SSH 登入。在這類機器上使用 `--store keychain` 會被拒絕。

在鑰匙圈或金鑰庫中，金鑰只存在於那一台機器上，沒有副本，也不會同步，其他機器無法讀取 `keychain:` 或 `keystore:` 參照。

機器遺失或被清除，就代表錢包也隨之遺失：錢包中請只放少量資金，或使用 1Password，所有已登入該保險庫的機器都能讀取。請以 `erpc login --store 1password-desktop` 登入 1Password；在沒有桌面應用程式的地方，則透過 `op signin` 登入。

1Password 服務帳戶可以保存應用的 Secret，但 erpc 不會透過服務帳戶讀取交易金鑰。使用 1Password 時，每次讀取都可能在應用程式中顯示核准提示，erpc 會在等待時顯示載入動畫。

## 保存 Secret

Secret（例如 API 權杖與 RPC 金鑰）也以相同方式保存，但會以環境變數的形式送達應用，而不是經由管道。`erpc worker secret put <NAME>` 會保存值，而 `erpc.toml` 中的 `[secrets]` 只保存其參照。

```bash
erpc worker secret put API_TOKEN --generate          # the bot's own API token, made for you and shown to nobody
erpc worker secret put ERPC_API_KEY --from-account   # the account's RPC key, read from your account (or SOLANA_RPC_ENDPOINT in [vars])
```

- **`--generate`** 會產生值：32 個隨機位元組，以 64 個十六進位字元表示。
- **`--from-account`** 會保存您帳戶的 RPC 金鑰中第一個被共享 RPC 接受的金鑰。金鑰依順序嘗試，主要金鑰優先，每把金鑰各發送一次 `getHealth`，並給予 8 秒回應時間。回應 401 或 403 的金鑰會被拒絕並改試下一把，只有被 RPC 接受的金鑰才會被保存。命令會說明它是帳戶的主要金鑰還是其他金鑰（使用 `--json` 時為 `account_key`）。
- 兩種值都不會被印出，使用 `--json` 時也一樣。首次使用金鑰庫，或金鑰庫處於鎖定狀態時，需要有人在終端機前操作。
- 金鑰是從本機嘗試的，因此僅限伺服器位址使用的金鑰在這裡會被拒絕，儘管它在伺服器上可以使用。當每把金鑰都被拒絕時，`--from-account` 不會保存任何東西，請由您手動保存想用的金鑰，以不顯示的方式輸入或經由管道傳入。當無法詢問 RPC 時，它不會保存任何東西，`erpc.toml` 保持原樣；請再執行一次相同的命令。

如需手動保存金鑰：

```bash
erpc worker secret put ERPC_API_KEY        # asks for the value, unseen
```

- `--replace` 會為已設定的名稱保存新值。`erpc worker secret list` 會依名稱列出 Secret 設定，以及各自的保存位置。
- 由資料線路提供的設定（`GRPC_ENDPOINT`、`SHREDS_ENDPOINT`、`SOLANA_SEND_RPC_ENDPOINT`）絕不是 Secret：由 `--grpc`、`--shreds` 與 `--unlimited` 設定。

`[secrets]` 或 `[wallet]` 中的參照為下列其中一種：

| 參照 | 值的所在位置 |
| --- | --- |
| `op://<vault-id>/<item-id>/<field>` | 1Password，依保險庫與項目的 ID |
| `keychain:<service>/<account>` | 保存該值的機器上的作業系統鑰匙圈 |
| `keystore:<service>/<account>` | 保存該值的機器上的 erpc 金鑰庫 |

## 金鑰庫

金鑰庫是目錄 `~/.erpc/keystore`（若設定了 `ERPC_HOME`，則為其下的 `keystore`）。在 Linux 與 macOS 上，其目錄為 `0700`，檔案為 `0600`；在 Windows 上，erpc 不會自行設定權限。

- `master.json` 保存一把隨機的 32 位元組主金鑰，並以 PBKDF2-HMAC-SHA256（600,000 次迭代）從您的通行片語推導出的金鑰加以封裝。每個項目保存一個值，並以該項目專屬的金鑰透過 ChaCha20-Poly1305 封裝。
- **通行片語**：第一次使用金鑰庫的 `key new` 或 `secret put` 會請您設定它，在終端機中輸入兩次，長度為 12 個字元以上。erpc 只從該隱藏提示取得通行片語，絕不從引數、環境變數或管道取得。
- **在 Linux 上解鎖**：通行片語開啟金鑰庫之後，解鎖狀態會保存在核心的持久金鑰環中（位於記憶體），直到機器重新啟動、金鑰環閒置達到其到期時間（三天，除非系統另有設定），或執行 `erpc worker secret lock` 為止。`erpc worker secret unlock` 會預先詢問通行片語，並說明解鎖持續到何時。在未經自身登入而啟動的 shell 中（不帶 `-` 的 `su`、`sudo -E`），不會保留解鎖狀態，每個命令都會詢問。
- **終端機前無人操作時**，需要金鑰庫的命令若有解鎖狀態就會使用它，否則就會失敗，並指出 `erpc worker secret unlock`。已解鎖的金鑰庫會交出 Secret，但不會交出交易金鑰。
- **在 macOS 與 Windows 上**（`--store keystore`），不會保留解鎖狀態：每個需要金鑰庫的命令都會詢問一次通行片語，因此需要終端機。

### 金鑰庫能保護什麼、不能保護什麼

- **請備份 `keystore` 目錄並記住通行片語**。erpc 兩者都無法找回，兩者缺一，金鑰庫保存的內容就會遺失。
- 同時擁有金鑰庫檔案與通行片語的人，就擁有金鑰。PBKDF2 會讓每次猜測都變慢，但不會讓可被猜中的通行片語變得安全。
- 金鑰庫處於解鎖狀態期間，以您的身分執行的任何程式都能從核心金鑰環讀取主金鑰（工作階段中沒有您金鑰環的程式，也能將其連結進來），並開啟每個項目，包括金鑰的項目。erpc 自身的規則（`[wallet]` 指定的金鑰只為終端機前的人讀取，絕不為 AI 工具讀取；保存在金鑰庫中的金鑰絕不以 Secret 的形式開啟）是 erpc 的行為；這些規則不會約束以您的身分執行的其他程式。使用完畢後，請執行 `erpc worker secret lock`。
- 項目名稱不會被隱藏，且項目的大小會透露值的長度。
- 被修改過的檔案無法開啟；但將同一項目的較舊副本放回原處，則可以開啟。
- `erpc worker secret rm` 會刪除 Secret 的金鑰庫項目，連同其在 `erpc.toml` 中的那一行（除非應用的其他設定也指定同一個項目），並將 1Password 或鑰匙圈中的值留在原處。它不會抹除磁碟，您備份中的副本也會保留。
- erpc 絕不會刪除或覆寫交易金鑰的項目。如要更換金鑰，請先轉移資金，然後自行移除其檔案與 `[wallet]`。
- 設定不能命名為 `WALLET`（不論大小寫），在金鑰庫或鑰匙圈中皆是如此；`--store 1password` 可以使用這個名稱。

## 使用交易金鑰

| 命令 | 作用 |
| --- | --- |
| `erpc worker key new` | 建立交易金鑰，並印出需要轉入資金的公鑰 |
| `erpc worker key import <FILE>` | 將金鑰檔案移入 1Password、鑰匙圈或金鑰庫，然後提議清除該檔案 |
| `erpc worker key show` | 顯示金鑰的公鑰及其保存位置 |
| `erpc worker key balance` | 透過應用自己的 RPC 設定，顯示金鑰的餘額 |
| `erpc worker key send --to <ADDRESS> --sol <N>` | 在您於終端機中確認後，在記憶體中簽署一筆轉帳。`--all` 會送出扣除手續費後的全部金額 |

若 erpc 結束時無法確定轉帳是否已上鏈，請先查詢其簽章再重新傳送：第二次傳送就是第二筆轉帳。
