← กลับไปหน้าบทความ
เอเจนซี่

โทเคนของลูกค้ารายหนึ่งหมดอายุกลางดึก แล้ว Event ของลูกค้าทุกคนในระบบเดียวกันหยุดส่งพร้อมกันหมด วาง Credential Rotation ให้พังแยกราย ไม่ใช่พังยกล็อต

ทีมบรรณาธิการ linli07 ก.ย. 07:43อัปเดต 07 ก.ย. 07:43อ่าน 2 นาที
โทเคนของลูกค้ารายหนึ่งหมดอายุกลางดึก แล้ว Event ของลูกค้าทุกคนในระบบเดียวกันหยุดส่งพร้อมกันหมด วาง Credential Rotation ให้พังแยกราย ไม่ใช่พังยกล็อต
บทความนี้จัดทำเพื่อความรู้ ชื่อธุรกิจ ตัวเลข หรือบทสนทนาที่ไม่มีแหล่งอ้างอิงกำกับเป็นกรณีตัวอย่างเพื่ออธิบายแนวคิด ดูรายละเอียดที่ นโยบายกองบรรณาธิการ

สรุปสั้น ๆ

เมื่อระบบโหลด credential ของลูกค้าทุกรายพร้อมกันตอน startup โดยไม่มีการแยกจัดการความล้มเหลว credential ของลูกค้ารายหนึ่งที่หมดอายุหรือผิดพลาดอาจทำให้ทั้งระบบล่มไปด้วย การออกแบบ credential lifecycle ที่แยกจัดการต่อรายลูกค้า พร้อมระบบแจ้งเตือนก่อนหมดอายุ คือทางป้องกันที่ทำให้ปัญหาของลูกค้ารายหนึ่งไม่ลามไปกระทบรายอื่น

เอเจนซี่แห่งหนึ่งที่ผมช่วยตรวจระบบให้ เจอเหตุการณ์ที่ระบบส่ง CAPI ของลูกค้าทุกรายหยุดทำงานพร้อมกันตอนตีสามของคืนวันหนึ่ง ทีมงานตกใจมากเพราะคิดว่าเซิร์ฟเวอร์ทั้งชุดล่ม แต่พอไล่ log จริง ๆ พบว่าสาเหตุมาจาก access token ของลูกค้ารายเดียวที่หมดอายุ แล้วโค้ดที่โหลด credential ของลูกค้าทุกรายพร้อมกันตอนเริ่มระบบ (startup) เขียนไว้แบบที่ถ้าโหลด credential ตัวใดตัวหนึ่งล้มเหลว ทั้งกระบวนการ startup จะหยุดทำงานทันที

ผลคือลูกค้าอีกแปดรายที่ credential ยังใช้งานได้ปกติทุกประการ ก็ไม่สามารถส่ง event ได้เลยตลอดทั้งคืนจนกว่าทีมจะตื่นมาแก้ไข เพราะระบบไม่เคยเริ่มทำงานได้เลยตั้งแต่ตอน startup ล้มเหลว นี่คือความเสี่ยงที่ซ่อนอยู่ในสถาปัตยกรรมที่ดูเผิน ๆ เหมือนไม่มีปัญหาอะไร แต่จริง ๆ แล้วมีจุดล้มเหลวร่วม (single point of failure) ที่ credential ของใครก็ตามเพียงรายเดียวสามารถดึงทั้งระบบลงได้

บทความนี้จะเจาะแนวทางออกแบบ credential lifecycle สำหรับเอเจนซี่ที่ดูแลหลายลูกค้า ให้ความล้มเหลวของ credential รายหนึ่งไม่ลามไปกระทบรายอื่น พร้อมกลไกแจ้งเตือนก่อนที่ token จะหมดอายุจริง

จุดล้มเหลวร่วมที่ซ่อนอยู่ในโค้ดโหลด credential พร้อมกันตอน startup

รูปแบบที่พบบ่อยในระบบที่ดูแลหลายลูกค้าคือ การเขียนโค้ดที่โหลด credential ของทุกรายเข้าหน่วยความจำพร้อมกันตอนเริ่มระบบ ซึ่งดูเหมือนมีประสิทธิภาพเพราะไม่ต้องดึงข้อมูลซ้ำทุกครั้งที่ใช้งาน แต่ถ้าไม่มีการจัดการ error แยกเป็นรายลูกค้า ความล้มเหลวของ credential เพียงตัวเดียวจะทำให้กระบวนการ startup ทั้งหมดล้มเหลวไปด้วย เพราะโค้ดส่วนใหญ่เขียนแบบให้หยุดทำงานทันทีเมื่อเจอ error ระหว่าง initialization

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

ออกแบบให้การโหลด credential แต่ละรายเป็นอิสระจากกัน

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

ในทางปฏิบัติ หมายความว่าเมื่อระบบเริ่มทำงาน มันควรพยายามโหลด credential ของลูกค้าแต่ละรายแยกกัน แล้วบันทึกว่ารายไหนโหลดสำเร็จ รายไหนล้มเหลว จากนั้นระบบเริ่มทำงานได้ปกติสำหรับลูกค้าที่โหลดสำเร็จ ส่วนลูกค้าที่โหลดล้มเหลวจะถูกทำเครื่องหมายว่าต้องการการแก้ไข พร้อมส่งแจ้งเตือนให้ทีมทราบ โดยไม่กระทบการทำงานของลูกค้ารายอื่นเลย

รู้ล่วงหน้าก่อน token หมดอายุ ดีกว่ารู้ตอนที่มันหมดไปแล้ว

แนวทางวิธีทำงานประโยชน์
ตรวจสอบวันหมดอายุเป็นรอบรัน job ตรวจสอบวันหมดอายุของ token ทุกวัน เทียบกับวันปัจจุบันรู้ล่วงหน้าก่อนหมดอายุจริงหลายวัน มีเวลาเตรียมต่ออายุ
แจ้งเตือนแบบขั้นบันไดแจ้งเตือนที่ 14 วัน 7 วัน และ 1 วันก่อนหมดอายุ ความถี่เพิ่มขึ้นเมื่อใกล้วันจริงลดโอกาสที่การแจ้งเตือนครั้งเดียวจะถูกมองข้ามหรือลืมดำเนินการ
ทดสอบ token ก่อนใช้งานจริงทุกครั้งเรียก API แบบเบา ๆ เพื่อตรวจสอบว่า token ยังใช้งานได้ก่อนเริ่มยิง event จริงจับปัญหา token ที่ถูกเพิกถอนก่อนกำหนดได้ ไม่ใช่แค่ตรวจวันหมดอายุตามทฤษฎี

เก็บ credential ของลูกค้าแต่ละรายอย่างไรให้ปลอดภัยและดูแลง่าย

เอเจนซี่ที่ดูแลลูกค้าหลายรายควรหลีกเลี่ยงการเก็บ credential ทุกรายไว้ในไฟล์ config เดียวกันที่ไม่มีการเข้ารหัสหรือจำกัดสิทธิ์การเข้าถึง เพราะนอกจากความเสี่ยงเรื่อง single point of failure แล้วยังมีความเสี่ยงด้านความปลอดภัยเพิ่มเข้ามาด้วย ถ้าไฟล์นั้นรั่วไหล credential ของลูกค้าทุกรายจะหลุดไปพร้อมกันทั้งหมด

แนวทางที่ดีกว่าคือใช้ secret manager ที่แยกจัดเก็บ credential ต่อรายลูกค้าเป็นหน่วยอิสระ พร้อมจำกัดสิทธิ์การเข้าถึงตามความจำเป็น (least privilege) และมี audit log ที่บันทึกว่าใครเข้าถึง credential ของลูกค้ารายไหนเมื่อใด เพื่อให้ตรวจสอบย้อนหลังได้หากเกิดเหตุการณ์ผิดปกติ

เมื่อพนักงานที่ดูแลลูกค้ารายนั้นลาออก ใครรับผิดชอบต่ออายุ credential

ปัญหาที่พบได้จริงในเอเจนซี่คือ credential ของลูกค้าบางรายผูกอยู่กับบัญชีส่วนตัวของพนักงานที่เคยดูแลลูกค้ารายนั้น เมื่อพนักงานคนนั้นลาออกโดยไม่มีการส่งมอบที่ชัดเจน token อาจถูกเพิกถอนไปพร้อมกับบัญชีของพนักงาน หรือไม่มีใครรู้ว่าต้องต่ออายุยังไงเมื่อถึงเวลา

การป้องกันปัญหานี้ต้องมีกระบวนการ handoff ที่ชัดเจนเมื่อมีการเปลี่ยนแปลงผู้รับผิดชอบลูกค้ารายใดรายหนึ่ง โดยควรใช้บัญชีระดับองค์กรหรือ service account สำหรับการเชื่อมต่อ credential แทนบัญชีส่วนตัวของพนักงานตั้งแต่ต้น เพื่อไม่ให้ความต่อเนื่องของระบบขึ้นอยู่กับการที่พนักงานคนใดคนหนึ่งยังทำงานอยู่หรือไม่

เตรียม runbook ไว้ล่วงหน้า สำหรับตอนที่ credential ของลูกค้ารายใดรายหนึ่งมีปัญหาจริง

แม้จะออกแบบระบบให้แยก isolation ดีแค่ไหน วันหนึ่งก็ยังมีโอกาสที่ credential ของลูกค้ารายใดรายหนึ่งจะมีปัญหาจริง เช่น ลูกค้าเปลี่ยนรหัสผ่านบัญชีโฆษณาโดยไม่แจ้งเอเจนซี่ล่วงหน้า หรือแพลตฟอร์มเพิกถอน token โดยไม่มีการแจ้งเตือนที่ชัดเจนพอ สิ่งที่ทำให้ทีมตอบสนองได้เร็วในสถานการณ์แบบนี้ไม่ใช่แค่การมีระบบแจ้งเตือนอัตโนมัติ แต่คือการมี runbook ที่เขียนขั้นตอนแก้ไขไว้ล่วงหน้าอย่างชัดเจน

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

ควรซ้อมทำตาม runbook นี้อย่างน้อยหนึ่งครั้งกับสถานการณ์จำลอง ไม่ใช่เขียนทิ้งไว้เฉย ๆ โดยไม่เคยทดลองใช้จริง เพราะขั้นตอนที่ดูสมบูรณ์บนกระดาษอาจมีจุดที่ทำได้ยากในทางปฏิบัติ เช่น ติดต่อลูกค้าไม่ได้ทันทีตามที่คาดไว้ การซ้อมล่วงหน้าช่วยให้ทีมพบจุดที่ต้องปรับปรุงก่อนที่จะต้องใช้ runbook นี้จริงในสถานการณ์ฉุกเฉิน

ใครเข้าถึง credential ของลูกค้ารายไหนได้บ้าง ต้องตรวจสอบได้เสมอ

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

การมี audit log ที่บันทึกการเข้าถึง secret manager แยกตามผู้ใช้และเวลา ควบคู่กับการจำกัดสิทธิ์การเข้าถึงตามความจำเป็นของงาน (least privilege) เป็นมาตรฐานพื้นฐานที่เอเจนซี่ที่ดูแลข้อมูลลูกค้าหลายรายควรมี ไม่ใช่แค่เพื่อป้องกันปัญหาความปลอดภัย แต่ยังเพื่อสร้างความมั่นใจให้ลูกค้าว่าข้อมูลของพวกเขาถูกดูแลอย่างรอบคอบและตรวจสอบได้จริง

สรุป

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

การแจ้งเตือนล่วงหน้าก่อน token หมดอายุอาจดูเป็นรายละเอียดเล็กน้อย แต่คือสิ่งที่แยกเอเจนซี่ที่ทำงานเชิงรุกออกจากเอเจนซี่ที่คอยแก้ปัญหาเฉพาะหน้าตลอดเวลา ลูกค้าที่เห็นว่าปัญหาถูกป้องกันไว้ล่วงหน้าจะมีความเชื่อมั่นมากกว่าลูกค้าที่ต้องคอยแจ้งปัญหาเข้ามาเอง

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

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

ถ้า token ของลูกค้ารายหนึ่งหมดอายุกลางดึกแบบไม่มีใครรู้ตัว จะเกิดอะไรขึ้นถ้าออกแบบ isolation ถูกต้อง

ถ้าออกแบบถูกต้อง event ของลูกค้ารายนั้นจะถูกกันไว้รอ retry หรือถูกบันทึกเป็นสถานะล้มเหลวที่รอการแก้ไข ในขณะที่ลูกค้ารายอื่นทั้งหมดยังคงทำงานได้ตามปกติ ไม่มีผลกระทบข้ามกันเลย ทีมจะได้รับแจ้งเตือนเฉพาะลูกค้ารายที่มีปัญหาเมื่อระบบตรวจพบ

ควรต่ออายุ credential ล่วงหน้ากี่วันก่อนหมดอายุ

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

credential ของลูกค้าที่ยกเลิกสัญญากับเอเจนซี่ไปแล้ว ต้องจัดการยังไง

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

การแยก isolation ของ credential เกี่ยวข้องกับการแยก queue ต่อ tenant ที่เคยพูดถึงไหม

เกี่ยวข้องกันในหลักการเดียวกันคือ treat แต่ละลูกค้าเป็นหน่วยอิสระที่ไม่ควรกระทบกัน แต่เป็นคนละชั้นของระบบ การแยก<a href="/blog/capi-agency-multi-tenant-isolation-line">queue ต่อ tenant</a>แก้ปัญหาเรื่องการแย่งทรัพยากรประมวลผล ส่วนการแยก credential lifecycle แก้ปัญหาเรื่องความล้มเหลวของการเชื่อมต่อ ทั้งสองเรื่องควรออกแบบคู่กันในระบบที่ดูแลหลายลูกค้า

เอเจนซี่ขนาดเล็กที่ดูแลลูกค้าแค่สองสามราย จำเป็นต้องมีระบบซับซ้อนขนาดนี้ไหม

หลักการพื้นฐานยังมีประโยชน์แม้จะมีลูกค้าไม่กี่ราย เพราะความเสี่ยงที่ credential รายหนึ่งกระทบรายอื่นเกิดขึ้นได้ไม่ว่าจำนวนลูกค้าจะมากหรือน้อย แต่ implementation สามารถเริ่มจากง่าย ๆ เช่น การ try-catch แยกต่อรายลูกค้าตอน startup ก่อน แล้วค่อยพัฒนาระบบแจ้งเตือนเพิ่มเติมเมื่อจำเป็น

ถ้าเอเจนซี่ใช้ระบบสำเร็จรูปที่มีการจัดการ credential ให้อยู่แล้ว ยังต้องกังวลเรื่องนี้ไหม

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

พิสูจน์ผลงานแอดเข้า LINE ให้ลูกค้าเห็นถึงยอดขาย

ดูแลลูกค้าหลายราย แต่ละรายมี LINE OA ของตัวเอง — linli แยกโปรเจกต์ แยก Tracking และส่ง Conversion กลับแพลตฟอร์มของแต่ละลูกค้า เริ่มฟรี 14 วัน

ทดลองใช้ฟรี 14 วัน

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

เอเจนซี่ดูแลลูกค้า 8 เจ้า แต่ละเจ้าอยากได้โมเดล attribution คนละแบบ จะวางมาตรฐานให้เทียบผลงานกันได้ยังไง

เอเจนซี่ดูแลลูกค้า 8 เจ้า แต่ละเจ้าอยากได้โมเดล attribution คนละแบบ จะวางมาตรฐานให้เทียบผลงานกันได้ยังไง

ลูกค้าคลินิกอยากดู Last-Click ลูกค้าอสังหาฯ อยากดู Time-Decay ลูกค้าอีคอมเมิร์ซอยากดู Linear เอเจนซี่ที่ดูแลหลายบัญชีพร้อมกันจะวางมาตรฐานการรายงานยังไงให้ทั้งตอบโจทย์ลูกค้าแต่ละเจ้าและเปรียบเทียบผลงานทีมได้เอง
เอเจนซี่ที่ดูแลหลายแบรนด์พร้อมกัน จะจัดการข้อมูลลูกค้าแต่ละเจ้าใน LINE ให้แยกกันชัดเจนได้อย่างไร

เอเจนซี่ที่ดูแลหลายแบรนด์พร้อมกัน จะจัดการข้อมูลลูกค้าแต่ละเจ้าใน LINE ให้แยกกันชัดเจนได้อย่างไร

เอเจนซี่ที่รับดูแลลูกค้าหลายแบรนด์มักเจอปัญหาข้อมูลลูกค้าปนกันหรือไม่ชัดเจนว่าใครเป็นเจ้าของข้อมูลจริง บทความนี้ชวนดูวิธีวางโครงสร้างข้อมูลให้แยกกันสะอาดตั้งแต่ต้น เพื่อป้องกันปัญหาทั้งด้านความไว้วางใจและด้านกฎหมาย
แดชบอร์ดเอเจนซี่รายงานคอนเวอร์ชั่น 180 ราย แต่สเปรดชีตลูกค้าเห็น 95 ราย ต้องเชื่อฝั่งไหน

แดชบอร์ดเอเจนซี่รายงานคอนเวอร์ชั่น 180 ราย แต่สเปรดชีตลูกค้าเห็น 95 ราย ต้องเชื่อฝั่งไหน

เวลาตัวเลขสองฝั่งไม่ตรงกัน ปัญหาไม่ได้อยู่ที่ใครโกหกใคร แต่มักอยู่ที่นิยามคำว่า 'คอนเวอร์ชั่น' ที่แต่ละฝั่งนับไม่เหมือนกัน