OpDeck
era: agent
created_at: 2026/10/12 05:00:00

一個自架的開發者指令中心,同時也是我自己的密碼管理器:在任何地方按下 Ctrl+K 叫出指令面板(Command Palette),找 secret、跑指令,都在同一個輸入框裡完成,也可以整合 chrome extension 來填密碼。
簡單說就像是 Flow Launcher + 1Password 的合體,再加上一些魔改(?)
目前尚未開源。現階段以提高我自己的開發與使用體驗為主,等未來把權限控管整合好之後再開源。
為什麼會有這個服務
兩個理由,剛好對應到它的兩半。
專案的 secrets 散落各處。 手上的專案越來越多之後,每個專案都有自己的一堆 secrets、環境設定、後台網址、常用的指令,散落在各個地方,換一台電腦或開一個新的 Dev Container 就要重新找一次、貼一次。
自己的密碼也快記不住了。 我一直不想在每個地方都記不同的密碼,以前服務不多的時候,是用生活中的關聯在腦袋裡做 hash,每個平台算出一組不一樣的密碼;服務一多就開始擔心哪天算不出來,也怕這套規則被看穿,一個破了就全破。
既然兩種東西本質上都是「要加密存放、要能分享給對的人、要在需要時一鍵拿到」,就乾脆做成同一個工具:一個自己架的地方統一放,桌面上按個快捷鍵就能叫出來用,瀏覽器登入時自動填。
Demo
影片有旁白,大概一分二十秒,想跳著看的話:
| 時間 | 內容 |
|---|---|
0:00 | 面板:設定好的網址一按就開、上下鍵選取,也能開資料夾或 IDE |
0:16 | 在測試網站上,擴充功能跳出配對提示,到桌面程式核准,配對完成 |
0:32 | 擴充功能產生隨機密碼 → 註冊 → 送出後 OpDeck 主動問要不要存 → 取個名字存起來 |
0:52 | 下次登入點一下帳號欄,選剛存的帳密,自動填入 |
1:04 | HTTP 來源 json-todo:輸入不同的 id 即時查詢,只取出事先用 JSON Path 篩好的欄位,Enter 複製 |
功能說明
由三個部分組成:桌面的指令面板、網頁後台、瀏覽器擴充功能。

金鑰只存在桌面程式這一層:網頁後台拿不到金鑰,所以敏感值只能寫、不能讀;擴充功能也沒有金鑰、也不直接連 Server,要查詢或解密都透過本機的 Native Messaging 請桌面程式代勞;敏感值在 Server 上從頭到尾只有密文。

指令面板
- 直接打字就會同時搜尋
secrets、指令與來源,常用的會排在前面 Enter複製選到的secret,Ctrl+Enter則是原地偷看一眼而不複製- 指令有幾種類型,在後台用表單設定:
- 開啟網址
- 開啟資料夾
- 用
VS Code開啟某個路徑 - 呼叫一支
HTTP API,把回應裡的某個值複製出來
HTTP指令可以帶參數,執行時面板會一步一步問(例如要哪個環境);開網址、開資料夾這類指令則可以設定多個目標,執行時用子選單選- 指令裡可以放「裝置變數」,同一個指令在不同電腦上會代入各自的路徑或
token,而這些變數只存在那台裝置上 - 指令可以分組,一層一層點進去



- 產生隨機密碼
- 匯入
.env:在網頁後台貼上內容,逐筆加密後才上傳;之後可以重新匯入同步
登入項目與瀏覽器擴充功能
這一半就是密碼管理器。
- 除了
key/value的secret,另外有「登入項目」:網址、帳號、密碼、TOTP種子 - 擴充功能在登入頁偵測到表單時,會問要不要存;之後到同一個網站就能自動填入,
TOTP的驗證碼也直接從面板複製 - 新密碼由面板或擴充功能產生,每個網站一組隨機的,不用再自己想規則
- 登入項目預設是個人的,可以自願分享給組織;分享和取消分享可以在面板裡完成


網頁後台
- 管理
secrets、來源、指令、登入項目、裝置 - 組織與成員
- 稽核紀錄
- 本地帳號可以開啟
TOTP兩步驟驗證 - 也可以用
GitHub登入:網頁走一般的Authorization Code Flow;桌面程式沒有callback URL可以收,所以走OAuth Device Flow,畫面上顯示一組code、到瀏覽器按同意就好,client secret從頭到尾只在Server

Zero Knowledge
這個服務最核心的設計是:伺服器不會拿到明文,也沒有解密的金鑰。
Client 加密 -> 上傳密文 -> Server 只存密文與 metadata
-> 有權限的 Client 下載 -> Client 本地解密
- 每個
secret用自己的一把隨機金鑰加密,這把金鑰再用每一台有權限的裝置的公鑰分別包一次 - 裝置的私鑰在裝置上產生,放在作業系統提供的安全儲存區,從頭到尾沒有離開過那台裝置
- 所以就算資料庫整個被拿走,拿到的也只有密文

這個設計也帶來一些連鎖的限制,而這些限制都沒有為了方便而放寬:
- 網頁後台只能寫、不能讀:瀏覽器沒有安全的地方放私鑰,所以後台可以新增敏感的
secret,但看不到它的值(標成非敏感的Plain類型除外,那種本來就是明文) - 擴充功能自己不解密:它透過
Native Messaging請正在執行的桌面程式解密再填入,本身不持有任何金鑰 - 新裝置要先被核准,再等一台已授權的裝置上線:新裝置註冊後是待核准狀態,要在另一台已核准的桌面程式上比對指紋、按下核准;之後也得等一台持有金鑰的裝置上線替它重新包一份,因為伺服器沒辦法代替你重新加密
- 裝置全部遺失就救不回來:所以另外提供了可選的紙本復原金鑰,只顯示一次,不會存在任何地方
組成
- 後端:
Go(Gin+GORM+FX)、PostgreSQL - 網頁後台:
SvelteKit+Svelte 5+Tailwind - 桌面端:
Tauri 2(Rust),支援Windows與macOS - 瀏覽器擴充功能:
Chromium MV3 - 部署:
Docker Compose