Policy as Code: เปลี่ยนกฎสิทธิ์ของระบบและ AI Agent ให้ตรวจสอบได้
Policy as Code เปลี่ยนกฎการอนุญาตจากเงื่อนไขที่กระจัดกระจายให้เป็นโค้ดที่ตรวจสอบ ทดสอบ และย้อนกลับได้ แนวคิดนี้ยิ่งสำคัญในยุค AI Agent ซึ่งสามารถเรียกใช้เครื่องมือและดำเนินการแทนผู้ใช้ได้หลายขั้นตอน

Policy as Code: เปลี่ยนกฎสิทธิ์ของระบบและ AI Agent ให้ตรวจสอบได้
ระบบซอฟต์แวร์แทบทุกระบบมีนโยบายกำกับการทำงานอยู่แล้ว ไม่ว่าจะเป็นกฎว่าใครอนุมัติการคืนเงินได้ ใครเข้าถึงข้อมูลลูกค้าได้ หรือคำขอแบบใดต้องถูกปฏิเสธทันที ปัญหาคือนโยบายเหล่านี้มักกระจายอยู่ในเอกสาร การประชุม โค้ดหลายส่วน และความทรงจำของสมาชิกในทีม
Policy as Code คือแนวทางที่เปลี่ยนนโยบายเหล่านั้นให้เป็นกฎที่เครื่องอ่านและบังคับใช้ได้ เมื่อกฎกลายเป็นส่วนหนึ่งของซอฟต์แวร์ ทีมจึงสามารถตรวจสอบการเปลี่ยนแปลง ทดสอบผลลัพธ์ และย้อนกลับไปใช้เวอร์ชันเดิมได้อย่างเป็นระบบ
Policy as Code คืออะไร
Policy as Code คือการเขียนกฎด้านสิทธิ์ ความปลอดภัย และข้อกำหนดทางธุรกิจให้อยู่ในรูปแบบโค้ดหรือข้อมูลเชิงโครงสร้าง แทนที่จะปล่อยให้กฎสำคัญอยู่เพียงในเอกสารหรืออาศัยความเข้าใจร่วมกันของทีม
ตัวอย่างนโยบายที่สามารถเขียนเป็นโค้ดได้ ได้แก่
- ผู้ดูแลระบบอ่านใบแจ้งหนี้ทั้งหมดได้
- เจ้าของบัญชีอ่านใบแจ้งหนี้ของตนเองได้
- เจ้าหน้าที่ฝ่ายสนับสนุนอ่านใบแจ้งหนี้ได้เมื่อมี ticket ที่เกี่ยวข้องเปิดอยู่
- AI Agent เรียกเครื่องมือโอนเงินได้เฉพาะเมื่อผู้ใช้มีสิทธิ์และผ่านเงื่อนไขการอนุมัติ
- Bot ต้องไม่เห็นข้อมูลบัตรเครดิต ไม่ว่ากำลังทำงานในบริบทใด
เป้าหมายไม่ใช่เพียงการเปลี่ยนข้อความในเอกสารให้เป็นเงื่อนไขอีกชุดหนึ่ง แต่คือการสร้างแหล่งอ้างอิงที่ชัดเจนสำหรับการตัดสินสิทธิ์ ซึ่งทุกฝ่ายสามารถอ่าน ตรวจสอบ และพิสูจน์ผลลัพธ์ได้
Authorization เป็นเรื่องของความถูกต้องของผลิตภัณฑ์
การกำหนดสิทธิ์มักถูกมองว่าเป็นงานด้าน security เท่านั้น แต่ในความเป็นจริง authorization เป็นส่วนหนึ่งของ product correctness ด้วย ระบบจะถือว่าทำงานถูกต้องได้ก็ต่อเมื่ออนุญาตให้บุคคลที่เหมาะสมทำสิ่งที่เหมาะสมกับข้อมูลหรือทรัพยากรที่ถูกต้องภายใต้บริบทที่กำหนด
คำถามจึงไม่ได้จบเพียงว่าผู้ใช้ล็อกอินแล้วหรือยัง แต่ต้องตอบให้ได้ว่า ผู้ใช้คนนี้ทำ action นี้กับ resource นี้ได้จริงหรือไม่ ตัวอย่างเช่น เจ้าหน้าที่ support อาจอ่านอีเมลของลูกค้าได้เมื่อรับผิดชอบ ticket นั้น แต่ไม่มีสิทธิ์อ่าน payment token หรือส่งออกข้อมูลดิบทั้งหมด
หากระบบตรวจสอบเพียงสถานะการล็อกอินหรือ role แบบกว้างเกินไป ความสามารถที่ควรมีเงื่อนไขเพิ่มเติมอาจถูกเปิดให้ใช้งานโดยไม่ตั้งใจ นี่เป็นทั้งช่องโหว่ด้านความปลอดภัยและข้อผิดพลาดของพฤติกรรมผลิตภัณฑ์
เมื่อกฎสิทธิ์กระจัดกระจายไปทั่วระบบ
ในระบบที่เติบโตมาระยะหนึ่ง policy มักกระจายอยู่ในหลายตำแหน่ง บางกฎเป็น if statement ใน backend บางกฎซ่อนอยู่ใน service อีกตัว ขณะที่บางหน้าพึ่งการซ่อนปุ่มใน frontend และยังมีเงื่อนไขอีกส่วนหนึ่งอยู่ใน wiki ที่ไม่มีใครเปิดอ่าน
การซ่อนปุ่มช่วยลดความสับสนของผู้ใช้ แต่ไม่ใช่กลไกบังคับสิทธิ์ เพราะผู้ใช้หรือโปรแกรมอื่นอาจเรียก API โดยตรงได้ เมื่อแต่ละชั้นตัดสินสิทธิ์ด้วยกฎคนละชุด ระบบจึงเสี่ยงต่อผลลัพธ์ที่ไม่สอดคล้องกัน
ผลกระทบที่พบได้บ่อยมีหลายด้าน ได้แก่
- ไม่มีใครอธิบายกฎทั้งหมดของระบบได้อย่างมั่นใจ
- การเปลี่ยนนโยบายหนึ่งข้ออาจต้องแก้โค้ดหลายบริการ
- ทีม QA สร้าง test matrix ได้ยากเพราะไม่รู้ว่ากฎจริงอยู่ที่ใด
- การ refactor อาจทำให้สิทธิ์เปลี่ยนโดยไม่มีสัญญาณเตือน
- Security review ต้องอ่าน business logic จำนวนมากเพื่อค้นหาเงื่อนไขที่เกี่ยวข้อง
Policy as Code ช่วยลดความคลุมเครือนี้ด้วยการทำให้นโยบายเป็น artifact ที่มีวงจรชีวิตเช่นเดียวกับโค้ดส่วนอื่น กฎจึงผ่าน code review เก็บใน version control ทดสอบอัตโนมัติ และ rollback ได้เมื่อพบปัญหา
องค์ประกอบของการตัดสินสิทธิ์
การตัดสินใจที่ดีควรพิจารณาอย่างน้อยสี่องค์ประกอบ ได้แก่ subject ผู้กำลังร้องขอ action สิ่งที่ต้องการทำ resource เป้าหมายของการกระทำ และ context สถานการณ์ประกอบการตัดสินใจ
ตัวอย่างคำขอประเมิน policy สำหรับ Agent ที่กำลังทำงานแทนผู้ใช้อาจมีโครงสร้างดังนี้
subject:
type: agent
acting_for: user_123
action: read_customer_note
resource:
type: customer
id: customer_789
context:
workspace: workspace_a
role: support
ticket_status: open
data_classification: confidential
Policy engine นำข้อมูลเหล่านี้ไปประเมินแล้วตอบ allow หรือ deny พร้อมเหตุผลที่เกี่ยวข้อง ตัวอย่างเช่น คำขออาจได้รับอนุญาตเพราะผู้ใช้เป็นเจ้าหน้าที่ใน workspace เดียวกันและมี ticket เปิดอยู่ หรือถูกปฏิเสธเพราะข้อมูลมีระดับความลับสูงกว่าสิทธิ์ที่กำหนด
การส่ง context เข้า policy ต้องทำอย่างระมัดระวังเช่นกัน เพราะผลตัดสินจะน่าเชื่อถือได้ก็ต่อเมื่อข้อมูลประกอบถูกต้อง ระบบไม่ควรให้ Agent หรือผู้ใช้กำหนด role, tenant หรือระดับความลับของ resource เองโดยไม่มีการตรวจสอบจากแหล่งข้อมูลที่เชื่อถือได้
ภาษาหรือเครื่องมือไม่ใช่จุดเริ่มต้น
ทีมสามารถใช้ OPA/Rego, Cedar, Zanzibar-style tuple, Casbin หรือสร้าง DSL ที่เหมาะกับระบบของตนเองก็ได้ แต่การเลือกเครื่องมือไม่ใช่หัวใจสำคัญที่สุด สิ่งที่สำคัญกว่าคือ policy ต้องแยกออกจาก business logic มากพอที่จะค้นหา ทบทวน และทดสอบได้โดยไม่ต้องแกะโค้ดทั้งระบบ
การแยก policy ไม่ได้หมายความว่าต้องรวมทุกกฎไว้ใน service เดียวเสมอไป แต่ทีมควรมีขอบเขตและเจ้าของกฎที่ชัดเจน จุดที่บังคับใช้นโยบายต้องใช้ผลตัดสินจากแหล่งที่เชื่อถือได้ และไม่ควรมีช่องทางอื่นที่ข้ามการตรวจสอบเดียวกันได้
กฎที่ดีควรอ่านแล้วสื่อความหมายทางธุรกิจได้ เช่น เจ้าของเอกสารอ่านเอกสารของตนได้ หรือ Agent ส่งออกข้อมูลดิบไม่ได้ แม้รูปแบบทางเทคนิคจะแตกต่างกัน หลักการคือสมาชิกทีมควรเชื่อมโยง policy กับข้อกำหนดจริงของผลิตภัณฑ์ได้
Policy ต้องมีชุดทดสอบ
Policy as Code จะมีคุณค่าเต็มที่เมื่อกฎถูกทดสอบเหมือนโค้ดทั่วไป แต่ละ test case ควรระบุข้อมูลตั้งต้น การกระทำที่ร้องขอ และผลลัพธ์ที่คาดหวังอย่างชัดเจน โดยต้องมีทั้งกรณีที่อนุญาตและกรณีที่ปฏิเสธ
ตัวอย่างกรณีทดสอบที่ควรมี ได้แก่
- User A เป็นเจ้าของ document X จึงอ่าน document X ได้
- User B ไม่ได้อยู่ใน workspace ของ document X จึงอ่านไม่ได้
- เจ้าหน้าที่ support เห็นอีเมลของลูกค้าได้ แต่ไม่เห็น payment token
- AI Assistant สรุปข้อมูลตามขอบเขตงานได้ แต่ export raw data ไม่ได้
- Agent ที่ทำงานแทนผู้ใช้ต้องไม่สามารถขยายสิทธิ์เกินกว่าสิทธิ์ของผู้ใช้นั้น
- คำขอที่ไม่มีข้อมูล tenant หรือ data classification ที่จำเป็นต้องถูกปฏิเสธ
ชุดทดสอบควรครอบคลุมกรณีขอบเขต เช่น resource อยู่คนละ workspace, ticket เพิ่งปิด หรือ role ของผู้ใช้ถูกเปลี่ยน การทดสอบลักษณะนี้ช่วยให้ทีมทราบทันทีว่าการแก้กฎหนึ่งข้อส่งผลต่อสิทธิ์ส่วนใดบ้าง
ทำไม Policy as Code จึงสำคัญต่อ AI Agent
แอปพลิเคชันทั่วไปอาจเพียงแสดงข้อมูลหรือรับคำสั่งจากแบบฟอร์ม แต่ AI Agent สามารถค้นข้อมูล เรียกใช้ tool ส่งข้อความ สร้าง ticket และยิง API ต่อเนื่องหลายขั้นตอน ความผิดพลาดเพียงครั้งเดียวจึงอาจสร้างผลกระทบจริงก่อนที่ผู้ใช้จะทันสังเกต
การเขียนไว้ใน prompt ว่า Agent ไม่ควรทำสิ่งที่ผู้ใช้ไม่มีสิทธิ์ยังไม่เพียงพอ เพราะ prompt เป็นคำแนะนำต่อโมเดล ไม่ใช่ด่านบังคับ โมเดลอาจเข้าใจบริบทผิด ผู้ใช้อาจพยายามทำ prompt injection หรือข้อมูลจากหลาย tenant อาจปะปนกันระหว่างกระบวนการทำงาน
ทุก action ที่มีผลสำคัญจึงควรถูกตรวจ policy ที่ชั้นบังคับใช้ก่อนเรียก tool หรือ API จริง ลำดับการทำงานพื้นฐานอาจเป็นดังนี้
- ยืนยันตัวตนของผู้ใช้และ Agent ที่กำลังทำงานแทน
- รวบรวม action, resource และ context จากแหล่งข้อมูลที่เชื่อถือได้
- ส่งคำขอไปยัง policy engine
- ดำเนินการเฉพาะเมื่อผลตัดสินเป็น
allow - บันทึกผลตัดสิน เหตุผล และเวอร์ชันของ policy สำหรับการตรวจสอบ
หลักการสำคัญคือ Agent ควรได้รับสิทธิ์เท่าที่จำเป็นต่อภารกิจ และต้องไม่ขยายสิทธิ์จากผู้ใช้ที่มันทำงานแทน หาก Agent มีหน้าที่เพียงสรุปข้อมูล ระบบก็ควรให้สิทธิ์อ่านเฉพาะข้อมูลที่จำเป็นโดยไม่เปิดความสามารถในการส่งออก ลบ หรือส่งข้อมูลไปยังบุคคลภายนอก
Audit และการอธิบายเหตุการณ์ย้อนหลัง
เมื่อ policy ถูกจัดเก็บเป็นโค้ด ทีมสามารถระบุได้ว่าในช่วงเวลาที่เกิดเหตุ ระบบกำลังใช้กฎเวอร์ชันใด คำขอหนึ่งได้รับอนุญาตจาก rule ใด และเหตุใดคำขออีกชุดจึงถูกปฏิเสธ ข้อมูลเหล่านี้ช่วยทั้งการ debug การตรวจสอบด้าน security และงาน compliance
Audit log ที่มีประโยชน์ควรเชื่อมโยงตัวตน การกระทำ resource ผลการตัดสิน เหตุผล และ policy version เข้าด้วยกัน อย่างไรก็ตาม ไม่ควรบันทึกข้อมูลลับทั้งหมดโดยไม่จำเป็น เพราะระบบ audit เองอาจกลายเป็นแหล่งข้อมูลอ่อนไหวที่ต้องได้รับการปกป้อง
ความสามารถในการอธิบายผลตัดสินยังช่วยให้ทีมพูดคุยกันบนกฎจริงแทนการคาดเดา Security reviewer สามารถดู diff ของ policy ขณะที่ QA นำกฎเดียวกันไปสร้าง test matrix และ developer สามารถ refactor business logic โดยตรวจได้ว่าสิทธิ์เดิมยังคงทำงานเหมือนเดิม
วิธีเริ่มต้นโดยไม่ต้องเปลี่ยนทั้งระบบ
ทีมไม่จำเป็นต้องสร้าง policy platform ขนาดใหญ่ตั้งแต่วันแรก จุดเริ่มต้นที่เหมาะสมคือ action ซึ่งมีความเสี่ยงสูงหรือสร้างผลกระทบที่ย้อนกลับได้ยาก เช่น
- การส่งออกข้อมูล
- การลบ record
- การคืนเงิน
- การส่งข้อความไปยังบุคคลภายนอก
- การอ่านข้อมูลส่วนบุคคลหรือ PII
- การเรียก API ที่สร้างธุรกรรมจริง
จากนั้นจึงระบุ subject, action, resource และ context ที่จำเป็นสำหรับแต่ละกรณี เขียนกฎให้ชัดเจน สร้าง test case สำหรับสถานการณ์ที่ทีมกังวลมากที่สุด และวาง enforcement point ไว้ก่อนการดำเนิน action จริง
แนวทางเริ่มต้นที่ปฏิบัติได้มีดังนี้
- เลือก action เสี่ยงสูงหนึ่งรายการและรวบรวมกฎปัจจุบันจากทุกส่วนของระบบ
- เขียน expected behavior ทั้งกรณีที่ต้อง allow และ deny
- ย้ายการตัดสินใจไปยัง policy ที่ตรวจสอบและทดสอบได้
- บังคับให้ทุกช่องทางซึ่งทำ action เดียวกันผ่าน policy นี้
- บันทึกผลตัดสินและติดตามความผิดปกติก่อนขยายไปยัง action อื่น
ก่อนเลือก framework ทีมควรถามว่าสิทธิ์นี้พิสูจน์ได้อย่างไร หากกฎเปลี่ยนจะรู้ได้หรือไม่ว่าอะไรพัง และเมื่อ Agent ทำงานแทนผู้ใช้ ระบบบังคับสิทธิ์ที่ชั้นใด คำตอบของคำถามเหล่านี้จะช่วยกำหนดสถาปัตยกรรมได้ดีกว่าการเริ่มจากรายการคุณสมบัติของเครื่องมือ
ข้อผิดพลาดที่ควรหลีกเลี่ยง
การมี policy engine ไม่ได้ทำให้ระบบปลอดภัยโดยอัตโนมัติ หากยังมี API บางเส้นทางที่ข้ามการตรวจสอบ หรือแต่ละบริการตีความผลตัดสินไม่เหมือนกัน นโยบายที่ดีจึงต้องมาพร้อม enforcement ที่ครอบคลุมและมีค่าเริ่มต้นเป็นการปฏิเสธเมื่อข้อมูลสำหรับตัดสินไม่เพียงพอ
ทีมควรหลีกเลี่ยงการใช้ frontend, prompt หรือเอกสารเป็นกลไกควบคุมหลัก รวมถึงไม่ควรคัดลอกกฎเดียวกันไปไว้หลายจุดโดยไม่มีแหล่งอ้างอิงร่วมกัน อีกปัญหาหนึ่งคือการเขียนเฉพาะกรณีอนุญาตแต่ไม่มี negative test ซึ่งอาจทำให้เงื่อนไขที่กว้างเกินไปหลุดผ่านโดยไม่มีใครสังเกต
สรุป
Policy as Code คือการเปลี่ยนความไว้วางใจและข้อกำหนดด้านสิทธิ์ให้กลายเป็นสิ่งที่ตรวจสอบได้ กฎสามารถอ่าน ทบทวน เก็บเวอร์ชัน ทดสอบ ย้อนกลับ และใช้อธิบายเหตุการณ์ย้อนหลังได้เหมือนโค้ดส่วนอื่นของระบบ
แนวคิดนี้ยิ่งสำคัญเมื่อ AI Agent สามารถลงมือทำงานแทนผู้ใช้ได้จริง Prompt อาจช่วยกำกับพฤติกรรม แต่ทุก action สำคัญต้องผ่านด่าน policy ที่บังคับใช้อย่างสม่ำเสมอ เพราะ authorization ที่ดีไม่ควรเป็นเวทมนตร์ซ่อนอยู่ใน if-else แต่ควรเป็นกฎที่ทีมพิสูจน์ได้และปล่อยให้เครื่องตัดสินซ้ำได้อย่างมั่นใจ