الوصول إلى قاعدة البيانات
تستطيع كل بيئة أن تعطيك سلسلة اتصال PostgreSQL للترحيلات والأدوات: psql وpg_dump وPrisma وDrizzle وأمثالها. تكون مطفأة حتى يشغّلها مالك أو مدير.
التشغيل
- افتح صفحة البيئة في لوحة الإدارة.
- تحت Database اضغط Turn on database access.
- انسخ سلسلة الاتصال التي تظهر. لا تظهر كلمة المرور إلا مرة واحدة؛ وزر New password يستبدلها، فتتوقف القديمة عن العمل.
تبدو السلسلة هكذا:
postgresql://e_…_developer:<password>@127.0.0.1:6543/e_…الاتصال من حاسوبك
العنوان على الخادم نفسه. افتح نفق SSH، ثم استخدم السلسلة كما هي:
ssh -N -L 6543:127.0.0.1:6543 you@your-server
psql "postgresql://e_…_developer:<password>@127.0.0.1:6543/e_…?sslmode=disable"أمثلة:
psql "postgresql://…@127.0.0.1:6543/e_…?sslmode=disable" -v ON_ERROR_STOP=1 -1 -f supabase/migrations/20261017000000_init.sql # one migration file
pg_dump "postgresql://…@127.0.0.1:6543/e_…?sslmode=disable" --schema=public > public.sql
DATABASE_URL="postgresql://…@127.0.0.1:6543/e_…?sslmode=disable" npx prisma migrate deploy
supabase db push --db-url "postgresql://…@127.0.0.1:6543/e_…?sslmode=disable" # every file in supabase/migrations
supabase gen types typescript --db-url "postgresql://…@127.0.0.1:6543/e_…?sslmode=disable" > database.types.tsما يستطيعه حساب المطوّر
يعمل مثل المستخدم postgres في مشروع Supabase، داخل قاعدة بيانات هذه البيئة وحدها:
إنشاء الجداول والعروض والدوال والسياسات في
publicوتعديلها. تُمنح الجداول الجديدة لـanonوauthenticatedوservice_role، فتصل إليها الواجهة، ويحدد أمان الصفوف ما يراه كل مستدعٍ. تُضبط هذه الصلاحيات الافتراضية مرة واحدة، عند أول تشغيل للوصول، والترحيل الذي يضيّقها يبقى اختياره قائمًا.إضافة مشغّلات (triggers) على
auth.users(مثلًا لإنشاء ملف شخصي عند التسجيل) وسياسات علىstorage.objects.قراءة كل الصفوف وكتابتها؛ فهو يتجاوز أمان الصفوف، كما يفعل المستخدم
postgres.حفظ سجل الترحيلات في
supabase_migrations، وهو مخطط (schema) أُنشئ له، يسجّل فيه وكلاء الذكاء الاصطناعي ما طبّقوه.إنشاء مخططات خاصة به، مثل
appأوprivate، وتغيير أسمائها. لكنه لا يستطيع استخدام اسم تنشئه المنصة نفسها:authوstorageوextensionsوpublicوrealtimeو_realtimeوvaultوpgsodiumوcronوnetوgraphqlوgraphql_publicوأسماء أخرى قليلة (RESERVED_SCHEMASفيlab/durable_runtime.py)، وأي اسم يبدأ بـsupabaseأوsbarbase. فالمخطط الذي يسبق إليه بأحد هذه الأسماء سيشغّل شيفرته بصلاحيات المنصة، لذلك يرفض PostgreSQL الأمر، ويرفض كذلك تغيير اسم مخطط إلى أحدها.حفظ الأسرار في Vault (
vault.create_secretوvault.update_secretوvault.decrypted_secrets) كما في Supabase، ويقرؤهاservice_roleأيضًا. ولا يستطيع الحساب أن يعطي هذا الوصول لأدوار أخرى، فلا يفتح منحُه لـanonالأسرارَ للواجهة.إنشاء الإضافات (extensions) التي يستخدمها التطبيق، مثل
pg_trgmوbtree_gistوvectorوpgtapوpg_graphql. أما الإضافات التي تصل إلى شبكة الخادم، أو ترى نشاط كل البيئات، أو تحمّل شيفرة، أو تكتب ملفات على الخادم، أو تمسك مفتاح الخادم، فمرفوضة على الخادم المشترك:dblinkوpostgres_fdwوhttpوpg_netوwrappersوpg_cronوpg_tleوpgsodiumوpg_stat_statementsوpg_stat_monitorوpg_walinspectوpg_buffercacheوpg_prewarmوpg_repackوpgauditوpgroongaوغيرها قليل (RESERVED_EXTENSIONSفيlab/durable_runtime.py).إضافة جداول إلى منشور
supabase_realtime، وهو موجود دائمًا ويملكه الحساب، كما يملكه المستخدمpostgresفي مشروع Supabase. يشمل المنشور مخططpublicكله، فجداوله منشورة أصلًا، وإضافة أحدها مقبولة ولا تغيّر شيئًا. ويمكن إضافة جداول المخططات الأخرى واحدًا واحدًا. وإن حذفه الحساب، تعيد المنصة إنشاءه في المرة التالية التي يُشغَّل فيها الوصول.
تُمنح هذه الصلاحيات عند تشغيل الوصول؛ وللبيئة التي كان الوصول فيها مفعّلًا من قبل، أوقفه ثم شغّله مرة واحدة.
تُشفَّر أسرار Vault بمفتاح جذري واحد يخص الخادم لا البيئة: كل البيئات على الخادم تستخدم المفتاح نفسه. وتبقى منفصلة لأن كل بيئة لا تصل إلا إلى قاعدة بياناتها. انتبه لذلك في النسخ الاحتياطية: نسخة من vault.secrets لبيئة ما يمكن قراءتها في أي بيئة على الخادم نفسه، وعلى خادم آخر فقط بمفتاح هذا الخادم.
ليس مستخدمًا خارقًا، ولا يستطيع إنشاء أدوار أو قواعد بيانات، ولا الوصول إلى قاعدة بيانات بيئة أخرى. وحده الأقصى 10 اتصالات.
كيف يبقى آمنًا
- يستمع المنفذ على عنوان loopback في الخادم، على المنفذ 6543 افتراضيًا. يقرأ اسم الدخول في كل اتصال قبل أن يصل أي شيء إلى PostgreSQL، ولا يمرّر إلا حساب مطوّر لبيئة يطلب قاعدة بيانات تلك البيئة نفسها. أي حساب آخر، ومنه المستخدم الخارق، يُرفض هناك.
- ثم يتحقق PostgreSQL من كلمة المرور (SCRAM). وإطفاء الوصول يغلق الحساب وكل الجلسات المفتوحة به.
- لا يشفّر المنفذ الاتصال؛ نفق SSH هو الذي يشفّره. يمكن لـ
SBARBASE_DATABASE_BINDأن يعرض المنفذ على عنوان آخر، لكن افعل ذلك على شبكة تثق بها فقط (الإعدادات).
يشغّل CI الوصول لبيئة على جهاز نظيف مع كل تغيير، وينفّذ ترحيلًا بأسلوب Supabase عبر المنفذ، ويتحقق من حالات الرفض وتجديد كلمة المرور والإطفاء (الدليل). وفحص آخر يدخل بحساب بيئة واحدة ويجرّب كل اسم مخطط محجوز، وتغيير الأسماء، والإضافات المرفوضة، ومنشور Realtime، والحماية نفسها، وVault، وقاعدة بيانات البيئة الأخرى (الدليل).
الحدود
- حساب واحد لكل بيئة، حتى 10 اتصالات؛ ولا يوجد مجمّع اتصالات بعد.
- يرفض المنفذ TLS؛ استخدم
sslmode=disableأوpreferعبر النفق. - يُرفض الترحيل الذي يذكر الدور
postgres، مثلalter default privileges for role postgres: فحساب المطوّر في كل بيئة يقوم بهذا الدور، أماpostgresنفسه فمشترك بين كل الخادم. اكتبه دونfor role postgres، فينطبق على الحساب الذي يشغّله.