ModelEngine-Group / ModelEngine-Group/nexent
SERVICE_ROLE_KEY silently falls back to SUPABASE_KEY — privilege boundary erased
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5.9k
- Forks
- 731
- Avg merge
- 19h 34m
- Merged PRs (30d)
- 172
Description
In backend/consts/const.py:74:
SUPABASE_URL = os.getenv('SUPABASE_URL')
SUPABASE_KEY = os.getenv('SUPABASE_KEY')
SERVICE_ROLE_KEY = os.getenv('SERVICE_ROLE_KEY', SUPABASE_KEY)
The fallback is dangerous in either direction:
- If
SERVICE_ROLE_KEYis unset (a common config mistake), the anon key is used for admin operations — meaning everything that callsget_supabase_admin_client()(backend/utils/auth_utils.py:240) will silently fall back to anon-level access. RLS-protected operations will mysteriously fail, often with cryptic 401s buried inside service code. - If only
SERVICE_ROLE_KEYis set (e.g. a developer setting up locally and not realising they need both),SUPABASE_KEYisNone, butSERVICE_ROLE_KEYis now anchored to the actually-set value. Thenget_supabase_client()(line 232) tries to create a client withkey=Noneandcreate_clientraises.
The two keys carry fundamentally different privileges in Supabase — the anon key is intended to be public-readable, the service role key bypasses RLS. Conflating them via a silent default is exactly the kind of mistake that's easy to ship and hard to find in production.
Suggested fix
SUPABASE_KEY = os.getenv('SUPABASE_KEY')
SERVICE_ROLE_KEY = os.getenv('SERVICE_ROLE_KEY')
if SERVICE_ROLE_KEY is None:
# Don't silently fall back to the anon key — that erases the privilege boundary.
# In speed/demo mode it's fine to be unset; admin clients will refuse to construct.
logger.warning("SERVICE_ROLE_KEY is not configured; admin-scoped Supabase operations will fail")
…and have get_supabase_admin_client raise a clear RuntimeError (or domain exception) when called with SERVICE_ROLE_KEY is None, instead of create_client failing inside a generic except.
Category: H (security hardening). Severity: High.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with backend/consts/const.py:74 and trace the clients in backend/utils/auth_utils.py at lines 232 and 240. Verify the behavior when either key is unset and identify the existing exception handling around admin client creation. Done means the two keys remain distinct and an unset SERVICE_ROLE_KEY produces a clear admin-client failure rather than silently falling back or failing generically.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, supabase
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100