搞對 CLI 認證:完整解析 4 種方法指南
4 種重要的 CLI 認證方法、GitHub、AWS 與 AI 工具如何實作,以及你必須避開的安全陷阱。
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 | 機器對機器、服務間 | 高 | 不需要 |
每個方法都有權衡。以下是你需要知道的重點。
這就是 CLI 會顯示一個像 ABCD-1234 的驗證碼與網址,讓你在任一裝置打開網址並輸入驗證碼的流程。
採用範例: GitHub CLI(預設)、Azure CLI(用 --use-device-code)、Vercel CLI(最近改為預設)、OpenAI Codex CLI(Beta 選項)
cli loginclient_id 與要求的 scopedevice_code(內部用 ID)、user_code(短驗證碼)、verification_uri(要去的網頁)最大賣點:到處都可用。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。
值得注意幾點:
expires_in(驗證碼有效期)由認證伺服器設定,RFC 以 1800 秒(30 分鐘)為例,但不是硬性規定。slow_down,每次輪詢間隔需再加 5 秒。這是本地 CLI 最主流的登入方式——login 會開瀏覽器認證,然後 browser redirect 回 CLI 開的小型本地 http server。現代實作都會加上 PKCE(音 "pixie"),安全性大幅提升。
採用範例: Claude Code、gcloud CLI、Terraform CLI、AWS CLI v2.22+(SSO, 預設 PKCE)
cli loginhttp://127.0.0.1:8742)http://127.0.0.1:8742/callback?code=XXXX&state=YYYY使用體驗流暢,無需複製黏貼驗證碼,也不用自己打網址。
當 CLI 無法開瀏覽器、無法綁定 localhost 時就 GG 了,包括:
所以大多數預設用 browser OAuth 的工具,也會提供 device code 或 API key 當備用方案。
爆雷 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 流程如下:
code_verifier(高熵字串)code_challengecode_verifier攔到 code 的攻擊者沒 code_verifier,完全沒戲。
這就是 AWS CLI v2.22+ SSO 預設改用 PKCE 的原因——瀏覽器在本機能開時,browser OAuth + PKCE 比 device code flow 更安全,不會被釣魚騙走 session。如果一定無法本機開瀏覽器,才用 device code flow。大部分本地開發都適用 browser OAuth + PKCE。
最陽春的方式:你去 Web 儀表板生一組金鑰,貼到 CLI 設定或環境變數就完事。
採用範例: Stripe CLI(login 選項)、npm、pip、多數 AI 工具 fallback(Claude Code 用 ANTHROPIC_API_KEY,OpenAI 用 OPENAI_API_KEY,Aider)
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 時,環境變數夠簡單。
聰明的做法是:長效金鑰只用來換取短效 token。
AWS 是先驅,利用 STS(Security Token Service)讓你的長效金鑰只拿來 request 一小時的短效金鑰。aws-vault 這類工具自動處理整個流程。
即使一開始就只有 API key,建議還是實作這種模式。這樣萬一外洩,傷害從「被發現前都可用」降到「一小時」。
這是 OAuth 2.0 設計給機器對機器之間的授權流程:沒有人類參與。
採用場景: CI/CD pipeline、背景服務、自動工具
服務端直接送上 client_id 與 client_secret,回傳短效 access token。完全不需瀏覽器、無人干預、無需跳轉。
當以下情況:
不要給人類裝認證用。這種 flow 沒法做 MFA、SSO、或需互動獲取驗證。
以下整理自文件或 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 成為安全性最高的主流。
即使前面認證做對,如果金鑰儲存錯了還是白搭。
每個 OS 都有內建加密憑證儲存:
這些提供 OS 層級加密、存取權限、甚至支援硬體安全性。CLI 本身不用自己搞加密。
沒法用金鑰鏈時(如 container、極簡環境),可用加密檔案加嚴格權限:
明文檔案。 聽起來老掉牙,但還真有很多工具在用。明文金鑰檔案對本機所有進程、備份程式,以及任何能臨時存取你機器的用戶都易如反掌。
長期金鑰放環境變數。 環境變數能被 process list 看到,也常被 crash reporter、除錯工具 log 下來,被子進程繼承。CI/CD 環境(一個 Job 用一次)可,但本機開發很危險。
Browser localStorage。 CLI 若有 Web 介面,千萬別把 token 存在 localStorage。只要有 XSS,全部一把抓。
一定要設短效。一小時最常見。到期時 CLI 自動 refresh,不該讓用戶一到期就要重登才能繼續工作。
Refresh token 是長時效金鑰,用來免重登入取得 access token。它們價值極高,通常效期好幾天甚至幾個月。
當代服務會每用一次 refresh token 就自動換掉:
這樣即使 refresh token 被偷,如果被盜用方跟正當用戶碰撞到同一組舊 token 使用,伺服器會偵測 reuse,整組 family 一次註銷。攻擊者跟用戶都需重登,但能阻止攻擊者持續存取。
前文已提,永遠只綁 127.0.0.1,不要 0.0.0.0。
這比大家承認的還普遍。debug log、錯誤 handler 印 request header、一個過度詳盡的 verbose mode...
Docker image 不是秘密儲存區,每一層金鑰都可被抽出來。
作業中 token 過期,不能直接 401 錯誤就閃退,應自動 refresh。只有 refresh token 也到期才要求重登入。
不要要什麼都用 admin:* scope,明明只需 repo:read。這包括 OAuth scope 與 API key 權限。
AI agent 操作 CLI 時特別要注意。沒人想讓 AI 助手能砍掉 repo,只因它用 CLI 讀程式碼。
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 代操」。
這領域還在進化。目前建議你:
挑認證方式?快速參考:
「用戶多為本地開發者」 → 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 騙人輸入,等於取得授權。所以 AWS 才把登入預設從 device code flow 換成 PKCE。無法用 PKCE 的 headless 環境,device code flow 仍是最佳解,但要有釣魚意識。
CI/CD 場景:可以,CI 平台會加密硬碟儲存並於執行時注入。 本地開發:不推薦。改用 OS 金鑰鏈。環境變數 process list 裡能看到,很容易被意外 log 出或外洩給子進程。
功能幾乎無差,兩者都是長期金鑰可做 API 認證。主要差異在組織用途:API key 通常綁服務/專案,personal access token(PAT)綁帳號。本質雷同,名稱差異而已。
Access token:1 小時以下(多由 token refresh 流程自動處理)。Refresh token:每用一次就輪換(伺服器應自動做)。API key:90 天內要換一次,或有風險時立刻換。現實是多數團隊都是出事才換,這明顯慢了。
依優先順序:
docker run -e API_KEY=${API_KEY}),適合 CI/CDdocker run -v ~/.config/tool:/root/.config/tool:ro),適合本地開發永遠不要 bake credential 進 image,永遠不要。
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 會成為主力用戶的打算。