การจัดการสิทธิ์ (Privileges) เป็นหัวใจสำคัญของการรักษาความปลอดภัยของฐานข้อมูล ไม่ว่าจะเป็น MySQL หรือ PostgreSQL การทราบว่าผู้ใช้งานคนใดมีสิทธิ์ทำอะไรได้บ้างในระดับตาราง คอลัมน์ หรือแม้แต่ Schema ต่างๆ จึงเป็นสิ่งจำเป็นสำหรับ Senior Developer และ System Architect
บทความนี้จะนำเสนอวิธีการตรวจสอบและจัดการสิทธิ์ของผู้ใช้ในระบบ PostgreSQL โดยเน้นการใช้คุณสมบัติขั้นสูงของ PostgreSQL เพื่อให้มั่นใจว่าเราได้ปฏิบัติตามหลักการ Least Privilege (มอบสิทธิ์เท่าที่จำเป็นเท่านั้น) อย่างเคร่งครัด
🔑 หลักการตรวจสอบสิทธิ์ผู้ใช้ใน PostgreSQL
ใน PostgreSQL การจัดการสิทธิ์จะถูกควบคุมโดยระบบ Role และ System Catalogs แทนที่จะเป็นการตั้งค่าไฟล์คอนฟิกแบบเดิมๆ เราสามารถเข้าถึงข้อมูลสิทธิ์ทั้งหมดผ่าน information_schema หรือ View เฉพาะของระบบได้
1. ตรวจสอบบทบาท (Roles) และผู้ใช้งาน
ก่อนอื่น คุณต้องทราบว่ามี Role ใดบ้างที่ถูกสร้างขึ้นมาในระบบ ซึ่งสามารถทำได้โดยใช้คำสั่ง Meta-command \du หรือการ Query ผ่าน View pg_roles:
SQL
SELECT rolname, rolsuper, rolcreaterole FROM pg_roles WHERE rolname NOT IN ('postgres', 'public');
2. ตรวจสอบสิทธิ์ระดับตารางและคอลัมน์ (Object Privileges)
การตรวจสอบสิทธิ์ที่ละเอียดที่สุดคือการดูว่า Role นั้นๆ มีสิทธิ์ SELECT, INSERT, UPDATE หรือ DELETE บน Object ใดบ้าง เราสามารถใช้ information_schema.column_privileges เพื่อดึงข้อมูลนี้ได้อย่างมีประสิทธิภาพ:
SQL
-- ตัวอย่าง: ตรวจสอบสิทธิ์ SELECT ทั้งหมดบนตาราง 'user_data' ใน Schema 'public'
SELECT
grantee,
table_name,
column_name,
privilege_type
FROM
information_schema.column_privileges
WHERE
table_name = 'user_data' AND column_name IS NOT NULL;
3. การตรวจสอบสิทธิ์ที่ซับซ้อนด้วย Recursive CTE
ในกรณีที่คุณต้องการตรวจสอบการพึ่งพาของ Object (เช่น ตาราง A ถูกเรียกใช้โดย View B ซึ่งถูกเรียกใช้โดย Function C) คุณสามารถใช้ Recursive Common Table Expression (CTE) เพื่อไล่ลำดับความสัมพันธ์ได้อย่างแม่นยำ:
SQL
WITH RECURSIVE dependency_chain AS (
-- Anchor Member: เริ่มต้นจาก Object ที่ต้องการตรวจสอบ
SELECT 'user_data'::text AS object_name, 1 AS depth
UNION ALL
-- Recursive Member: ค้นหา Object ที่อ้างอิงถึง Object ก่อนหน้า
SELECT
t.table_name,
dc.depth + 1
FROM
information_schema.views v
JOIN pg_depend d ON d.objid = v.viewowner::regclass AND d.refobjid = v.oid
WHERE
v.table_name = 'user_data' -- กำหนดจุดเริ่มต้น
)
SELECT * FROM dependency_chain;
💡 บทสรุปและแนวทางปฏิบัติที่ดีที่สุด
การตรวจสอบสิทธิ์ใน PostgreSQL ไม่ได้จบแค่การ Query ข้อมูล แต่ต้องนำไปสู่การปรับปรุงระบบอย่างต่อเนื่องเสมอ สิ่งที่สำคัญที่สุดคือการยึดมั่นในหลักการ Least Privilege เสมอ เมื่อคุณพบว่า Role ใดมีสิทธิ์เกินความจำเป็น (Over-privileged) คุณควรใช้คำสั่ง REVOKE เพื่อถอดสิทธิ์เหล่านั้นออก และใช้ GRANT เฉพาะสิ่งที่จำเป็นเท่านั้น
ด้วยการทำความเข้าใจโครงสร้างของ information_schema และการใช้ฟังก์ชันขั้นสูงอย่าง Recursive CTE คุณจะสามารถบริหารจัดการความปลอดภัยของฐานข้อมูล PostgreSQL ได้ในระดับ Senior Architect อย่างแท้จริง