การรับรองความถูกต้อง CLI อย่างถูกวิธี: คู่มือฉบับสมบูรณ์สำหรับทั้ง 4 วิธี
4 วิธีการรับรองความถูกต้อง CLI ที่สำคัญ, วิธีที่ GitHub, AWS, และเครื่องมือ AI นำไปใช้, และข้อผิดพลาดด้านความปลอดภัยที่คุณควรหลีกเลี่ยง
4 วิธีการรับรองความถูกต้อง CLI ที่สำคัญ, วิธีที่ GitHub, AWS, และเครื่องมือ AI นำไปใช้, และข้อผิดพลาดด้านความปลอดภัยที่คุณควรหลีกเลี่ยง
นักพัฒนา CLI ทุกคนจะมี login เป็นคำสั่งแรก และแต่ละตัวก็แก้ปัญหาการรับรองตัวตนแตกต่างกัน
GitHub จะแสดงโค้ดพร้อมเปิดเบราว์เซอร์ให้คุณยืนยัน, AWS จะเปิดเบราว์เซอร์เพื่อใช้ PKCE-based SSO, Stripe ให้คุณยืนยัน pairing code ใน dashboard และเครื่องมือ AI รุ่นใหม่ (Claude Code, OpenAI Codex CLI, Cursor) ก็มีวิธีของตัวเองด้วย
ถ้าคุณกำลังสร้าง CLI ใหม่ เรื่อง auth เป็นสิ่งที่คุณต้องคิดก่อนเป็นอันดับต้น ๆ เลือกผิดอาจโดนผู้ใช้งานบ่น, โดนตรวจสอบความปลอดภัย หรือทั้งคู่ และยุค AI coding agent ที่เรียก CLI แบบอัตโนมัติ ยิ่งต้องระวังให้มากขึ้น: คุณไม่ได้แค่ยืนยันตัวคนแล้ว แต่อาจยื่นข้อมูลรับรองให้งานอัตโนมัติด้วย
นี่คือ 4 วิธีสำคัญในการรับรองความถูกต้อง, ตัวอย่างการนำไปใช้จากเครื่องมือยอดนิยม และข้อผิดพลาดที่ควรหลีกเลี่ยง
ก่อนลงรายละเอียด มาดูตารางเปรียบเทียบสั้น ๆ กันก่อน:
| วิธี | เหมาะกับ | ความปลอดภัย | ต้องใช้เบราว์เซอร์? |
|---|---|---|---|
| OAuth Device Code Flow | สภาพแวดล้อมไร้หัว (headless), SSH | สูง | ไม่ (เบราว์เซอร์ในเครื่องใดก็ได้) |
| OAuth ผ่านเบราว์เซอร์ (localhost redirect) | การพัฒนาบนเครื่องโลคอล | สูงสุด | ใช่ |
| API Keys / PATs | ออโตเมชั่น, CI/CD, ทดลองเร็ว ๆ | ปานกลาง | ไม่ |
| Client Credentials | machine-to-machine, บริการ | สูง | ไม่ |
แต่ละแบบมีข้อดีข้อเสียต่างกัน มาดูรายละเอียดกัน
แบบนี้ CLI จะโชว์โค้ดเช่น ABCD-1234 และ URL แล้วบอกให้คุณเปิด URL นี้บนอุปกรณ์ใดก็ได้ กรอกโค้ดนั้น
ใครใช้: GitHub CLI (ดีฟอลต์), Azure CLI (ผ่าน --use-device-code), Vercel CLI (เปลี่ยนมาเป็นดีฟอลต์ล่าสุด), OpenAI Codex CLI (เบต้า)
cli loginclient_id และ scope ที่ต้องการไปด้วยdevice_code (รหัสภายใน), user_code (โค้ดสั้นให้ผู้ใช้กรอก), และ verification_uri (URL สำหรับยืนยัน)จุดขาย: ใช้ได้กับทุกที่ SSH เข้าเซิร์ฟเวอร์? ได้ รันใน Docker? ได้ Cloud IDE ที่ไม่เปิดเบราว์เซอร์? ก็ได้ ไม่ต้องขอเบราว์เซอร์บนเครื่องเดียวกันกับ CLI
ยังรองรับ enterprise auth เต็มรูปแบบ (SAML, OIDC, MFA) เพราะทุกอย่างเกิดในเบราว์เซอร์ ไม่ใช่ในเทอร์มินัล CLI ไม่เห็นรหัสผ่านของคุณเลย
Device code flow คือเป้าของการ phishing ผู้ไม่หวังดีสามารถสร้าง request เพื่อ device code, ได้ user code แบบถูกต้อง แล้วหลอกให้คุณนำไปกรอก ซึ่งเท่ากับคุณ authorize session ของคนร้าย มีรายงานการโจมตีแบบนี้กับ AWS SSO device code แล้วจริง ๆ
จุดนี้ AWS เปลี่ยนนโยบาย โดยตั้งแต่ AWS CLI v2.22.0 ดีฟอลต์ของ aws sso login จะกลายเป็น PKCE-based authorization code flow แทน แต่ device code ยังมีอยู่ผ่าน --use-device-code แค่ไม่ใช่ default
ขณะที่ฝั่ง Microsoft เริ่ม block device code flow ผ่าน conditional access policy แล้ว แสดงว่าพวกเขามองว่านี่คือตัวเลือกความเสี่ยงสูง
สั้น ๆ คือ: Vercel นำ device code flow มาใช้เป็นดีฟอลต์ใน ก.ย. 2025 ส่วน AWS เลิกใช้ เป็นดีฟอลต์ เหมาะกับกรณีที่เปิดเบราว์เซอร์ local ไม่ได้จริง ๆ ถ้าเปิดได้ PKCE ปลอดภัยกว่าเยอะ
สำหรับฝั่งผู้ให้บริการ auth ตัวเลือกนี้กำลังนิยม Logto เพิ่งปล่อย OAuth 2.0 Device Authorization Grant ให้ใช้กับ native app แล้วใน v1.38.0 (open source) และ Logto Cloud ถ้าคุณกำลังสร้าง CLI อยู่ ให้ provider จัดการ logic ให้นั้นสะดวกกว่า เพราะการทำ RFC 8628 ให้ครบถ้วน (หมดอายุ, จำกัด rate, polling, UX ที่หน้า verification) ไม่ง่าย
expires_in ของ device code ถูกกำหนดโดย auth server ตัว RFC เสนอ 1800 วินาที (30 นาที) เป็นตัวอย่าง ไม่จำเป็นต้องยึดตามนี้interval, client ควร default เป็น 5 วินาทีslow_down, เพิ่ม interval อีก 5 วินาทีนี่คือวิธีที่นิยมที่สุดสำหรับ CLI ที่รันบนเครื่องนักพัฒนาเอง คุณรัน login, แอปเปิดเบราว์เซอร์, login เสร็จ browser redirect กลับไปที่ localhost ที่ CLI เปิดไว้ สมัยนี้จะใช้ PKCE (อ่านว่า "pixie") เพิ่มเข้ามา ทำให้การโจมตีทำได้ยากขึ้นมาก
ใครใช้: Claude Code, gcloud CLI, Terraform CLI, AWS CLI v2.22+ (ใช้ PKCE SSO เป็นดีฟอลต์)
cli loginhttp://127.0.0.1:8742)http://127.0.0.1:8742/callback?code=XXXX&state=YYYYUX สมูธมาก ไม่ต้อง copy code ไม่ต้องพิมพ์ URL อะไรเลย
วิธีนี้จะใช้ได้เฉพาะเมื่อ CLI เปิดเบราว์เซอร์และ bind localhost ได้เท่านั้น ซึ่งแปลว่าใช้ไม่ได้ในกรณีต่อไปนี้:
จึงเห็นว่าเครื่องมือบางตัวที่ default เป็น browser OAuth มักจะมี fallback เช่น device code หรือ API key ด้วย
ข้อผิดพลาด 1: Bind ที่ 0.0.0.0 แทน 127.0.0.1
พบได้บ่อยและร้ายแรง เพราะ bind ที่ 0.0.0.0 ใครในวงแลนก็ดัก code ได้
เคยเห็น production CLI ทำผิดแบบนี้บ่อยมาก เพราะไลบรารี HTTP หลายตัว default เป็น 0.0.0.0
ข้อผิดพลาด 2: ไม่ตรวจสอบ state parameter
state คือการป้องกัน CSRF ถ้าขาดนี้ คนร้ายอาจหลอก CLI ให้รับ authorization code จาก session ปลอม
ข้อผิดพลาด 3: ไม่ใช้ PKCE
ถ้า flow OAuth ของคุณไม่ใช้ PKCE (Proof Key for Code Exchange), authorization code ที่ถูก intercept สามารถถูกนำไปแลก token ได้เลย
ใน standard code flow ถ้าโดนดักรหัส code (เช่นจาก redirect URL), จะแลก token ได้ PKCE ป้องกันนี้ด้วยการพิสูจน์ว่าทีมเดียวกับที่เริ่ม flow เท่านั้นที่แลกได้
PKCE เพิ่ม flow นี้เข้าไป:
code_verifier (random string ระดับ entropy สูง)code_challengecode_verifier กลับไปคนร้ายที่ intercept code ไม่มี code_verifier ก็จบ
นี่คือเหตุผลที่ AWS CLI v2.22+ เปลี่ยน default SSO เป็น PKCE browser OAuth+PKCE ดีกว่า device code flow ทั้ง UX และความปลอดภัย ฟิชชิ่งก็หมด Device code flow เหมาะกับกรณีที่เบราว์เซอร์ไม่ได้อยู่บนเครื่องเดียวกับ CLI (SSH, container, remote dev) ส่วน local development ใช้ PKCE ดีกว่า
วิธีที่ง่ายที่สุด: สร้าง token ที่ dashboard, นำไปวางใน config CLI หรือ environment variable ก็ใช้ได้ทันที
ใครใช้: Stripe CLI (เป็นหนึ่งใน login option), npm, pip, AI coding tools ส่วนใหญ่ (Claude Code ใช้ ANTHROPIC_API_KEY, OpenAI ใช้ OPENAI_API_KEY, Aider)
sk_live_, ghp_, npm_)~/.config/stripe/config.toml, ~/.aws/credentials) หรือ environment variableCLI จะอ่านและส่งเป็น header Authorization: Bearer ใน request
สำหรับ automation, API key ใช้ง่ายมาก CI/CD, container, script, cron job แค่ set env var ก็จบ ไม่ต้องใช้ browser ไม่ต้องมี prompt ไม่ต้อง refresh token อะไรทั้งนั้น
สำหรับ workflow แบบ AI agent, API key นี่แหละง่ายสุด Claude Code หรือ Cursor ที่ต้อง call API ผ่าน CLI แค่มี env var ก็โหลดได้
ถ้าต้องใช้ API key, ให้แลกเป็น token อายุสั้นที่ runtime เช่นที่ AWS ทำด้วย STS (Security Token Service) ใช้ credential ตัวจริงเพื่อขอ credential ชั่วคราวอายุ 1 ชั่วโมง มี aws-vault ทำให้อัตโนมัติ
ถึงจะเริ่มด้วย API key ก็ลองเพิ่มวิธีนี้ไว้ด้วย เพื่อจำกัดระยะเวลาความเสียหายจาก "จนกว่าจะถูกตรวจพบ" เหลือแค่ "1 ชั่วโมง"
OAuth 2.0 flow แบบนี้ออกแบบมาเพื่อการยืนยันตัวตนระหว่างเครื่องกับเครื่อง: service คุยกับ service ไม่มี user
ใช้กับ: CI/CD pipeline, บริการ background, เครื่องมือ automation
service ส่ง client_id กับ client_secret ไปตรง ๆ กับ auth server ได้ access token อายุสั้นกลับมา ไม่ต้องใช้เบราว์เซอร์ ไม่ต้องมี user ไม่ต้อง redirect
เหมาะเมื่อ:
อย่าใช้สำหรับผู้ใช้จริง เพราะไม่มี MFA, SSO หรือ verification แบบโต้ตอบ
อันนี้คือตารางสรุปที่อัปเดตล่าสุด อ้างอิงจากเอกสารและโค้ดจริง หลายเว็บไซต์เขียนผิดเพราะค่า default เปลี่ยนบ่อยมาก
| CLI Tool | ดีฟอลต์ auth | ตัวเลือก fallback | เก็บ token ที่ไหน |
|---|---|---|---|
GitHub CLI (gh) | Device code flow ผ่านเบราว์เซอร์ | PAT (--with-token), env var (GH_TOKEN) | OS keychain (fallback: plain text file) |
| AWS CLI v2 | PKCE auth code flow (SSO) | Device code (--use-device-code), credential files | ~/.aws/sso/cache/ |
Azure CLI (az) | WAM บน Windows; browser auth code flow บน Linux/macOS | Device code (--use-device-code) | ~/.azure/msal_token_cache.* |
| Vercel CLI | Device code flow (ดีฟอลต์ใหม่ ก.ย. 2025) | API token (--token, env var) | ~/.local/share/com.vercel.cli/auth.json |
| Stripe CLI | Browser-based pairing flow | API key (--interactive, --api-key, หรือ env var) | ~/.config/stripe/config.toml |
| gcloud CLI | Browser OAuth | --no-browser manual flow | ~/.config/gcloud/ |
| Claude Code | Browser OAuth | API key (env var, apiKeyHelper) | OS keychain / ~/.claude/.credentials.json |
| OpenAI Codex CLI | Browser OAuth | Device code (beta), API key | ~/.codex/auth.json / OS keyring |
| Terraform CLI | Browser OAuth | Token paste | ~/.terraform.d/credentials.tfrc.json |
แนวโน้ม: browser-based OAuth เป็นดีฟอลต์สำหรับ local, fallback เป็น device code สำหรับ headless และ API key สำหรับ automation PKCE ได้รับความนิยมเพิ่มขึ้นเพราะปลอดภัยสูงสุดถ้ามีเบราว์เซอร์
ต่อให้ auth ดีแค่ไหน ถ้าเก็บ token ผิดก็จบ
ทุกระบบ OS มี credential store แบบเข้ารหัสในตัว:
ปลอดภัย, มีฮาร์ดแวร์ช่วย, Control permissions ได้, CLI ไม่ต้องสร้าง crypto เอง
หากใช้ keychain ไม่ได้ (container, Linux มินิมอล) ให้ใช้ไฟล์ config ที่ permission limit สุด ๆ
ไฟล์ plaintext. ฟังดูง่าย แต่หลายเครื่องมือยังทำอยู่ ทุก process ที่ใช้งาน user เดียวกัน/back up/แม้แต่แค่คนอื่นนั่งเครื่องก็เปิดดูได้หมด
Environment variable แบบเก็บระยะยาว. Env var โชว์ใน process listing, ฝังใน log/crash dump/child process, เหมาะกับ CI/CD (ที่ secret ถูกจัดการโดยแพลตฟอร์ม) แต่ไม่ควรใช้กับ local
Browser localStorage. ถ้า CLI ของคุณมี web component อย่าเก็บ token ใน localStorage ช่องโหว่ XSS รั่วหมด
ควรอายุสั้น (1 ชั่วโมงเป็นมาตรฐาน) เมื่อหมดอายุ CLI ควร refresh เองโดย user ไม่ต้อง re-login
Refresh token เป็นรหัสระยะยาวสำหรับขอ access token ใหม่โดยไม่ต้องยืนยันใหม่ มูลค่าสูงสำหรับคนร้าย (เพราะอายุนาน)
ระบบ auth สมัยใหม่จะหมุน refresh token ทุกครั้งที่ใช้:
ถ้า refresh token โดนขโมย แล้วเจ้าของที่ถูกต้องใช้ก่อน หน้า server เจอ token reuse จะรีเซ็ตทั้งชุด (ทั้งของโจรและของ user จริง) บังคับ re-auth ป้องกันคนร้ายรักษา session ไว้ได้
ย้ำอีกที: bind ที่ 127.0.0.1 เท่านั้น อย่าใช้ 0.0.0.0
เกิดขึ้นบ่อยอย่างไม่น่าเชื่อ debug log/error มัก log header รวม token ไปและสุดท้ายก็โผล่ใน Slack
Docker image ไม่ใช่ที่เก็บความลับ ทุกเลเยอร์แตกไฟล์ดูได้หมด
ถ้า token หมดอายุระหว่างใช้งาน อย่าให้ crash 401 ดื้อ ๆ ควรลอง refresh ดูก่อน ถ้า refresh ก็หมดด้วยค่อยบังคับ login ใหม่
อย่าไปขอ scope admin:* ถ้าต้องการแค่ repo:read ทั้ง OAuth scope และ API key
ถ้า AI agent ใช้ CLI ของคุณยิ่งสำคัญ อย่าให้สิทธิ์มากกว่ารีดจริง ให้แค่พอใช้งาน
นี่คือสิ่งที่ทำให้ปี 2026 ไม่เหมือนปี 2023: CLI ไม่ใช่แค่คนพิมพ์แล้วตอนนี้ AI coding agent อย่าง Claude Code, Codex, Cursor agent mode เรียก CLI อัตโนมัติ ทำให้เรื่อง auth ยากขึ้น
Delegated permissions. เมื่อ Claude Code รัน gh pr create แทนคุณ มันใช้ credential ของ คุณ แต่ควรหรือไม่ที่ agent จะได้สิทธิ์เท่าคุณ? หลัก least privilege ตอบว่าไม่ควร แต่เครื่องมือส่วนใหญ่ยังไม่มีฟีเจอร์คุมขอบเขตสิทธิ์ agent แยก
Credential exposure. ถ้า API key อยู่ใน env var ทุก process ใน environment นั้นอ่านได้หมด รวมถึง subprocess ของ AI agent Claude Code บางตัวแก้ด้วย apiKeyHelper ที่ generate token อายุน้อย on demand แต่ยังไม่เหมือนกันหมด
Headless auth สำหรับ agent. AI agent ใน sandbox เปิดเบราว์เซอร์ไม่ได้ device code flow ใช้ได้ (คนไป approve บนอุปกรณ์อื่น) แต่ API key นิยมเพราะไม่ต้องโต้ตอบใด ๆ
Audit trail. ถ้า agent เรียก API ด้วย credential ของคุณ log จะโชว์ว่า คุณ เป็นคนทำ ไม่มีวิธีแยกว่า "มนุษย์ทำ" หรือ "agent ทำแทนมนุษย์"
ข้อปฏิบัติ:
จะเลือกวิธี auth แบบไหน อ่านสรุปสั้นต่อไปนี้ได้เลย:
"ผู้ใช้ของฉันคือ dev บนเครื่อง local" → ใช้ browser-based OAuth + PKCE (ปลอดภัยสุด + UX ดียอด)
"CLI ต้องใช้ได้ใน SSH หรือ container" → Device code เป็น fallback, browser OAuth เป็นหลัก
"รันใน CI/CD แบบไม่มีมนุษย์" → Client credentials flow หรือ API key แบบ limit ขอบเขต
"ขอติดตั้งเร็วสุด" → API key (แต่เพิ่ม token rotation ทีหลัง)
"ลูกค้าองค์กรต้อง SSO กับ MFA" → OAuth flow อะไรก็ได้ (device code หรือ browser) รองรับ auth สำหรับองค์กร
"AI agent จะใช้ CLI ตัวนี้" → รองรับ API key (สำหรับ agent) + browser OAuth (สำหรับคน), จำกัดขอบเขต permission และใช้ token อายุน้อย
ปลอดภัยกับโจมตีส่วนใหญ่ แต่มีช่องโหว่ phishing คือโจรสร้าง device code แล้วหลอกให้ user authorize ซึ่ง AWS จึงเปลี่ยน default SSO เป็น PKCE แต่กรณีที่ PKCE ใช้ไม่ได้ device code ก็ยังดีที่สุด เพียงแต่ต้องตระหนักเรื่อง phishing
บน CI/CD: ได้ เพราะ platform จัดการ secret เข้ารหัส inject ให้เอง แต่ local ไม่ควร ควรใช้ OS keychain ดีกว่า เพราะ env var มองเห็นได้ใน process list, log, และลูก process อื่น
ฟังก์ชันเหมือนกัน ต่างแค่ชื่อและวิธีจัดการ API key จะผูกกับโปรเจคหรือแอป ส่วน PAT ผูกกับผู้ใช้ บางเจ้าสลับใช้ชื่อกัน
Access token: ทุก 1 ชั่วโมงหรือน้อยกว่า (token refresh flow จัดการ) Refresh token: หมุนทุกครั้งที่ใช้ (auth server จัดการ) API key: อย่างน้อยทุก 90 วัน หรือทันทีที่สงสัยว่าหลุด ในทางปฏิบัติมักหมุนหลังเกิดเรื่อง ซึ่งช้าเกินไป
3 ตัวเลือก อันดับความปลอดภัย:
docker run -e API_KEY=${API_KEY}) สำหรับ CI/CDdocker run -v ~/.config/tool:/root/.config/tool:ro) สำหรับ developmentอย่าฝัง credential ลงใน image เด็ดขาด
MCP คือมาตรฐานใหม่สำหรับ AI agent เชื่อมต่อกับเครื่องมือ/บริการภายนอก มุม auth คือ agent ต้องใช้ credential กับ MCP server ซึ่งเองก็ต้องใช้ credential กับ downstream API ตอนนี้มักใช้ API key หรือ OAuth token ผ่าน config อยู่ กำลังพัฒนาอยู่เร็วมาก
CLI auth กำลังเปลี่ยนไวมาก สิ่งที่เคยเป็น best practice เมื่อสองปีก่อน (device code flow ดีฟอลต์, cred file plain text) กำลังถูกแทนที่ ถ้าคุณจะเพิ่ม auth ให้ CLI ตอนนี้ เริ่มด้วย browser OAuth + PKCE สำหรับมนุษย์, API key สำหรับ automation แล้ววางแผนสำหรับวันที่ AI agent จะเป็นผู้ใช้หลักของคุณด้วย