feat: add Supabase Edge Function secrets sync - #1014
Open
rohan-chaturvedi wants to merge 1 commit into
Open
Conversation
nimish-ks
self-requested a review
September 9, 2026 07:20
rohan-chaturvedi
marked this pull request as ready for review
September 9, 2026 09:03
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔍 Overview
Phase currently supports syncing secrets to 11 third-party services (GitHub Actions, Railway, Vercel, Render, Cloudflare, etc.), but there is no integration for Supabase. Supabase Edge Functions consume secrets set on a project via the Supabase Management API, and teams using Phase as their source of truth currently have to copy secrets over manually or script the
supabaseCLI.This PR adds Supabase Edge Function secrets as a first-class sync integration, following the same provider pattern as the existing token-credential integrations (Cloudflare Workers / Railway).
Fixes #1013
💡 Proposed Changes
Backend
supabaseprovider (singleaccess_tokencredential — a Supabase personal access token) andsupabase_edge_functionsservice in the provider registry (api/services.py)api/utils/syncing/supabase/main.py:list_supabase_projects— lists projects viaGET /v1/projects, sourcing the project ref from the documentedreffield (with fallback to the deprecatedid)sync_supabase_secrets— authoritative sync: fetches remote secret names, deletes remote secrets no longer present in Phase, then bulk-upserts all Phase secrets viaPOST /v1/projects/{ref}/secretsSUPABASE_-prefixed names are never deleted remotely, andSUPABASE_-prefixed Phase keys are skipped on push (the API rejects them); skipped keys are reported in the sync event messageperform_supabase_sync+SERVICE_DISPATCHentry (api/tasks/syncing.py)supabaseProjects(credentialId)query (gated onIntegrationCredentials:read+ provider check) andcreateSupabaseSyncmutation with the same credential-org,sse_enabled, app-access, and duplicate-sync checks as sibling providers; sync options storeproject_ref+project_name0140_supabase_sync_choices— validation-onlyAlterFieldpair for the new provider/service choices (no DB schema change)Frontend
CreateSupabaseSyncsetup component (credential → Phase env/path → project combobox showing name, ref and region), wired intoCreateSyncDialogProviderIcon(Supabase logo),ServiceInfo(project name + ref on sync cards)graphql/{queries,mutations}/syncing/supabase/, regenerated schema + codegen typesACCESS TOKENfield automatically)🖼️ Screenshots or Demo
📝 Release Notes
❓ Open Questions
docs.phase.dev/integrations/platforms/supabasepage needs to land inphasehq/docsalongside this.🧪 Testing
backend/tests/utils/syncing/test_supabase.pycovering project listing (success / bad credentials / API error /reffallback) and sync semantics (stale deletion, reserved-prefix skipping on both delete and push, 100-item batching, and error paths for fetch/delete/create)test_file_read_permission_errorbaseline)tsc --noEmitclean vs the main baseline, ESLint clean on all touched components, jest fully green🎯 Reviewer Focus
backend/api/utils/syncing/supabase/main.py— the delete-then-upsert semantics and the reserved-prefix handlingCreateSupabaseSyncmutation inbackend/backend/graphene/mutations/syncing.py— authz checks mirrorCreateCloudflareWorkersSync/CreateRailwaySyncfrontend/components/syncing/Supabase/CreateSupabaseSync.tsx— mirrorsCreateCloudflareWorkersSync➕ Additional Context
frontend/apollo/schema.graphqlincludes a few non-Supabase docstring hunks (email-change mutations): the checked-in schema was stale relative tomain's backend, and this export refreshes it.get_environment_secretspath used by all providers.✨ How to Test the Changes Locally
python manage.py migratein the backend container)supabase secrets list --project-ref <ref>(or Dashboard → Edge Functions → Secrets); delete a secret in Phase, redeploy, and confirm it's removed remotelySUPABASE_URLetc. are untouched, and a Phase key namedSUPABASE_Xis skipped with a note in the sync event message💚 Did You...