← กลับไปหน้าบทความ
คู่มือ

ตั้งค่า MCP OAuth ให้ Agent พิสูจน์ตัวตนก่อนแตะ Tool ทุกตัว

ทีมบรรณาธิการ linli12 ส.ค. 04:52อัปเดต 12 ส.ค. 04:52อ่าน 4 นาที
ตั้งค่า MCP OAuth ให้ Agent พิสูจน์ตัวตนก่อนแตะ Tool ทุกตัว
บทความนี้จัดทำเพื่อความรู้ ชื่อธุรกิจ ตัวเลข หรือบทสนทนาที่ไม่มีแหล่งอ้างอิงกำกับเป็นกรณีตัวอย่างเพื่ออธิบายแนวคิด ดูรายละเอียดที่ นโยบายกองบรรณาธิการ

สรุปสั้น ๆ

MCP OAuth คือการใช้มาตรฐาน OAuth เป็นกลไกยืนยันตัวตนและกำหนดสิทธิ์ให้ Client เข้าถึง Remote MCP Server แทนการฝัง API Key ตายตัวไว้ในโค้ด หัวใจสำคัญคือการออกแบบ Scope ของ Token ให้ Agent เรียก Tool ได้เฉพาะเท่าที่จำเป็นจริง กำหนดอายุ Token ให้เหมาะสม และมีทางเพิกถอนสิทธิ์ได้ทันทีเมื่อพบความผิดปกติ

หลังทีมพัฒนาตัดสินใจย้าย MCP Server ไปเป็น Remote คำถามแรกที่ตามมาเสมอคือจะยืนยันตัวตนของ Agent ที่เรียกเข้ามาอย่างไร บางทีมเริ่มจากวิธีง่ายที่สุดคือฝัง API Key ตัวเดียวไว้ให้ทุก Client ใช้ร่วมกัน ซึ่งใช้งานได้จริงในระยะสั้น แต่พอมีคนหลายกลุ่มเข้าถึง Server เดียวกัน วิธีนี้เริ่มมีรอยรั่วที่มองเห็นได้ชัด

ปัญหาของ API Key ตัวเดียวคือไม่มีทางรู้ว่าใครเป็นคนเรียกจริง ไม่มีทางจำกัดว่าแต่ละคนควรเรียก Tool ไหนได้บ้าง และถ้า Key รั่วออกไป ก็ต้องเปลี่ยน Key ทั้งระบบพร้อมกันหมด กระทบผู้ใช้ทุกคนแม้จะมีแค่คนเดียวที่ทำ Key หลุด MCP จึงวางแนวทางให้ Remote Server ใช้ OAuth เป็นกลไกมาตรฐาน เพราะแก้ปัญหาทั้งสามข้อนี้ได้ในคราวเดียว

บทความนี้พาไล่ดูว่า MCP OAuth ทำงานอย่างไรในทางปฏิบัติ ตั้งแต่ขั้นตอนขอสิทธิ์ครั้งแรก การออกแบบ Scope ที่เหมาะสม ไปจนถึงจุดที่ทีมส่วนใหญ่ตั้งค่าผิดตอนเริ่มใช้งานจริง

ทำไม Remote MCP Server ต้องพึ่ง OAuth มากกว่าการฝัง API Key ตายตัว

API Key แบบดั้งเดิมถูกออกแบบมาให้เป็นความลับที่ใครถือก็เรียกได้ทุกอย่างเท่ากันหมด ไม่มีมิติเรื่องตัวตนหรือขอบเขตสิทธิ์แนบมาด้วย เมื่อนำมาใช้กับ Remote MCP Server ที่อาจมี Agent จากหลายทีมหลายวัตถุประสงค์เรียกเข้ามาพร้อมกัน ข้อจำกัดนี้กลายเป็นความเสี่ยงทันที เพราะ Server ไม่มีทางแยกได้เลยว่า Request ที่เข้ามาแต่ละครั้งเป็นของใคร ควรได้รับอนุญาตแค่ไหน

OAuth แก้ปัญหานี้ด้วยการแยกขั้นตอน 'ขอสิทธิ์' ออกจากขั้นตอน 'ใช้สิทธิ์' อย่างชัดเจน ผู้ใช้หรือระบบที่เป็นเจ้าของข้อมูลเป็นคนอนุญาตให้ Agent เข้าถึงได้เฉพาะขอบเขตที่กำหนด แล้ว Agent ถือ Token ที่ผูกกับสิทธิ์นั้นไปใช้เรียก Tool แทนการถือรหัสลับตัวเดียวที่ทำอะไรก็ได้ไม่จำกัด

ขั้นตอน OAuth ที่เกิดขึ้นจริงตอน Agent เชื่อมต่อ MCP Server ครั้งแรก

เมื่อ Client พยายามเชื่อมต่อ Remote MCP Server ที่ตั้งค่า OAuth ไว้ Server จะไม่ตอบรับ Request ทันทีเหมือน Local Server แต่จะส่งกลับมาว่าต้องผ่านขั้นตอนขอสิทธิ์ก่อน ลำดับที่เกิดขึ้นจริงมีดังนี้:

  1. Client พยายามเรียก MCP Server แล้วได้รับแจ้งกลับว่าต้องยืนยันตัวตนก่อน พร้อมที่อยู่สำหรับขอสิทธิ์
  2. ผู้ใช้ถูกพาไปหน้าจอ Authorize ของระบบที่ดูแลสิทธิ์ เพื่อยืนยันว่ายินยอมให้ Agent เข้าถึงในขอบเขตที่ระบุไว้
  3. หลังยืนยัน ระบบออก Authorization Code กลับมาให้ Client แลกเป็น Access Token ในขั้นถัดไป
  4. Client แนบ Access Token นี้ไปกับทุก Request ที่เรียก Tool บน MCP Server นับจากนั้น จนกว่า Token จะหมดอายุ

ออกแบบ Scope ของ Token อย่างไรไม่ให้ Agent ทำได้เกินความจำเป็น

จุดที่ตัดสินความปลอดภัยของระบบทั้งหมดจริง ๆ ไม่ใช่ตัวโปรโตคอล OAuth เอง แต่คือการออกแบบ Scope ว่าจะแบ่งสิทธิ์เป็นก้อนไหนบ้าง ทีมที่ทำง่ายเกินไปมักออก Scope เดียวที่ครอบคลุมทุก Tool ใน Server ซึ่งพอ Token หลุดหรือถูกใช้ผิดจุดประสงค์ ความเสียหายจะกว้างเท่ากับสิทธิ์ทั้งหมดของ Server ตัวนั้นทันที

แนวทางออกแบบ Scopeลักษณะความเสี่ยงเมื่อ Token หลุด
Scope เดียวครอบทั้ง ServerToken ใบเดียวเรียก Tool ได้ทุกตัวสูง เพราะเสียหายเท่ากับสิทธิ์เต็มของ Server
แบ่ง Scope ตามระดับอ่าน/เขียนแยก read กับ write ออกจากกันชัดเจนปานกลาง จำกัดได้ว่าอย่างน้อยข้อมูลไม่ถูกแก้
แบ่ง Scope ตามกลุ่ม Tool ย่อยเช่น scope เฉพาะ Tool เกี่ยวกับตั๋วงาน แยกจากกลุ่มบัญชีต่ำ เสียหายจำกัดเฉพาะกลุ่ม Tool ที่ Token นั้นเข้าถึงได้

Token อายุสั้นกับอายุยาว แลกกับความเสี่ยงและความสะดวกต่างกันตรงไหน

Access Token ที่มีอายุสั้นมาก เช่นหลักนาทีถึงหลักชั่วโมง ช่วยลดความเสียหายเมื่อ Token หลุดออกไป เพราะต่อให้มีคนได้ Token ไปจริง ก็ใช้ได้ในกรอบเวลาสั้น ๆ ก่อนหมดอายุ แต่ข้อเสียคือ Client ต้องขอ Token ใหม่บ่อยขึ้น ถ้าออกแบบ Flow ไม่ดี ผู้ใช้อาจต้อง Authorize ซ้ำบ่อยจนรำคาญ

แนวทางที่ใช้กันทั่วไปคือคู่ Access Token อายุสั้นกับ Refresh Token อายุยาวกว่า โดย Refresh Token ใช้แลก Access Token ใหม่โดยอัตโนมัติเบื้องหลังโดยผู้ใช้ไม่ต้อง Authorize ซ้ำทุกครั้ง แต่ Refresh Token เองก็ต้องเก็บอย่างระมัดระวังเป็นพิเศษ เพราะถ้าหลุดออกไป ผู้ถือสามารถขอ Access Token ใหม่ต่อเนื่องได้เรื่อย ๆ จนกว่าจะถูกเพิกถอน

ตัวอย่างสมมติ: บริษัทต้องการให้ AI ผู้ช่วยในเครื่องมือพัฒนาเชื่อมต่อ MCP Server ที่ครอบระบบ HR ไว้ เพื่อให้พนักงานถามข้อมูลวันลาคงเหลือของตัวเองได้ คำถามคือใครควรเป็นคนกด Authorize ให้ Agent เข้าถึงระบบนี้ ถ้าให้ผู้ดูแลระบบคนเดียว Authorize แทนทุกคน Agent จะเห็นข้อมูลของพนักงานทุกคนในสิทธิ์เดียว ซึ่งกว้างเกินความจำเป็นสำหรับ Use Case ที่แค่ต้องการให้แต่ละคนเห็นข้อมูลของตัวเอง

แนวทางที่ปลอดภัยกว่าคือให้พนักงานแต่ละคน Authorize ด้วยตัวเองผ่านบัญชีของตัวเอง เพื่อให้ Token ที่ออกมาผูกกับตัวตนของพนักงานคนนั้นโดยตรง Server จึงกรองข้อมูลตามเจ้าของ Token ได้ทันทีโดยไม่ต้องเขียน Logic ตรวจสอบสิทธิ์เพิ่มเติมในชั้น Business Logic เอง วิธีนี้เหมาะกับ Use Case ที่ข้อมูลผูกกับตัวบุคคลชัดเจน ต่างจากกรณีที่ Agent ทำงานเป็น Service กลางที่ต้อง Authorize ในนามระบบแทน

สำหรับกรณีที่ Agent ไม่ได้ทำงานแทนพนักงานคนใดคนหนึ่งโดยตรง แต่เป็น Service กลางที่ทำงานอัตโนมัติ เช่น สรุปรายงานทุกเช้าจากหลายระบบ ทีมมักใช้รูปแบบ Service Account ที่ Authorize แยกต่างหากจากบัญชีบุคคล โดยจำกัด Scope ของ Service Account ให้แคบที่สุดเท่าที่งานอัตโนมัตินั้นต้องใช้จริง และไม่ควรให้ Service Account ตัวเดียวมีสิทธิ์เท่ากับผู้ดูแลระบบสูงสุด แม้จะสะดวกกว่าตอนตั้งค่าก็ตาม

เพิกถอนสิทธิ์ Agent ได้ทันทีเมื่อไร และทำไมต้องหมุน Credential เป็นระยะ

ข้อดีอีกอย่างของ OAuth เทียบกับ API Key ตัวเดียวคือเพิกถอน Token ของ Client ตัวใดตัวหนึ่งได้โดยไม่กระทบ Client ตัวอื่น เมื่อพบว่ามี Agent ตัวใดพฤติกรรมผิดปกติ เช่น เรียก Tool ถี่ผิดเวลาหรือพยายามเข้าถึง Tool นอก Scope ที่ควรได้ ทีมสามารถเพิกถอน Token เฉพาะตัวนั้นได้ทันทีโดยผู้ใช้คนอื่นยังใช้งานต่อได้ปกติ

นอกจากเพิกถอนตอนพบปัญหาแล้ว ทีมควรมีนโยบายหมุน Credential ที่ใช้ในขั้นตอนแลก Token เป็นระยะด้วย ไม่ใช่รอจนเกิดเหตุการณ์ผิดปกติก่อนถึงจะเปลี่ยน เพราะ Credential ที่ใช้นานเกินไปมีโอกาสรั่วสะสมสูงขึ้นตามเวลา โดยเฉพาะถ้ามีคนในทีมเปลี่ยนหมุนเวียนหรือมีการเชื่อมต่อระบบภายนอกเพิ่มขึ้นเรื่อย ๆ

เชื่อมหลาย MCP Server พร้อมกัน ต้องจัดการ Token แยกกันอย่างไร

เมื่อ MCP Client เชื่อมกับ Remote Server มากกว่าหนึ่งตัวพร้อมกัน แต่ละ Server อาจมีระบบออก Token เป็นของตัวเอง ไม่ได้ใช้ผู้ให้บริการ Authorization เดียวกันเสมอไป ทีมพัฒนาจึงต้องออกแบบ Client ให้เก็บ Token แยกต่อ Server อย่างชัดเจน ไม่ใช่ผสมกันจนสับสนว่า Token ใบไหนใช้กับ Server ตัวไหน

ความเสี่ยงที่พบได้จริงคือถ้า Client เขียนโค้ดจัดการ Token แบบเดียวใช้ร่วมกันทุก Server เพราะคิดว่าจะช่วยลดความซับซ้อน อาจเกิดกรณีที่ Token ของ Server หนึ่งถูกส่งไปแนบกับ Request ของอีก Server โดยไม่ตั้งใจ ซึ่งอย่างน้อยที่สุดทำให้ Request ล้มเหลว แต่ในกรณีเลวร้ายกว่านั้นอาจทำให้ Server ปลายทางประมวลผลสิทธิ์ผิดชุดไปเลย

จุดพลาดที่ทีมมักเจอตอนตั้งค่า MCP OAuth ครั้งแรก

ทีมที่ตั้งค่า OAuth ให้ MCP Server เป็นครั้งแรกมักเจอปัญหาซ้ำกันไม่กี่แบบ เพราะเป็นเรื่องที่ต้องคิดหลายชั้นพร้อมกันทั้ง Flow การขอสิทธิ์ การออกแบบ Scope และการจัดเก็บ Token ให้ปลอดภัย

  • ให้ Scope เดียวครอบทุก Tool ตั้งแต่แรกเพราะอยากให้ตั้งค่าเสร็จเร็ว ทำแบบนี้แล้วพัง เพราะพอ Token หลุดหรือถูกใช้ผิดจุดประสงค์ ความเสียหายจะกว้างเท่ากับสิทธิ์เต็มของ Server ทั้งที่ Agent อาจต้องการแค่ Tool สองสามตัว
  • เก็บ Refresh Token ไว้แบบข้อความธรรมดาในไฟล์ Config ทำแบบนี้แล้วพัง เพราะ Refresh Token มีอายุยาวและใช้ขอ Access Token ใหม่ได้ต่อเนื่อง ถ้าไฟล์ Config หลุดออกไป ผู้ไม่หวังดีจะเข้าถึงได้ยาวนานกว่าที่คิด
  • ไม่มีทางเพิกถอน Token เฉพาะตัวเมื่อพบพฤติกรรมผิดปกติ ทำแบบนี้แล้วพัง เพราะเมื่อเจอปัญหาจริง ทีมจะต้องเปลี่ยน Credential ทั้งระบบ กระทบผู้ใช้ทุกคนแทนที่จะตัดสิทธิ์เฉพาะจุดที่มีปัญหา
  • ให้ผู้ดูแลระบบคนเดียว Authorize แทนผู้ใช้ทุกคนเพื่อความรวดเร็ว ทำแบบนี้แล้วพัง เพราะ Token ที่ได้จะกว้างเกินความจำเป็นของแต่ละคน และตรวจสอบย้อนหลังไม่ได้ว่าใครเป็นคนสั่งงานจริง

สรุป

MCP OAuth ไม่ใช่แค่การเปลี่ยนจาก API Key เป็น Token แต่คือการเปลี่ยนวิธีคิดทั้งระบบให้แยกได้ว่าใครเรียก Tool ได้บ้าง เรียกได้แค่ไหน และเพิกถอนสิทธิ์ได้ทันทีเมื่อจำเป็น ทีมที่ตั้งค่า Scope กว้างเกินไปตั้งแต่แรกมักต้องกลับมาแก้ทีหลังตอนที่ระบบมีผู้ใช้จริงแล้ว ซึ่งยากกว่าออกแบบให้ถูกตั้งแต่ต้น

ก่อนเปิด Remote MCP Server ให้ใครใช้งานจริง ควรตอบให้ได้ก่อนว่า Scope จะแบ่งเป็นกี่ระดับ ใครเป็นคนกด Authorize และมีขั้นตอนเพิกถอน Token เฉพาะตัวพร้อมใช้งานหรือยัง สามข้อนี้สำคัญกว่ารายละเอียดการ Implement OAuth ในทางเทคนิคด้วยซ้ำ

  • OAuth แยกขั้นตอนขอสิทธิ์ออกจากการใช้สิทธิ์ ทำให้กำหนด Scope อายุ Token และเพิกถอนสิทธิ์เฉพาะตัวได้
  • ควรแบ่ง Scope อย่างน้อยตามระดับอ่าน/เขียน ไม่ใช่ให้ Token เดียวเข้าถึงทุก Tool ใน Server
  • คู่ Access Token อายุสั้นกับ Refresh Token อายุยาวช่วยลดความเสียหายเมื่อ Token หลุดโดยไม่กระทบประสบการณ์ใช้งาน
  • เชื่อมหลาย Server ต้องเก็บ Token แยกกันชัดเจน ไม่ผสมกันจนส่ง Token ผิด Server โดยไม่ตั้งใจ

คำถามที่พบบ่อย

MCP OAuth ต่างจาก API Key แบบเดิมอย่างไรในทางปฏิบัติ

API Key แบบเดิมเป็นความลับตัวเดียวที่ใครถือก็ทำได้ทุกอย่างเท่ากัน ส่วน OAuth แยกขั้นตอนขอสิทธิ์ออกจากการใช้สิทธิ์ ทำให้กำหนด Scope เฉพาะเจาะจง จำกัดอายุ Token และเพิกถอนสิทธิ์เฉพาะตัวได้โดยไม่กระทบผู้ใช้คนอื่น

Local MCP Server จำเป็นต้องมี OAuth ด้วยหรือไม่

โดยทั่วไปไม่จำเป็นถ้า Server รันในเครื่องส่วนตัวและไม่มีใครเข้าถึงจากนอกเครื่อง แต่ทันทีที่ย้ายไปเป็น Remote Server ที่เข้าถึงได้จากเครือข่าย ควรมีระบบยืนยันตัวตนแบบ OAuth เสมอ

ถ้า Access Token หมดอายุระหว่างที่ Agent กำลังทำงานอยู่จะเกิดอะไรขึ้น

Client ที่ออกแบบมาอย่างถูกต้องจะตรวจพบว่า Token หมดอายุจาก Response ที่ Server ส่งกลับ แล้วใช้ Refresh Token แลก Access Token ใหม่โดยอัตโนมัติก่อนเรียก Tool ต่อ โดยผู้ใช้ไม่จำเป็นต้อง Authorize ซ้ำถ้า Refresh Token ยังไม่หมดอายุ

Scope ควรแบ่งละเอียดแค่ไหนถึงจะพอดี ไม่ใช่ละเอียดจนดูแลไม่ไหว

ไม่มีสูตรตายตัว แต่แนวทางที่ใช้ได้จริงคือแบ่งตามกลุ่ม Tool ที่มีระดับความเสี่ยงต่างกัน เช่น กลุ่มที่แค่อ่านข้อมูล กับกลุ่มที่เขียนหรือแก้ไขข้อมูล แยก Scope อย่างน้อยสองระดับนี้ก่อน แล้วค่อยแบ่งละเอียดขึ้นเมื่อเห็นความจำเป็นจริงจากการใช้งาน

จำเป็นต้องเขียนระบบ OAuth เองทั้งหมดไหมสำหรับ MCP Server

ไม่จำเป็นเสมอไป มี Library และผู้ให้บริการ Authorization มาตรฐานที่รองรับ OAuth อยู่แล้วหลายเจ้า ทีมส่วนใหญ่เลือกใช้ระบบที่มีอยู่แล้วมาต่อยอด แทนที่จะเขียนกลไกออก Token และตรวจสอบ Token เองทั้งหมดตั้งแต่ศูนย์

OAuth ช่วยป้องกัน Prompt Injection ที่มาจากผลลัพธ์ของ Tool ได้ไหม

ไม่ได้ป้องกันโดยตรง เพราะ OAuth ควบคุมว่าใครเรียก Tool ได้และเรียกอะไรได้บ้าง แต่ไม่ได้ตรวจเนื้อหาที่ Tool ส่งกลับมาให้โมเดล เรื่องนี้เป็นความเสี่ยงคนละชั้นที่ต้องป้องกันแยกต่างหาก

ทดลองวัดผลโฆษณาเข้า LINE ฟรี 14 วัน

สมัครแล้วสร้างโปรเจกต์ เชื่อม LINE ติดตั้ง Tracking แล้วเริ่มเห็น Funnel จาก Click ถึง Purchase ได้ทันที ไม่ต้องใช้บัตรเครดิต

เริ่มทดลองใช้ฟรี 14 วัน

บทความที่เกี่ยวข้อง

ต้องเขียน MCP Server เองทุกครั้งไหม หรือใช้ตัวสำเร็จรูปได้เลย

ต้องเขียน MCP Server เองทุกครั้งไหม หรือใช้ตัวสำเร็จรูปได้เลย

หลายทีมเข้าใจว่า MCP คือแนวคิดกว้าง ๆ แต่พอถึงขั้นลงมือทำจริงกลับงงว่า MCP Server ต้องเขียนเองแค่ไหน และควรวางโครงสร้างยังไงให้ดูแลง่ายในระยะยาว
ทำไม MCP Prompt Injection ถึงเกิดขึ้นได้ทั้งที่ Tool ผ่านการตรวจสอบสิทธิ์มาแล้ว

ทำไม MCP Prompt Injection ถึงเกิดขึ้นได้ทั้งที่ Tool ผ่านการตรวจสอบสิทธิ์มาแล้ว

ทีมที่ตั้ง OAuth และจำกัดสิทธิ์ Tool เรียบร้อยแล้วมักคิดว่าปลอดภัยแล้ว แต่ Prompt Injection โจมตีผ่านช่องทางที่ต่างออกไปคือเนื้อหาที่ Tool ส่งกลับมาให้โมเดลอ่าน ไม่ใช่ตัวสิทธิ์การเรียก
เปิด Tool ให้ Agent อ่านอย่างเดียว กับเปิดให้เขียนด้วย เสี่ยงต่างกันแค่ไหน

เปิด Tool ให้ Agent อ่านอย่างเดียว กับเปิดให้เขียนด้วย เสี่ยงต่างกันแค่ไหน

หลายทีมมองว่าตั้ง Authentication ให้ MCP Server เรียบร้อยแล้วเท่ากับปลอดภัยแล้ว แต่ความเสี่ยงของ MCP มีหลายชั้นกว่านั้น ตั้งแต่ขอบเขต Tool ไปจนถึงข้อมูลที่รั่วผ่าน Resource โดยไม่มีใครสังเกตเห็น