Protect Supabase Service Role Key in Expo
Privileged Supabase reads for Expo without service_role on device
The Supabase service_role key bypasses row level security, so it must never appear in an Expo app or OTA update. Keep the anon key in the app for normal queries and send privileged reads to a RealComposer pipeline that holds service_role in the vault and returns filtered fields.
Why service_role keys must stay off Expo devices
Some features, such as leaderboards or admin counts, need queries that row level security would block. Putting service_role in the app solves it quickly but hands every user full read and write access to the database.
- Full database access from a key extracted from the bundle
- Row level security bypassed for every client
- Rotation requiring a forced app update
How RealComposer Solves This at the Edge
Store credentials in Secret Vault
Save SUPABASE_SERVICE_ROLE_KEY in RealComposer so the value never enters the Expo project.
Configure the edge pipeline
Add the upstream steps with vault header injection, set allowed origins, and map only the fields the screen binds.
Fetch privileged data from Expo
Call your workspace edge URL with a restricted rc_live_ client token.
const res = await fetch('https://realcomposer.com/v1/workspace/protect-supabase-service-role-key-expo', {
headers: { Authorization: 'Bearer rc_live_client_token' },
});
const { leaders } = await res.json();
[
{
"display_name": "ada",
"points": 980,
"user_id": "u_1"
},
{
"display_name": "grace",
"points": 940,
"user_id": "u_2"
},
{
"display_name": "linus",
"points": 910,
"user_id": "u_3"
}
]
{
"leaders": [
{
"name": "ada",
"points": 980
},
{
"name": "grace",
"points": 940
},
{
"name": "linus",
"points": 910
}
]
}
Recipe Specs
- HTTP method
- GET
- Upstream calls
- 1
- Edge cache TTL
- 60s
- Client auth
- Restricted client token
- Mapped output fields
- 6
- Payload
- 161 B to 101 B (-37%)
curl -X GET "https://realcomposer.com/v1/workspace/protect-supabase-service-role-key-expo" \ -H "Authorization: Bearer rc_live_client_token"
Developer Questions & Troubleshooting
Is the Supabase anon key safe in Expo?
Yes, when row level security is enabled on every table. The anon key is designed to be public; service_role is not.
Why cache the leaderboard for 60 seconds?
Every user sees the same top three, so a short edge cache serves thousands of requests from one Supabase query.
Sources & Definitions Used in This Answer
Deploy this Expo + Supabase Recipe
Clone this pre-configured pipeline into your RealComposer workspace in one click. We pre-populate upstream URLs, headers, and mapping rules.