PostgreSQL: المستخدمون والأدوار وإدارة الصلاحيات في…
آخر تحديث: 2026-08-26
1. ما ستتعلمه
- CREATE ROLE / CREATE USER (في PG، USER = دور مع LOGIN)
- إدارة الصلاحيات GRANT / REVOKE
- تسلسل الصلاحيات: قاعدة البيانات / المخطط / الجدول / العمود / الدالة / التسلسل
- DEFAULT PRIVILEGES
- سياسات أمان مستوى الصفوف (RLS، ميزة PG)
- التحكم في صلاحيات SCHEMA
- توريث الأدوار (INHERIT / NOINHERIT)
- طرق عرض النظام: pg_roles / pg_auth_members
2. القصة
Charlie هو DBA لمنصة تجارة إلكترونية SaaS ويحتاج إلى تكوين صلاحيات قاعدة البيانات لـ 5 فرق:
| الفريق | الصلاحيات المطلوبة |
|---|---|
| dev (التطوير) | قراءة/كتابة جميع جداول الأعمال، إنشاء جداول اختبار |
| analytics (التحليلات) | قراءة فقط جميع جداول الأعمال، إنشاء طرق عرض مادية |
| ops (العمليات) | إدارة المستخدمين، مراقبة قاعدة البيانات |
| audit (التدقيق) | قراءة فقط سجلات التدقيق، ليس بيانات الأعمال |
| app (خدمة التطبيق) | قراءة/كتابة جداول الأعمال، لا DDL |
يستخدم Charlie توريث الأدوار و RLS لتنفيذ مبدأ الصلاحيات الدنيا.
3. المفهوم: الأدوار والمستخدمين
(1) CREATE ROLE مقابل CREATE USER
| الأمر | صلاحية LOGIN | الشكل المكافئ |
|---|---|---|
CREATE ROLE r1; |
لا شيء (لا يمكن تسجيل الدخول) | — |
CREATE USER u1; |
نعم (يمكن تسجيل الدخول) | CREATE ROLE u1 LOGIN; |
في PG، المستخدمون والأدوار هما نفس المفهوم؛ USER هو مجرد ROLE مع سمة LOGIN.
(2) سمات الدور في لمحة
| السمة | الوصف | صيغة الإنشاء |
|---|---|---|
| LOGIN | السماح بالاتصال بقاعدة البيانات | LOGIN / NOLOGIN |
| SUPERUSER | مستخدم مميز، يتجاوز جميع الصلاحيات | SUPERUSER |
| CREATEDB | يمكن إنشاء قواعد بيانات | CREATEDB |
| CREATEROLE | يمكن إنشاء/إدارة الأدوار | CREATEROLE |
| INHERIT | يرث تلقائياً صلاحيات الأدوار المملوكة | INHERIT (افتراضي) |
| NOINHERIT | لا يرث تلقائياً؛ يحتاج SET ROLE | NOINHERIT |
| PASSWORD | تعيين كلمة مرور | PASSWORD 'xxx' |
| VALID UNTIL | وقت انتهاء صلاحية كلمة المرور | VALID UNTIL 'timestamp' |
(1) ▶ مثال
-- أدوار المجموعة (لا يمكنها تسجيل الدخول)
CREATE ROLE dev_team NOINHERIT;
CREATE ROLE analytics_team NOINHERIT;
CREATE ROLE ops_team NOINHERIT;
CREATE ROLE audit_team NOINHERIT;
-- مستخدمو تسجيل الدخول
-- ⚠️ لا ترمز كلمات المرور في الإنتاج؛ استخدم متغيرات البيئة أو مدير أسرار
CREATE USER alice_dev PASSWORD 'SecureP@ss1' IN ROLE dev_team;
CREATE USER bob_dev PASSWORD 'SecureP@ss2' IN ROLE dev_team;
CREATE USER charlie_analyst PASSWORD 'SecureP@ss3' IN ROLE analytics_team;
CREATE USER diana_ops PASSWORD 'SecureP@ss4' IN ROLE ops_team INHERIT;
Output:
CREATE TABLE
(2) ▶ مثال
-- إضافة صلاحية CREATEDB لقائد فريق العمليات
ALTER ROLE diana_ops CREATEDB;
-- تعيين انتهاء صلاحية كلمة المرور
ALTER ROLE charlie_analyst VALID UNTIL '2025-12-31';
-- إعادة تسمية دور
ALTER ROLE dev_team RENAME TO engineering_team;
-- تعطيل تسجيل الدخول مؤقتاً
ALTER ROLE bob_dev NOLOGIN;
Output:
CREATE TABLE
4. المفهوم: صلاحيات GRANT / REVOKE
(1) تسلسل الصلاحيات
flowchart TD
A[قاعدة البيانات<br/>CONNECT / CREATE / TEMP] --> B[المخطط<br/>CREATE / USAGE]
B --> C[الجدول<br/>SELECT / INSERT / UPDATE / DELETE / TRUNCATE / REFERENCES / TRIGGER]
C --> D[العمود<br/>SELECT / INSERT / UPDATE / REFERENCES]
B --> E[الدالة<br/>EXECUTE]
B --> F[التسلسل<br/>USAGE / SELECT / UPDATE]
A --> G[الدور<br/>MEMBER / SET]
style A fill:#e1f5fe
style B fill:#bbdefb
style C fill:#c8e6c9
style D fill:#fff9c4
(2) الكلمات المفتاحية الشائعة للصلاحيات
| الكائن | الصلاحيات القابلة للمنح | الوصف |
|---|---|---|
| DATABASE | CONNECT, CREATE, TEMP | الاتصال، إنشاء مخطط، جداول مؤقتة |
| SCHEMA | CREATE, USAGE | إنشاء كائنات، الوصول إلى الكائنات |
| TABLE | SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER | CRUD كامل + مرجع مفتاح خارجي |
| COLUMN | SELECT, INSERT, UPDATE, REFERENCES | تحكم على مستوى العمود |
| FUNCTION | EXECUTE | استدعاء الدالة |
| SEQUENCE | USAGE, SELECT, UPDATE | استخدام التسلسل |
(3) ▶ مثال
-- فريق التطوير: CRUD كامل على جداول الأعمال
GRANT SELECT, INSERT, UPDATE, DELETE ON products TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON orders TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON customers TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON order_items TO dev_team;
-- فريق التحليلات: قراءة فقط
GRANT SELECT ON products TO analytics_team;
GRANT SELECT ON orders TO analytics_team;
GRANT SELECT ON customers TO analytics_team;
-- فريق التدقيق: فقط سجلات التدقيق
GRANT SELECT ON price_audit_log TO audit_team;
GRANT SELECT ON ddl_audit_log TO audit_team;
Output:
INSERT 0 1
(4) ▶ مثال
-- فريق التطوي�� يمكنه إنشاء كائنات في مخطط dev
GRANT CREATE, USAGE ON SCHEMA dev TO dev_team;
-- فريق التحليلات يمكن�� الاستخدام لكن ليس الإنشاء في المخطط public
GRANT USAGE ON SCHEMA public TO analytics_team;
-- السماح للتحليلات بإنشاء طرق عرض مادية في مخططهم الخاص
GRANT CREATE, USAGE ON SCHEMA analytics TO analytics_team;
-- خدمة التطبيق تتصل بقاعدة البيانات
GRANT CONNECT ON DATABASE shop_db TO app_service;
Output:
CREATE TABLE
(5) ▶ مثال
-- سحب DELETE من فريق التطوير على products
REVOKE DELETE ON products FROM dev_team;
-- سحب جميع الصلاحيات على جدول
REVOKE ALL PRIVILEGES ON orders FROM public;
-- سحب حق إنشاء المخطط
REVOKE CREATE ON SCHEMA dev FROM dev_team;
-- تتالي: سحب والمنح التابعة
REVOKE SELECT ON products FROM analytics_team CASCADE;
Output:
DELETE 2
(3) GRANT ALL و GRANT SELECT ALL TABLES
| الأمر | التأثير |
|---|---|
GRANT ALL ON t TO r; |
منح جميع الصلاحيات على الجدول t |
GRANT ALL ON SCHEMA s TO r; |
منح جميع الصلاحيات على المخطط s |
GRANT SELECT ON ALL TABLES IN SCHEMA s TO r; |
منح SELECT على جميع الجداول في المخطط s |
GRANT USAGE ON ALL SEQUENCES IN SCHEMA s TO r; |
منح USAGE على جميع التسلسلات |
5. المفهوم: DEFAULT PRIVILEGES
(1) لماذا تحتاج الصلاحيات الافتراضية
GRANT العادي يؤثر فقط على الكائنات الموجودة بالفعل. الجداول المنشأة في المستقبل لن تحصل على الصلاحيات تلقائياً. DEFAULT PRIVILEGES تحل هذا.
| الأمر | التأثير |
|---|---|
ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT SELECT ON TABLES TO r; |
الجداول الجديدة في s تمنح تلقائياً |
ALTER DEFAULT PRIVILEGES FOR ROLE owner GRANT ... |
الصلاحيات الافتراضية لمنشئ محدد |
(6) ▶ مثال
-- جميع الجداول المستقبلية في المخطط public قابلة للقراءة من analytics_team
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO analytics_team;
-- جميع الجداول المستقبلية المنشأة بواسطة app_service قابلة للكتابة من dev_team
ALTER DEFAULT PRIVILEGES FOR ROLE app_service IN SCHEMA public
GRANT SELECT, INSERT, UPDATE ON TABLES TO dev_team;
-- جميع التسلسلات المستقبلية في المخطط public
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE, SELECT ON SEQUENCES TO dev_team;
-- جميع الدوال المستقبلية
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT EXECUTE ON FUNCTIONS TO analytics_team;
Output:
INSERT 0 1
(7) ▶ مثال
SELECT
pg_get_userbyid(defaclrole) AS grantor,
pg_get_userbyid(defaclnamespace) AS namespace_owner,
n.nspname AS schema,
defaclobjtype AS object_type,
defaclacl AS acl
FROM pg_default_acl d
JOIN pg_namespace n ON n.oid = d.defaclnamespace;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
6. المفهوم: سياسات أمان مستوى الصفوف (RLS)
(1) كيفية عمل RLS (ميزة PG)
RLS تتيح لك التحكم في الوصول إلى البيانات على مستوى الصف — الأدوار المختلفة ترى صفوفاً مختلفة في نفس الجدول.
| الخطوة | الأمر | الوصف |
|---|---|---|
| 1. تمكين RLS | ALTER TABLE t ENABLE ROW LEVEL SECURITY; |
تمكين أمان مستوى الصفوف على الجدول |
| 2. إنشاء سياسة | CREATE POLICY ... ON t ...; |
تعريف قاعدة مستوى الصف |
| 3. تجاوز المستخدم المميز | — | SUPERUSER لا يخضع لـ RLS افتراضياً |
| 4. تجاوز مالك الجدول | — | مالك الجدول لا يخضع افتراضياً؛ استخدم FORCE للفرض |
(2) أنواع الياسات
| نوع السياسة | الكلمة المفتاحية | الوصف |
|---|---|---|
| SELECT | FOR SELECT |
يتحكم في الصفوف المرئية |
| INSERT | FOR INSERT |
يتحكم في الصفوف القابلة للإدراج |
| UPDATE | FOR UPDATE |
يتحكم في الصفوف القابلة للتحديث (يشمل BEFORE/AFTER) |
| DELETE | FOR DELETE |
يتحكم في الصفوف القابلة للحذف |
| ALL | FOR ALL |
مشتركة عبر جميع العمليات |
(8) ▶ مثال
-- تمكين RLS على جدول orders
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
-- المحللون يمكنهم فقط رؤية الطلبات المكتملة
CREATE POLICY pol_analytics_completed
ON orders FOR SELECT
TO analytics_team
USING (order_status = 'completed');
-- فريق التطوير يمكنه رؤية جميع الصفوف
CREATE POLICY pol_dev_all
ON orders FOR ALL
TO dev_team
USING (true)
WITH CHECK (true);
Output:
CREATE TABLE
(9) ▶ مثال
-- تمكين RLS على جدول customers
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
-- كل مستخدم خدمة عملاء يرى فقط منطقته المعينة
CREATE POLICY pol_region_access
ON customers FOR SELECT
USING (region = current_setting('app.region', true));
-- فرض التزام مالك الجدول أيضاً بـ RLS
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
Output:
CREATE TABLE
(10) ▶ مثال
-- فريق المبيعات يمكنه فقط إدراج طلبات في منطقته
CREATE POLICY pol_sales_insert
ON orders FOR INSERT
TO dev_team
WITH CHECK (region = current_setting('app.region', true));
-- فريق المبيعات يمكنه فقط تحديث الطلبات في منطقته
CREATE POLICY pol_sales_update
ON orders FOR UPDATE
TO dev_team
USING (region = current_setting('app.region', true))
WITH CHECK (region = current_setting('app.region', true));
Output:
INSERT 0 1
(3) USING مقابل WITH CHECK
| العبارة | الدور | تنطبق على |
|---|---|---|
| USING | تصفي الصفوف المرئية (WHERE لـ SELECT/UPDATE/DELETE) | SELECT/UPDATE/DELETE |
| WITH CHECK | تتحقق مما إذا كان الصف الجديد مسموحاً (القيم الجديدة لـ INSERT/UPDATE) | INSERT/UPDATE |
7. المفهوم: توريث الأدوار وطرق عرض النظام
(1) INHERIT مقابل NOINHERIT
| السمة | السلوك | السيناريو |
|---|---|---|
| INHERIT (افتراضي) | يكتسب تلقائياً صلاحيات الأدوار المملوكة | المستخدمون العاديون |
| NOINHERIT | يحتاج SET ROLE r لاستخدام الصلاحيات |
تصعيد مؤقت للصلاحيات، فصل التدقيق |
(11) ▶ مثال
-- إنشاء دور قوي مع NOINHERIT
CREATE ROLE admin_role NOINHERIT;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO admin_role;
-- Diana في admin_role لكن لا يمكنها استخدام صلاحيات المسؤول تلقائياً
CREATE USER diana PASSWORD 'SecureP@ss5' IN ROLE admin_role NOINHERIT;
-- يجب على Diana التبديل صراحةً لاستخدام حقوق المسؤول
SET ROLE admin_role;
-- الآن يمكن لـ diana تنفيذ عمليات المسؤول
RESET ROLE;
-- العودة إلى الصلاحيات العادية
Output:
CREATE TABLE
(2) طرق عرض النظام
| طريقة العرض | المحتوى |
|---|---|
pg_roles |
جميع الأدوار وسماتها |
pg_auth_members |
علاقات الدور-العضو |
information_schema.role_table_grants |
صلاحيات مستوى الجدول |
information_schema.role_usage_grants |
صلاحيات المخطط/الدالة |
(12) ▶ مثال
-- سرد جميع الأدوار وسماتها
SELECT rolname, rolsuper, rolcreatedb, rolcanlogin, rolinherit
FROM pg_roles
WHERE rolname NOT LIKE 'pg_%'
ORDER BY rolname;
-- سرد عضوية الأدوار
SELECT
r1.rolname AS member,
r2.rolname AS role
FROM pg_auth_members m
JOIN pg_roles r1 ON r1.oid = m.member
JOIN pg_roles r2 ON r2.oid = m.roleid
ORDER BY r2.rolname, r1.rolname;
-- التحقق من صلاحيات الجدول لدور
SELECT table_name, privilege_type
FROM information_schema.role_table_grants
WHERE grantee = 'analytics_team'
ORDER BY table_name, privilege_type;
Output:
CREATE TABLE
8. مخطط التدفق: قرار تكوين الصلاحيات
flowchart TD
A[تكوين الصلاحيات] --> B{بحاجة لتحكم على مستوى الصف؟}
B -->|نعم| C[تمكين RLS<br/>CREATE POLICY]
B -->|لا| D{دقة الصلاحية؟}
D -->|جدول كامل| E[GRANT ON TABLE]
D -->|عمود محدد| F[GRANT column_name ON TABLE]
D -->|جميع الجداول في المخطط| G[GRANT ALL TABLES IN SCHEMA]
E --> H{بحاجة لمنح تلقائي على الجداول الجدي��ة؟}
G --> H
H -->|نعم| I[ALTER DEFAULT PRIVILEGES]
H -->|لا| J[GRANT يدوي]
C --> K{بحاجة لتقييد مالك الجدول أيضاً؟}
K -->|نعم| L[FORCE ROW LEVEL SECURITY]
K -->|لا| M[المالك يتجاوز RLS افتراضياً]
I --> N{المستخدم بحاجة لتصعيد مؤقت؟}
J --> N
N -->|نعم| O[NOINHERIT + SET ROLE]
N -->|لا| P[INHERIT افتراضياً]
style C fill:#fff9c4
style I fill:#c8e6c9
style O fill:#ffcdd2
9. مثال شامل
يقوم Charlie بتكوين نظام صلاحيات كامل للفرق الخمسة:
-- الخطوة 1: إنشاء أدوار المجموعة
CREATE ROLE dev_team NOINHERIT;
CREATE ROLE analytics_team NOINHERIT;
CREATE ROLE ops_team INHERIT;
CREATE ROLE audit_team NOINHERIT;
CREATE ROLE app_service LOGIN PASSWORD 'AppSecRet!';
-- الخطوة 2: منح صلاحيات المخطط
GRANT CREATE, USAGE ON SCHEMA public TO dev_team;
GRANT USAGE ON SCHEMA public TO analytics_team;
GRANT CREATE, USAGE ON SCHEMA analytics TO analytics_team;
GRANT USAGE ON SCHEMA public TO ops_team;
GRANT USAGE ON SCHEMA audit TO audit_team;
-- الخطوة 3: منح صلاحيات الجدول
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO dev_team;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO analytics_team;
GRANT SELECT ON ALL TABLES IN SCHEMA audit TO audit_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON products, orders, order_items, customers TO app_service;
-- الخطوة 4: الصلاحيات الافتراضية للجداول المستقبلية
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO analytics_team;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO dev_team;
ALTER DEFAULT PRIVILEGES IN SCHEMA audit
GRANT SELECT ON TABLES TO audit_team;
-- الخطوة 5: صلاحيات التسلسلات والدوال
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO dev_team;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_service;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE, SELECT ON SEQUENCES TO dev_team;
-- الخطوة 6: RLS - المحللون يرون فقط الطلبات المكتملة
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY pol_analytics_orders
ON orders FOR SELECT
TO analytics_team
USING (order_status = 'completed');
-- الخطوة 7: RLS - فريق التدقيق يرى فقط مخطط audit
ALTER TABLE price_audit_log ENABLE ROW LEVEL SECURITY;
CREATE POLICY pol_audit_read
ON price_audit_log FOR SELECT
TO audit_team
USING (true);
-- الخطوة 8: إنشاء مستخدمي تسجيل الدخول وتعيين الأدوار
CREATE USER alice_dev PASSWORD 'DevP@ss1' IN ROLE dev_team;
CREATE USER bob_dev PASSWORD 'DevP@ss2' IN ROLE dev_team;
CREATE USER charlie_analyst PASSWORD 'AnlP@ss3' IN ROLE analytics_team;
CREATE USER diana_ops PASSWORD 'OpsP@ss4' IN ROLE ops_team CREATEROLE;
CREATE USER eve_audit PASSWORD 'AudP@ss5' IN ROLE audit_team;
❓ أسئلة شائعة
\dp و \du+. لاحظ أن أدوار INHERIT تكتسب تلقائياً صلاحيات الأدوار التي تنتمي إليها.📖 ملخص
- في PG، USER = LOGIN ROLE؛ الدور هو الوحدة الأساس��ة لإدارة الصلاحيات
- سمات الدور: LOGIN/SUPERUSER/CREATEDB/CREATEROLE/INHERIT تتحكم في قدرات مختلفة
- GRANT/REVOKE تدير الصلاحيات؛ التسلسل هو: قاعدة البيانات → المخطط → الجدول → العمود
- DEFAULT PRIVILEGES تحل مشكلة المنح التلقائي للكائنات المنشأة حديثاً
- RLS (ميزة PG) تنفذ التحكم في الوصول على مستوى الصف؛ USING تصفي الصفوف المرئية، WITH CHECK تتحقق من الصفوف الجديدة
- INHERIT يرث الصلاحيات تلقائياً؛ NOINHERIT يحتاج SET ROLE للتصعيد المؤقت
- pg_roles / pg_auth_members / طرق عرض information_schema تستعلم تكوين الصلاحيات
- مبدأ الصلاحيات الدنيا: امنح حسب الطلب، تجنب الإفراط في الصلاحيات
📝 تمارين
-
⭐ أنشئ دور
readonlyومستخدماًreport_user، امنحreadonlyصلاحية SELECT على جميع الجداول في المخطط public، وعيّن الصلاحيات الافتراضية بحيث تمنح الجداول المنشأة حديثاً تلقائياً. -
⭐⭐ فعّل RLS على جدول
ordersوأنشئ سياسات:sales_teamيمكنه فقط رؤية الطلبات في منطقته (region = current_setting('app.region'))؛audit_teamيمكنه فقط رؤية الطلبات معorder_status = 'completed'. -
⭐⭐⭐ صمم نظام صلاحيات كامل: أنشئ 3 أدوار مجموعة (
backend_dev،data_analyst،db_admin)، مانحاً كل منها مستويات مختلفة من الصلاحيات (مخطط/جدول/عمود/دالة/تسلسل)، اضبط DEFAULT PRIVILEGES، امنح عمودsalaryبشكل منفصل (المحلل لا يمكنه رؤيته)، واستخدمpg_rolesوinformation_schemaللاستعلام والتحقق من نتيجة التكوين.