RBAC คืออะไร และออกแบบ Role กับ Permission อย่างไรไม่ให้ระบบสิทธิ์รก
แยก user, role และ permission ให้ชัดเจน ใช้หลัก least privilege และหลีกเลี่ยงการฝังชื่อ role กระจายในโค้ด เพื่อให้ระบบ authorization ขยายต่อได้

ภาพรวม
RBAC คืออะไร
RBAC ย่อมาจาก Role-Based Access Control แปลตรง ๆ คือ การกำหนดสิทธิ์ตามบทบาท ไม่ใช่กำหนดสิทธิ์ให้คนทีละคน
ฟังดูเป็นเรื่อง security แต่จริง ๆ เป็นเรื่อง design ด้วย เพราะถ้าออกแบบไม่ดีตั้งแต่แรก ระบบจะโตไปเป็นกอง spaghetti สิทธิ์ 🍝
ตัวอย่างง่าย ๆ ในระบบหลังบ้านอาจมีคน 4 แบบ admin manager support viewer
แต่ละคนไม่ได้ควรเข้าถึงทุกอย่างเท่ากัน admin จัดการระบบได้ manager ดูรายงานและอนุมัติได้ support ดูข้อมูลลูกค้าเพื่อช่วยแก้ปัญหาได้ viewer ดูได้อย่างเดียว
แนวคิดสำคัญคือ อย่าเริ่มจากคำถามว่า “user คนนี้ทำอะไรได้บ้าง” ให้เริ่มจากคำถามว่า “ระบบเรามี action อะไรบ้าง”
เช่น user.read user.create user.update user.delete order.read order.refund report.export setting.update
permission ควรเป็นคำกริยาที่ชัด อ่านแล้วรู้ว่าทำอะไรกับ resource ไหน อย่าตั้งชื่อแบบ canDoThing superPermission accessLevel3 เพราะอีก 6 เดือนจะไม่มีใครอยากแตะ 😅
จากนั้นค่อยเอา permission ไปประกอบเป็น role role จึงเป็นแค่ชุดของ permission ไม่ใช่ hardcode logic กระจายทั่ว codebase
ข้อผิดพลาดที่พบบ่อยคือ สร้าง role ตามตำแหน่งงานจริงแบบละเอียดเกินไป เช่น senior_sales_bangkok_team_a_temp ชื่อแบบนี้ทำให้ role ระเบิดจำนวนเร็วมาก
ให้แยกให้ออกว่า role คือสิทธิ์ในระบบ ไม่ใช่โครงสร้างบริษัททั้งหมด ถ้าต้องแยกสาขา ทีม หรือเจ้าของข้อมูล ให้ใช้ attribute เพิ่ม เช่น team_id, region, owner_id แล้วตรวจร่วมกับ permission
อีกเรื่องที่ควรระวังคือ role ซ้อน role ตอนแรกดูสะดวก admin inherit manager manager inherit staff แต่พอโตขึ้นจะ debug ยากมาก ว่า permission หนึ่งหลุดมาจากไหน ถ้าระบบยังไม่ใหญ่จริง เก็บ role เป็นชุด permission ตรง ๆ มักอ่านง่ายกว่า
หลักที่ดีคือ least privilege ให้สิทธิ์เท่าที่จำเป็น ไม่ให้เผื่อไว้ก่อน เพราะสิทธิ์ที่เกินวันนี้ อาจกลายเป็นช่องโหว่วันหน้า
ใน code ควรมีจุดตรวจสิทธิ์ที่สม่ำเสมอ เช่น middleware, policy, guard หรือ service กลาง อย่าเขียน if user.role == 'admin' กระจายทุกหน้า เพราะเมื่อ role เปลี่ยน คุณจะต้องไล่แก้ทั้งระบบ
รูปแบบที่สะอาดกว่าคือ ถามระบบว่า user มี permission นี้ไหม เช่น can(user, 'order.refund') can(user, 'report.export')
แบบนี้ business logic จะอ่านง่าย และเปลี่ยน role ได้โดยไม่ต้องรื้อ flow หลัก
อีกสิ่งที่ควรมีตั้งแต่แรกคือ audit ใครเปลี่ยน role เปลี่ยนเมื่อไร ให้ permission อะไรเพิ่ม เพราะปัญหา access control ไม่ได้เกิดแค่จาก bug แต่เกิดจากการ config ผิดได้ด้วย
RBAC ที่ดีไม่ใช่ RBAC ที่ซับซ้อนที่สุด แต่คือ RBAC ที่ทีมอ่านแล้วเข้าใจตรงกัน เพิ่ม role ใหม่ได้โดยไม่กลัว ตรวจสิทธิ์ได้โดยไม่เดา และลบสิทธิ์เก่าได้โดยไม่ทำระบบพัง
เริ่มจาก permission เล็ก ชัด และเป็นภาษาเดียวกันทั้งทีม แล้วค่อยประกอบเป็น role ระบบจะโตได้แบบไม่รกตั้งแต่วันแรกครับ ✨
แนวทางนำไปใช้
- นำแนวคิดจากโพสต์นี้ไปทดลองกับงานจริงของคุณ
- แยกเป็นขั้นตอนเล็ก ๆ แล้วทำทีละส่วน
- บันทึกผลลัพธ์และสิ่งที่เรียนรู้เพื่อต่อยอด
สรุป
แยก user, role และ permission ให้ชัดเจน ใช้หลัก least privilege และหลีกเลี่ยงการฝังชื่อ role กระจายในโค้ด เพื่อให้ระบบ authorization ขยายต่อได้