搞對 CLI 認證:完整解析 4 種方法指南
4 種重要的 CLI 認證方法、GitHub、AWS 與 AI 工具如何實作,以及你必須避開的安全陷阱。
每個開發者 CLI 的第一個指令都是 login。但每個 CLI 處理認證的方式都不一樣。
GitHub 會顯示一個驗證碼並打開瀏覽器讓你驗證。AWS 則是用瀏覽器開啟基於 PKCE 的 SSO。Stripe 則讓你在儀表板裡確認配對碼。新興的 AI 工具(Claude Code、OpenAI Codex CLI、Cursor)也都有各自的新做法。
如果你正在開發 CLI,認證機制會是你必須優先解決的事。選錯方法,你很快就會收到用戶的抱怨、安全稽核報告,甚至兩者兼有。隨著近期 AI 編碼代理能程式化呼叫 CLI 工具,這件事變得更關鍵:不只是驗證一個人類,還有可能是允許自主流程獲取金鑰。
以下是目前主流的四種 CLI 認證方式、各大工具怎麼實作,以及常見錯誤與破口。
四種認證方式總覽
先快速比較一次:
| 方法 | 適用場景 | 安全性 | 需要瀏覽器? |
|---|---|---|---|
| OAuth 裝置驗證碼流程 | 無頭環境、SSH | 高 | 不需要(同一台機器上) |
| 瀏覽器 OAuth(localhost redirect) | 本地開發 | 最高 | 需要 |
| API Key / 個人存取權杖 | 自動化、CI/CD、快速原型開發 | 中等 | 不需要 |
| Client Credentials | 機器對機器、服務間 | 高 | 不需要 |
每個方法都有權衡。以下是你需要知道的重點。
1. OAuth 裝置驗證碼流程(RFC 8628)
這就是 CLI 會顯示一個像 ABCD-1234 的驗證碼與網址,讓你在任一裝置打開網址並輸入驗證碼的流程。
採用範例: GitHub CLI(預設)、Azure CLI(用 --use-device-code)、Vercel CLI(最近改為預設)、OpenAI Codex CLI(Beta 選項)
運作方式
- 你執行
cli login - CLI 發出裝置驗證碼要求至認證伺服器,帶上
client_id與要求的 scope - 伺服器回傳三樣東西:
device_code(內部用 ID)、user_code(短驗證碼)、verification_uri(要去的網頁) - CLI 顯示驗證碼與網址,並開始每 5 秒輪詢伺服器
- 你可以用「任何一台」設備打開網址、輸入驗證碼並完成認證(密碼、SSO、密碼金鑰、MFA 都可以)
- 你核可後,下一次 CLI 輪詢會取得 Access Token 與 Refresh Token
- CLI 保存該資料,你就登入成功了
為什麼開發者喜歡這種方式
最大賣點:到處都可用。SSH 連進遠端主機?可用。跑在 Docker container 裡?可用。雲端 IDE 沒有本地瀏覽器?還是可用。因為瀏覽器不必跟 CLI 在同一台機器。
它也支援企業級的權限控管(SAML、OIDC、MFA),因為相關流程都在瀏覽器完成,終端機從來不用處理密碼。
多數人忽略的安全隱憂
Device code flow 會有釣魚風險。攻擊者可以發起 device code 請求,取得合法驗證碼,誘使用戶輸入,等於讓攻擊者的 session 被授權。這不是理論上,AWS SSO 已有安全研究者證實此攻擊有效。
**AWS 已因為這問題更改預設。**AWS CLI v2.22.0 起,aws sso login 預設從 device code flow 改成 PKCE 授權碼流程。不過你還是可以用 --use-device-code 強制用裝置驗證碼流程——只是已經不是預設值。
微軟自家租戶則 已經用條件存取政策完全封鎖 device code flow,明顯認定這種認證方式高風險。
所以現在有趣的分歧:Vercel 2025 年 9 月才改成預設用 device code flow,但 AWS 則反方向換掉。總結就是,如果真的無法開瀏覽器,device code flow 是最佳解——但用本機瀏覽器,PKCE 更安全。
認證服務端的支援也在快速提升。Logto 剛釋出 v1.38.0 支援原生 App 的 Device Authorization Grant(open source 與 Logto Cloud 都有),所以你在做 CLI 時可以直接啟用。RFC 8628 正確實作(效期處理、節流、輪詢、登入 UX...)比大多數團隊想像更費工,但讓 SaaS 認證平台代勞,可以讓你只需正確呼叫 http API。
RFC 實際細節
值得注意幾點:
expires_in(驗證碼有效期)由認證伺服器設定,RFC 以 1800 秒(30 分鐘)為例,但不是硬性規定。- 若伺服器沒給出輪詢間隔,Client 預設 5 秒。
- 收到
slow_down,每次輪詢間隔需再加 5 秒。 - device code 通常只使用一次且應快速過期。
- token 交換一定要走 HTTPS。
2. 瀏覽器 OAuth(localhost redirect)
這是本地 CLI 最主流的登入方式——login 會開瀏覽器認證,然後 browser redirect 回 CLI 開的小型本地 http server。現代實作都會加上 PKCE(音 "pixie"),安全性大幅提升。
採用範例: Claude Code、gcloud CLI、Terraform CLI、AWS CLI v2.22+(SSO, 預設 PKCE)
運作方式
- 執行
cli login - CLI 隨機挑 一個 port 開啟 http server(例如
http://127.0.0.1:8742) - 開預設瀏覽器,帶 localhost URL 作為 redirect URI
- 在瀏覽器進行認證(SSO、密碼、passkey ...)
- 認證商將瀏覽器導到
http://127.0.0.1:8742/callback?code=XXXX&state=YYYY - 本地 server 捕捉到 code,再經由 HTTPS 跟後端換取 token
- 瀏覽器頁面顯示「成功!」,你可以關閉分頁
- CLI 儲存 token、關閉 local server
使用體驗流暢,無需複製黏貼驗證碼,也不用自己打網址。
不適用時機
當 CLI 無法開瀏覽器、無法綁定 localhost 時就 GG 了,包括:
- SSH 遠端 session
- Docker container(除非大搞 port 映射)
- CI/CD pipeline
- 無頭 server
- 部分公司內網有阻擋
所以大多數預設用 browser OAuth 的工具,也會提供 device code 或 API key 當備用方案。
3 個常爆雷的安全缺失
爆雷 1:綁定 0.0.0.0 而非 127.0.0.1
最常見錯誤,而且很嚴重。如果你的 callback server 綁定到所有網路介面,任何區網裡的人都能攔截你的授權碼。
這問題在生產環境 CLI 很常見,因為很多 http server library 預設 0.0.0.0。
爆雷 2:沒檢查 state 參數
state 參數就是防 CSRF 的保護措施。沒檢查,攻擊 者可能讓 CLI 認領他發起的認證 Session。
爆雷 3:沒用 PKCE
OAuth 流程沒用 PKCE(Proof Key for Code Exchange)的話,授權碼被攔截會被重放。
在標準的授權碼流程裡,如果有人攔走你的 code(例如網路中間人、看到 redirect 網址),他就能用那 code 換取 token。有 PKCE 後,token 交換只會給發起流程的同一個 client 使用。
PKCE 流程如下:
- flow 開始前,CLI 隨機產生一組
code_verifier(高熵字串) - 用 SHA-256 hash 出
code_challenge - challenge 加到認證請求裡送出
- 換 token 時帶原始
code_verifier - 認證伺服器比對一致才放行
攔到 code 的攻擊者沒 code_verifier,完全沒戲。
這就是 AWS CLI v2.22+ SSO 預設改用 PKCE 的原因——瀏覽器在本機能開時,browser OAuth + PKCE 比 device code flow 更安全,不會被釣魚騙走 session。如果一定無法本機開瀏覽器,才用 device code flow。大部分本地開發都適用 browser OAuth + PKCE。
3. API key 與個人存取權杖
最陽春的方式:你去 Web 儀表板生一組金鑰,貼到 CLI 設定或環境變數就完事。
採用範例: Stripe CLI(login 選項)、npm、pip、多數 AI 工具 fallback(Claude Code 用 ANTHROPIC_API_KEY,OpenAI 用 OPENAI_API_KEY,Aider)
運作方式
- 登入服務網站
- 找設定 → API 金鑰(或個人存取權杖、開發金鑰)
- 產生新金鑰,通常有個前綴(例如
sk_live_、ghp_、npm_) - 存在設定檔(如
~/.config/stripe/config.toml、~/.aws/credentials)或環境變數
CLI 啟動時會讀進來,作為 Authorization header 發送 API request。
為什麼還是非常流行
自動化場合,API key 幾乎無敵。CI/CD、container、script、cron job 都適用。完全不需瀏覽器,無交互操作,無需 token refresh。
AI agent workflow 也非常愛 API key。Claude Code、Cursor 等要呼叫 API 時,環境變數夠簡單。
但風險也很現實
- 外洩。 API key 容易出現在 git、log、錯誤訊息、CI output。GitHub 一年掃出超過百萬次金鑰外洩。
- 權限太大。 多數 API key 權限很寬,外洩影響巨大。
- 沒有 MFA。 API key 會繞過你設好的多重認證。
- 很難輪換。 一換金鑰就要到處同步檔案、環境變數。團隊協作時難度更高。
現代進化法:短效金鑰換取
聰明的做法是:長效金鑰只用來換取短效 token。
AWS 是先驅,利用 STS(Security Token Service)讓你的長效金鑰只拿來 request 一小時的短效金鑰。aws-vault 這類工具自動處理整個流程。
即使一開始就只有 API key,建議還是實作這種模式。這樣萬一外洩,傷害從「被發現前都可用」降到「一小時」。
4. Client credentials flow
這是 OAuth 2.0 設計給機器對機器之間的授權流程:沒有人類參與。
採用場景: CI/CD pipeline、背景服務、自動工具
運作方式
服務端直接送上 client_id 與 client_secret,回傳短效 access token。完全不需瀏覽器、無人干預、無需跳轉。
適用時機
當以下情況:
- 機器或 bot 需要認證,而不是人類
- 在 CI/CD pipeline
- 需要自動、無人值守登入
- 「用戶」本身就是應用服務
不要給人類裝認證用。這種 flow 沒法做 MFA、SSO、或需互動獲取驗證。
各大 CLI 工具認證現狀
以下整理自文件或 source code,很多網路文章資訊已過時。
| CLI 工具 | 預設認證 | 備用選項 | 金鑰儲存方式 |
|---|---|---|---|
GitHub CLI (gh) | 裝置驗證碼 flow | PAT (--with-token)、環境變數 (GH_TOKEN) | OS 金鑰鏈(fallback: 明文檔案) |
| AWS CLI v2 | PKCE 授權碼(SSO) | Device code (--use-device-code)、憑證檔 | ~/.aws/sso/cache/ |
Azure CLI (az) | Windows 用 WAM; Linux/macOS 用 browser auth code flow | Device code (--use-device-code) | ~/.azure/msal_token_cache.* |
| Vercel CLI | Device code flow(2025/9 新預設) | API token (--token、環境變數) | ~/.local/share/com.vercel.cli/auth.json |
| Stripe CLI | 瀏覽器配對流程 | API key (--interactive, --api-key, or env var) | ~/.config/stripe/config.toml |
| gcloud CLI | Browser OAuth | --no-browser 手動流 | ~/.config/gcloud/ |
| Claude Code | Browser OAuth | API key (環境變數、apiKeyHelper) | OS 金鑰鏈 / ~/.claude/.credentials.json |
| OpenAI Codex CLI | Browser OAuth | Device code (beta)、API key | ~/.codex/auth.json / OS 金鑰鏈 |
| Terraform CLI | Browser OAuth | 貼上 token | ~/.terraform.d/credentials.tfrc.json |
趨勢明確:**本 地開發預設 browser OAuth,加上 device code 作為 headless 備用,API key 負責自動化腳本。**有瀏覽器時,PKCE 成為安全性最高的主流。
Token 儲存策略:怎麼做才安全
即使前面認證做對,如果金鑰儲存錯了還是白搭。
對的做法:用 OS 金鑰鏈
每個 OS 都有內建加密憑證儲存:
- macOS: Keychain(GitHub CLI、Claude Code 都採用)
- Windows: Credential Manager
- Linux: Secret Service API(GNOME Keyring、KDE Wallet)
這些提供 OS 層級加密、存取權限、甚至支援硬體安全性。CLI 本身不用自己搞加密。
無法用時的備用方案:加密設定檔
沒法用金鑰鏈時(如 container、極簡環境),可用加密檔案加嚴格權限:
千萬別這麼做
明文檔案。 聽起來老掉牙,但還真有很多工具在用。明文金鑰檔案對本機所有進程、備份程式,以及任何能臨時存取你機器的用戶都易如反掌。
長期金鑰放環境變數。 環境變數能被 process list 看到,也常被 crash reporter、除錯工具 log 下來,被子進程繼承。CI/CD 環境(一個 Job 用一次)可,但本機開發很危險。
Browser localStorage。 CLI 若有 Web 介面,千萬別把 token 存在 localStorage。只要有 XSS,全部一把抓。
Token 生命週期管理
Access token
一定要設短效。一小時最常見。到期時 CLI 自動 refresh,不該讓用戶一到期就要重登才能繼續工作。
Refresh token
Refresh token 是長時效金鑰,用來免重登入取得 access token。它們價值極高,通常效期好幾天甚至幾個月。
Refresh token 輪換
當代服務會每用一次 refresh token 就自動換掉:
- CLI 用 refresh token 拿新 access token
- 認證伺服器回應 access token 與一組新 refresh token
- 舊的 refresh token 立即作廢
- CLI 只保存最新 token
這樣即使 refresh token 被偷,如果被盜用方跟正當用戶碰撞到同一組舊 token 使用,伺服器會偵測 reuse,整組 family 一次註銷。攻擊者跟用戶都需重登,但能阻止攻擊者持續存取。
常見爆雷實例(含程式碼)
1. callback server 綁定所有介面
前文已提,永遠只綁 127.0.0.1,不要 0.0.0.0。
2. token 被寫進 log
這比大家承認的還普遍。debug log、錯誤 handler 印 request header、一個過度詳盡的 verbose mode...
3. 把金鑰 bake 進 Docker image
Docker image 不是秘密儲存區,每一層金鑰都可被抽出來。
4. 沒妥善處理 token 過期
作業中 token 過期,不能直接 401 錯誤就閃退,應自動 refresh。只有 refresh token 也到期才要求重登入。
5. 忽略最小權限原則
不要要什麼都用 admin:* scope,明明只需 repo:read。這包括 OAuth scope 與 API key 權限。
AI agent 操作 CLI 時特別要注意。沒人想讓 AI 助手能砍掉 repo,只因它用 CLI 讀程式碼。
AI agent 新挑戰
2026 年與 2023 最大不同之處:CLI 現在不只是人類在打指令,AI 編碼 agent(如 Claude Code、Codex、Cursor agent mode)也會程式化呼叫 CLI 工具。這帶來新的認證挑戰:
權限委託。 Claude Code 代你跑 gh pr create,其實是用「你的」 GitHub 金鑰。但 AI agent 應該擁有你完整權限嗎?最小權限原則說不行,偏偏大多工具還沒法限定 agent 權限。
金鑰外洩風險。 API key 放在環境變數,所有進程都能看到,包括 AI agent 的 subprocess。Claude Code 加了 apiKeyHelper script 可動態產生短效金鑰,但目前尚未是主流。
headless 認證。 sandoxed 的 AI agent 無法開瀏覽器。這時 device code flow 比較適合(人類可用他裝置批准),但自動化流程多半乾脆直接用 API key 省麻煩。
審計紀錄。 AI agent 拿你的金鑰發 API call,log 裡看到的都是「你」做的。尚未有業界標準區分「人親自操作」還是「agent 代操」。
這領域還在進化。目前建議你:
- agent 流程使用最小權限的 scoped token
- 優先用短效金鑰(短效 token、避免長期 API key)
- agent 用專屬 credential,別跟個人金鑰混用
- 主動監控 API 使用異常
決策對照表
挑認證方式?快速參考:
「用戶多為本地開發者」 → Browser OAuth + PKCE(最佳安全與順暢體驗)
「CLI必須支援 SSH 與 container」 → 主要用 browser OAuth,備用 device code flow
「CI/CD pipeline 完全無人操作」 → client credentials flow 或 scoped API key
「我要最快的開發速度」 → 先上 API key(後續再實作 token 輪換)
「企業客戶要求 SSO 與 MFA」 → 任一種 OAuth flow(device code 或 browser)皆支援完整企業認證
「AI agent 會用這 CLI」 → 支援 API key(方便 agent),也支援 browser OAuth(給人用),要配合最小權限與短效金鑰
常見問題
Device code flow 安全嗎?
一般攻擊已相對安全,但有已知釣魚風險。攻擊者能生一組 device code 騙人輸入,等於取得授權。所以 AWS 才把登入預設從 device code flow 換成 PKCE。無法用 PKCE 的 headless 環境,device code flow 仍是最佳解,但要有釣魚意識。
token 可以存環境變數嗎?
CI/CD 場景:可以,CI 平台會加密硬碟儲存並於執行時注入。 本地開發:不推薦。改用 OS 金鑰鏈。環境變數 process list 裡能看到,很容易被意外 log 出或外洩給子進程。
API key 跟個人存取權杖有什麼差?
功能幾乎無差,兩者都是長期金鑰可做 API 認證。主要差異在組織用途:API key 通常綁服務/專案,personal access token(PAT)綁帳號。本質雷同,名稱差異而已。
金鑰要多久輪換一次?
Access token:1 小時以下(多由 token refresh 流程自動處理)。Refresh token:每用一次就輪換(伺服器應自動做)。API key:90 天內要換一次,或有風險時立刻換。現實是多數團隊都是出事才換,這明顯慢了。
Docker container 裡怎麼做認證?
依優先順序:
- Device code flow 適用互動流程(browser 可在別台裝置)
- 環境變數 runtime 傳入(
docker run -e API_KEY=${API_KEY}),適合 CI/CD - mount 掛入 credential 檔案(
docker run -v ~/.config/tool:/root/.config/tool:ro),適合本地開發
永遠不要 bake credential 進 image,永遠不要。
MCP(Model Context Protocol)如何做認證?
MCP 是 AI agent 跟各工具和服務溝通的新興標準。它引入新維度:agent 需要 credential 跟 MCP server 認證,MCP server 又要憑證跟下游 API 溝通。標準化還在進展,目前多數 MCP 只把 API key 或 OAuth token 塞進 MCP 設定欄位。預期這會快速演變。
CLI 認證變化快。兩年前還算最佳實踐的 device code flow 預設、明文 token 檔,如今已不夠安全。如果你今天要加認證給 CLI,建議採用「browser OAuth + PKCE 給人用、API key 給自動程式」的雙模式,並預作 AI agent 會成為主力用戶的打算。

