permission denied for table: إيش الفرق بينه وبين RLS؟

خطأ permission denied for table في Supabase و Postgres: ليش يطلع حتى لو قواعد RLS صحيحة، وليش منح كل الصلاحيات للزوار حل خطير.

22 أكتوبر 2026 (11 جمادى الأولى 1448 هـ) · قراءة 4 دقائق · كتبها م. معاذ أحمد

منتجك يحاول يقرأ جدول أو يضيف فيه، ويرجع: permission denied for table orders. أو permission denied for sequence orders_id_seq، أو permission denied for schema public. يشبه خطأ RLS، لكنه شي ثاني، وحله مختلف. لو خلطت بينهم، ممكن «تصلّحه» بطريقة تفتح الجدول لكل الناس.

الفرق بينه وبين RLS

قاعدة البيانات تتأكد من شيئين قبل ما تسمح بأي طلب، بالترتيب:

  1. الصلاحية على الجدول (GRANT): هل هذا الدور، مثلًا زائر anon أو مستخدم مسجّل authenticated، مسموح له أصلًا يقرأ أو يضيف في هالجدول؟ إذا لا، يطلع permission denied.
  2. قواعد السطور (RLS): إذا مسموح له بالجدول، أي سطور بالضبط يشوف ويعدّل؟ إذا ما فيه قاعدة تسمح، يطلع خطأ RLS، أو ترجع نتيجة فاضية.

يعني permission denied مثل إن البوابة نفسها مقفلة عليك. وخطأ RLS مثل إنك دخلت المبنى لكن الغرفة مو لك. شرحنا الثاني في new row violates row-level security policy.

ليش يصير

  • جدول جديد بدون صلاحيات: في Supabase، الجداول اللي تنعمل في public كانت تاخذ صلاحيات للأدوار الأساسية تلقائيًا. المشاريع الجديدة من 30 مايو 2026، وكل المشاريع من 30 أكتوبر 2026، ما تاخذها: أي جدول جديد يحتاج grant صريح، وإلا يطلع permission denied، ورسالة الخطأ نفسها فيها أمر الـ grant المطلوب. الجداول القديمة تبقى على صلاحياتها، وهذا الحين أشهر سبب للخطأ في المنتجات اللي تنبني بالذكاء الاصطناعي.
  • الجدول انعمل بدور ثاني: حتى في المشاريع القديمة، الجدول اللي ينعمل بدور غير المعتاد ما ياخذ صلاحيات الأدوار الأساسية.
  • schema جديد: أداة الذكاء الاصطناعي حطت الجداول في schema اسمه مثلًا app، وما منحت الأدوار صلاحية استخدامه، وما أضافته للـ schemas اللي يفتحها Supabase للواجهة.
  • الـ sequence: الجدول عليه صلاحية الإضافة، لكن العدّاد اللي يولّد رقم السطر، وهو sequence، ما عليه صلاحية. فالإضافة تفشل بـ permission denied for sequence.
  • سكربت سحب الصلاحيات: أحيانًا الذكاء الاصطناعي، وهو «يأمّن» قاعدتك، يكتب أوامر revoke تسحب أكثر من اللازم.
  • سيرفرك بمستخدم محدود: إذا السيرفر يتصل بقاعدة البيانات بمستخدم أنشأته أنت، هذا المستخدم يحتاج صلاحياته الخاصة على كل جدول. وفي Postgres 15 وبعده، المستخدمين الجدد ما يقدرون ينشئون جداول في public تلقائيًا.

كيف تتأكد بنفسك

  1. شوف رسالة الخطأ: جدول؟ sequence؟ schema؟ كل واحد حله مختلف.
  2. شوف مين يطلب: من المتصفح، يعني الدور anon أو authenticated؟ ولا من سيرفرك بمستخدم قاعدة بيانات؟
  3. في SQL Editor في Supabase شغّل: select grantee, privilege_type from information_schema.role_table_grants where table_name = 'orders'; واستبدل orders باسم جدولك. النتيجة تقول مين عنده إيش على هالجدول.

الحل اللي لا تسويه

أشهر اقتراح تسمعه من أدوات الذكاء الاصطناعي: grant all on all tables in schema public to anon, authenticated. الخطأ يختفي، لكن الأمر يعطي الزوار صلاحية كاملة على كل جدول، ويخلّي RLS الحاجز الوحيد. وأي جدول RLS مو مفعّل عليه، أو قاعدته true، يصير مفتوح لأي أحد يقرأه ويعدّله ويحذفه، بما فيها جداول ما تبي الواجهة تلمسها أصلًا.

والاقتراح الثاني: استخدام مفتاح service_role في الواجهة لأنه «ما يطلع خطأ صلاحيات». هذا المفتاح يتجاوز كل شي، ومكانه السيرفر فقط.

الحل الصح

  • امنح الصلاحية اللي يحتاجها الدور على الجدول اللي يحتاجه فقط. مثلًا grant select, insert on table public.orders to authenticated; بدون حذف، وبدون الزوار، إذا ما يحتاجونها.
  • إذا الإضافة تحتاج الـ sequence، امنح usage عليه لنفس الدور.
  • لـ schema جديد: صلاحية usage على الـ schema، وأضفه في إعدادات الـ API في Supabase إذا الواجهة لازم توصله.
  • وتأكد إن RLS مفعّل على كل جدول تفتحه للواجهة، مع قواعد مكتوبة لكل عملية.

بعدها جرّب بحسابين وزائر بدون دخول: كل واحد يشوف اللي له فقط. فحوصات من هالنوع في 5 ثغرات في تسجيل الدخول.

تبي أحد يرتّبها معك؟

ترتيب الصلاحيات والقواعد لجدول أو جدولين يتم في مكالمة استشارية. إذا ما تدري إيش مفتوح وإيش مقفول في قاعدتك كلها، تدقيق جاهزية الإطلاق يمر على كل جدول ويعطيك تقرير مكتوب.

عندك نفس المشكلة؟

علّمنا إيش صار بدون كلام تقني، ونقول لك إيش تحتاج وكم يكلّف.

ابدأ طلبك

بدون أي كلمة سر · عرض السعر مجاني