Skip to content

security(#228): replace x-api-key on sporty-sync with Supabase JWT - #243

Merged
ChristopherRotnes merged 2 commits into
masterfrom
security/228-sporty-sync-jwt-auth
May 15, 2026
Merged

ChristopherRotnes merged 2 commits into
masterfrom
security/228-sporty-sync-jwt-auth

Conversation

@ChristopherRotnes

@ChristopherRotnes ChristopherRotnes commented May 15, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Replaces the x-api-key / VITE_SPORTY_SYNC_API_KEY auth pattern on POST /api/sporty-sync with the same Supabase JWT verification already used by /api/claude
  • JWT is sent in X-Supabase-Token (Azure SWA hijacks the Authorization header — this is a documented pitfall in CLAUDE.md)
  • Home.jsx DEV sync button now fetches the Supabase session and sends the token — no more VITE_ env var needed in the frontend
  • /api/sporty-health monitoring endpoint retains x-api-key (external monitoring tool, not frontend)
  • local.settings.json.example updated with a note clarifying SPORTY_SYNC_API_KEY is health-endpoint-only

Test plan

  • Verify all 82 tests still pass (npm test)
  • Start local dev (swa start), trigger sync with DEV button — should succeed with a valid session
  • Verify that calling POST /api/sporty-sync without a JWT returns 401
  • Verify GET /api/sporty-health still requires x-api-key (unchanged)

Closes #228

🤖 Generated with Claude Code

…se JWT

The POST /api/sporty-sync HTTP trigger was authenticated via a shared
x-api-key checked against SPORTY_SYNC_API_KEY. While VITE_SPORTY_SYNC_API_KEY
was not in CI secrets, the pattern was fragile and the key could leak if
accidentally added. The /api/claude endpoint already handles this correctly
with verifySupabaseJwt + X-Supabase-Token; this commit applies the same
pattern to the sporty-sync trigger.

The /api/sporty-health monitoring endpoint retains x-api-key — it is only
called by external monitoring tools, never by the frontend.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@supabase

supabase Bot commented May 15, 2026 •

Copy link
Copy Markdown

Updates to Preview Branch (security/228-sporty-sync-jwt-auth) ↗︎

Deployments Status Updated
Database ✅ Fri, 15 May 2026 20:54:24 UTC
Services ✅ Fri, 15 May 2026 20:54:24 UTC
APIs ✅ Fri, 15 May 2026 20:54:24 UTC

Tasks are run on every commit but only new migration files are pushed.
Close and reopen this PR if you want to apply changes from existing seed or migration files.

Tasks Status Updated
Configurations ✅ Fri, 15 May 2026 20:54:25 UTC
Migrations ❌ Fri, 15 May 2026 20:54:26 UTC
Seeding ⏸️ Fri, 15 May 2026 20:54:19 UTC
Edge Functions ⏸️ Fri, 15 May 2026 20:54:19 UTC

❌ Branch Error • Fri, 15 May 2026 20:54:26 UTC

ERROR: relation "session_templates" does not exist (SQLSTATE 42P01)
At statement: 0
-- Sprint 3: add template_type to session_templates
-- Nullable, no default — existing rows keep null (treated as unset in UI).
ALTER TABLE session_templates ADD COLUMN template_type text

View logs for this Workflow Run ↗︎.
Learn more about Supabase for Git ↗︎.

Keep both imports: verifySupabaseJwt from claudeUtils.js (this branch)
and normalizeName from sportyUtils.js (merged from master).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://white-island-090dfd003-243.westeurope.7.azurestaticapps.net

@ChristopherRotnes
ChristopherRotnes merged commit ab7e2b6 into master May 15, 2026
2 of 3 checks passed
@ChristopherRotnes
ChristopherRotnes deleted the security/228-sporty-sync-jwt-auth branch May 15, 2026 20:57

This branch was previously deployed

1 inactive deployment
preview — 04f9bb14 Deployed May 15, 2026 by ChristopherRotnes via Build and deploy #7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

As a developer I want the sporty-sync endpoint to use JWT auth so I can remove the shared API key from the frontend bundle

1 participant