讓應用的交易金鑰與 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 結束時無法確定轉帳是否已上鏈,請先查詢其簽章再重新傳送:第二次傳送就是第二筆轉帳。