// docs / baas security / supabase service role exposure
Supabase service role key በJavaScript የተጋለጠ፦ ምን ማለት እንደሆነና እንዴት እንደሚገኝ
Supabase service role key ለdatabase-ዎ master key ነው። የያዘው ሁሉ Row-Level Security-ን ይዘላል፣ የእያንዳንዱ table እያንዳንዱን column ሊያነብ ይችላል፣ እና የፈለገውን ሊጽፍ ወይም ሊሰርዝ ይችላል። የተነደፈው በserver-side code ብቻ እንዲኖር ነው — በbrowser ውስጥ በፍጹም አይደለም። AI coding tool ወደ JavaScript bundle ሲልከው፣ database-ዎ በትክክል public ነው። ይህ ጽሑፍ የተፈሰሰን key የሚለይ የJWT shape፣ ሦስቱን AI-tool pattern-ዎች የሚፈጥሩትን ስብር፣ ከመለየት በኋላ በመጀመሪያ ሰዓት ምን ማድረግ እንዳለበት፣ እና ተጠቃሚዎች ከማወቃቸው በፊት እንዴት automatic ሆኖ scan እንደሚደረግ ያብራራል።
Service role key ምን እንደሆነ
Supabase ለእያንዳንዱ project ሁለት የተለያዩ key-ዎች ያወጣል፦ anon key (በአዲሶቹ project-ዎች publishable key ተብሎም ይጠራል) እና service_role key። ሁለቱም በproject-ዎ JWT secret የተፈረሙ JSON Web Token-ዎች ናቸው። ልዩነቱ በJWT payload ውስጥ የተደቆሰው role claim ነው — ለpublic key anon፣ ለmaster key service_role። PostgREST፣ Supabase Storage እና Supabase Auth ሁሉም service_role claim-ን ሲያዩ ወደ bypass-everything mode ይቀየራሉ።
ማንኛውንም Supabase key በjwt.io ላይ decode ያድርጉና payload-ውን ይመልከቱ። የservice-role JWT shape በግልጽ የተለየ ነው፦
የService-role JWT decoded payload (ከታች በsyntax-highlighted block ሆኖ የተመለከተ)።
{
"iss": "supabase",
"ref": "[project-ref]",
"role": "service_role",
"iat": 1700000000,
"exp": 2000000000
}አዲሶቹ Supabase project-ዎች ከJWT ይልቅ የsb_secret_ prefix ያላቸው secret-style key-ዎች ያወጣሉ። ባህሪው ተመሳሳይ ነው — በpublic bundle ውስጥ sb_secret_ የያዘ ማንኛውም ነገር በተመሳሳይ አደገኛ ነው።
AI coding tool-ዎች service role key-ን እንዴት እንደሚያፈሱ
በሺዎች በሚቆጠሩ vibe-coded app-ዎች ላይ ተመሳሳዩን ሦስት pattern-ዎች አይተናል። እያንዳንዱ የሚጀምረው developer ለAI tool እርዳታ ሲጠይቅ ሲሆን፣ የሚጨርሰው service key በbundle ውስጥ ሲቀመጥ ነው።
Pattern 1፦ ከNEXT_PUBLIC_ prefix ጋር አንድ .env file
Developer-ው AI tool-ን "Supabase ይዘጋጅ" ብሎ ይጠይቅና ሁለቱም key-ዎች ያሉበት አንድ .env ይቀበላል። AI tool-ው — አብዛኞቹ environment variable-ዎች በNEXT_PUBLIC_* በኩል የተጋለጡበት corpus ላይ የተሰለጠነ — ሁለቱንም በNEXT_PUBLIC_ prefix ያደርጋቸዋል። Next.js በbuild time ይህን prefix የሚዛመድ ማንኛውንም ነገር ወደclient bundle ይጨምራል። ወደ Vercel ሲልኩ፣ service key በmain.[hash].js ውስጥ ይሆናል።
Pattern 2፦ በcreateClient call ውስጥ ስህተት ያለው key
Developer-ው ሁለቱንም key-ዎች AI ወደ ፈጠረው config.ts file ውስጥ ይለጥፋል፣ እና AI በስህተት የbrowser-side createClient() call-ን በprocess.env.SUPABASE_SERVICE_ROLE_KEY ይሞላዋል። Build variable-ውን ያስገባል፣ እና JWT በbundle ውስጥ ይሆናል።
Pattern 3፦ Service-role key በseed script ውስጥ hardcode ሆኖ
Developer-ው AI tool-ን database-ን የሚሞላ script እንዲጽፍ ይጠይቃል። AI service-role key-ን (ከenvironment ከማንበብ ይልቅ) በቀጥታ ወደ file ውስጥ hardcode ያደርጋል፣ file-ውን ወደ repository commit ያደርጋል፣ እና public GitHub repo ወይም የተሰማራው app /scripts/seed.js route አሁን key-ውን እያቀረበ ይሆናል።
የFixVibe bundle scan ይህን ስብር እንዴት እንደሚለይ
የFixVibe bundle-secrets check በተሰማራው app የተጠቀሰውን እያንዳንዱን JavaScript file ያወርዳል — entry chunks፣ lazy-loaded chunks፣ web workers፣ service workers — እና የJWT shape (eyJ[base64-header].eyJ[base64-payload].[signature]) የሚዛመድ ማንኛውንም ነገር decode በሚያደርግ detector ውስጥ ያስኪዳቸዋል። የdecode የተደረገው payload "role": "service_role" ከያዘ፣ scan ይህን እንደ critical finding የfile path እና key የሚታይበትን ትክክለኛ line ጋር ይዘግባል። ይኸው check አዲሱን የsb_secret_* pattern-ንም በprefix ይዛመዳል።
Scan በተገኘ key በፍጹም authenticate አያደርግም። Shape-ን ይለያል እና ስብርን ይዘግባል — exploit-ablility-ን ለማረጋገጥ key-ውን መጠቀም ወደ database-ዎ ያልተፈቀደ access ይሆናል። ማስረጃው በJWT payload ራሱ ውስጥ ነው።
ተገኝቷል — በመጀመሪያ ሰዓት ምን ማድረግ አለበት
የተፈሰሰ service role key የruntime አደጋ ነው። Key scrape ተደርጓል ብለው ይገምቱ — attacker-ዎች public bundle-ዎችን በrealtime ይከታተላሉ። Key-ውን እስኪሮቴት እና የቅርብ ጊዜ እንቅስቃሴን እስኪያytuit ድረስ database-ዎን እንደተጣረሰ ይያዙት።
- Key-ውን ወዲያውኑ ሮቴት ያድርጉ። በSupabase Dashboard ውስጥ ወደ Project Settings → API → Service role key → Reset ይሂዱ። ቀደም ያለው key በሰከንዶች ውስጥ invalidate ይደረጋል። Key-ውን የሚጠቀም ማንኛውም service-side code ሮቴሽን ከመድረሱ በፊት መታደስ እና እንደገና መሰማራት አለበት።
- የቅርብ ጊዜ database እንቅስቃሴን audit ያድርጉ። በdashboard ውስጥ Database → Logs ይክፈቱ። ባለፉት 7 ቀናት ላይ filter ያድርጉ። ካልተለመዱ PII ባላቸው table-ዎች ላይ
SELECT *query-ዎች፣ ትላልቅUPDATEወይምDELETEstatement-ዎች፣ እና ከሚታወቅ infrastructure-ዎ ውጭ ካሉ IP-ዎች request-ዎችን ይፈልጉ። Supabase በእያንዳንዱ request ላይx-real-ipheader-ን ይመዘግባል። - Storage object-ዎችን ይፈትሹ። Storage → Logs ይጎብኙ እና የቅርብ ጊዜ file download-ዎችን ይገምግሙ። የተፈሰሰ service-role key ለprivate bucket-ዎችም bypass-everything access ይሰጣል።
- Key-ውን ከsource control ያስወግዱት። ከሮቴሽን በኋላም ቢሆን JWT-ን በgit history ውስጥ መተው በpublic repo ላይ ሊገኝ ይችላል ማለት ነው።
git filter-repoወይም BFG Repo-Cleaner ይጠቀሙ ከhistory ለማጽዳት፣ ከዚያም force-push ያድርጉ (collaborator-ዎችን አስቀድመው ያስታውቁ)። - ከfix በኋላ እንደገና scan ያድርጉ። በተደጋገመው app ላይ አዲስ FixVibe scan ያስኪዱ። የbundle-secrets finding መጥፋት አለበት። በማንኛውም chunk ውስጥ
service_roleJWT እናsb_secret_*string አለመቆየቱን ያረጋግጡ።
ስብርን በመጀመሪያ ቦታ መከላከል
Structural fix-ው naming discipline ጨምሮ tool-level guardrail ነው፦
- Service key-ን
NEXT_PUBLIC_*፣VITE_*፣ ወይም ሌላ ማንኛውም bundle-inlining prefix በፍጹም አይጨምሩ። Naming convention-ው ድንበሩ ነው — እያንዳንዱ framework ይከበራል። - Service key-ን በdeveloper ማሽን ላይ ከ
.envጨርሶ ያስቀምጡት። በdeploy ላይ ከsecret manager (Doppler፣ Infisical፣ Vercel encrypted env vars) ያንብቡት፣ በፍጹም በlocal ላይ commit አያድርጉ። - <strong>Mark every Supabase client construction with explicit context.</strong> Files named <code>supabase/browser.ts</code> use the anon key; files named <code>supabase/server.ts</code> use the service-role key with <code>import 'server-only'</code> at the top. The <code>server-only</code> import causes a build error if a client component tries to consume the module.
- <strong>Add a pre-commit hook that greps for JWT-shaped strings.</strong> <code>git diff --staged | grep -E 'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+'</code> catches both anon and service tokens before they leave your machine.
- Build output-ን የሚscan CI gate ይጨምሩ። ከ
next buildበኋላ የ.next/static/chunks/output ለservice_rolestring grep ያድርጉ። የሚዛመድ ነገር ካለ build-ውን fail ያድርጉ።
# Pre-commit hook: refuse any staged JWT-shaped string.
git diff --staged \
| grep -E 'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+' \
&& echo "JWT detected in staged changes — refusing commit" \
&& exit 1
# CI gate: fail the build if "service_role" shipped to the static bundle.
grep -RE 'service_role|sb_secret_' .next/static/chunks/ \
&& echo "Service-role credential leaked into bundle" \
&& exit 1ብዙ ጊዜ የሚጠየቁ ጥያቄዎች
Attacker-ዎች የተፈሰሱ Supabase service-role key-ዎችን ምን ያህል በፍጥነት ያገኛሉ?
Public-bundle scanner-ዎች አዲስ deployment-ዎችን በደቂቃዎች ውስጥ ይvar እያደረጉ ናቸው። ተመራማሪዎች ከመጀመሪያው deploy ጀምሮ ከአንድ ሰዓት ባነሰ ጊዜ ውስጥ በአዲስ Supabase project-ዎች ላይ የሚሰሩ exploit-ዎችን ሰነድ አድርገዋል። ማንኛውንም service-role exposure እንደ 60-ደቂቃ window አድርገው ይያዙት፣ እንደ 60-ቀን አይደለም።
Key-ውን ሮቴት ማድረግ በቂ ነው ወይም data exfiltration ግምት ላይ መውሰድ አለብኝ?
ሮቴሽን የተፈሰሰውን key invalidate ያደርጋል ግን ቀደም ሲል የተወሰደ data-ን ወደ ኋላ አያቀርብም። Table-ዎ PII፣ payment data ወይም ሌላ ማንኛውም regulated data ካለ፣ በGDPR (72 ሰዓት)፣ CCPA ወይም HIPAA ስር የማስታወቅ ግዴታ ሊኖርዎ ይችላል። Log-ዎችን audit ያድርጉ እና audit-ው አጠራጣሪ access ካሳየ legal counsel ያማክሩ።
Service-role key ቢፈስ RLS ይጠብቀኝ ይችላል?
አይ። Row-Level Security በservice_role claim ጨርሶ ይዘላል። ይህ በdesign ነው — key-ው ያለው admin operation-ዎች ላይ backend code RLS-ን እንዲዘል ለማስቻል ብቻ ነው። መፍትሄው key-ው attacker ሊያነበው ወደሚችል context በፍጹም እንዳይደርስ ማረጋገጥ ነው።
ይህ በአዲሱ Supabase publishable / secret key ሞዴል (<code>sb_publishable_</code> / <code>sb_secret_</code>) ላይ ይተገበራል?
አዎ — ተመሳሳይ risk class። የsb_secret_* key ለአዲሶቹ project-ዎች service-role JWT-ን የሚተካ አዲሱ secret-key format ነው። sb_secret_*-ን በbundle ውስጥ የያዘ ማንኛውም ነገር እንደተፈሰሰ service-role JWT አደገኛ ነው። የFixVibe bundle-secrets detector ሁለቱንም shape-ዎች ይዛመዳል።
ስለanon / publishable key-ስ — በbundle ውስጥ ደህና ነው?
አዎ፣ በdesign ነው። Anon key በbrowser ውስጥ እንዲቆይ የተደረገ ሲሆን፣ ይህ ሁሉም Supabase web client-ዎች የሚጠቀሙት ነው። ደህንነቱ በእያንዳንዱ public table ላይ RLS በትክክል ተዋቀረ መሆኑ ላይ ሙሉ በሙሉ ይታመናል። ምን መፈተሽ እንዳለበት ለማየት Supabase RLS scanner ጽሑፍ ይመልከቱ።
ቀጣይ እርምጃዎች
በproduction URL-ዎ ላይ FixVibe scan ያስኪዱ — የbundle-secrets check ነጻ፣ signup የለውም፣ እና ከአንድ ደቂቃ ባነሰ ጊዜ ውስጥ service_role exposure ይዘግባል። ይህን ከSupabase RLS scanner ጽሑፍ ጋር ያጋጩ RLS layer ሥራውን እያደረገ መሆኑን ለማረጋገጥ፣ እና ከSupabase storage bucket security checklist ጋር file access-ን ለመቆለፍ። AI tool-ዎች ይህን leak class ለምን በዚህ መልክ እንደሚፈጥሩ ምክንያት ለማወቅ AI coding tool-ዎች ለምን የደህንነት ክፍተት ይተዋሉ ያንብቡ።
