Guide

How to Add Authentication to a SwiftUI App with Supabase

Wire up Supabase auth and Sign in with Apple in a SwiftUI app from zero — sessions, keychain persistence, and a server-side identity you can actually build on. Do it by hand, or skip the plumbing with The Swift Kit.

Last updated: 2026-06-09 6 min read By Ahmed Gagan, iOS Engineer
Quick Answer

To add authentication to a SwiftUI app, the cleanest 2026 path is Supabase for the backend (Postgres-backed user table, session management, JWTs) plus Sign in with Apple as the native provider Apple requires when you ship any third-party login. You add the supabase-swift SDK, configure the Apple provider in the Supabase dashboard, present an ASAuthorizationAppleIDButton, and exchange the returned Apple identity token for a Supabase session that persists in the keychain. The Swift Kit ships this exact stack pre-wired so the auth gate, session restore, and RevenueCat user identity link work on first launch.

Backend
Supabase (Postgres + auth + JWT sessions)
Native provider
Sign in with Apple (required by App Store if you offer any third-party login)
Key safety
API keys proxied via Supabase Edge Functions, never shipped in the binary

Why Supabase + Sign in with Apple specifically

There are a dozen ways to add login to iOS — Firebase Auth, raw StoreKit-adjacent identity hacks, your own server. The reason this guide picks Supabase plus Sign in with Apple is App Store reality, not preference. Apple's guideline 4.8 requires that if you offer any third-party or social login, you must also offer Sign in with Apple as an equivalent option, or risk rejection. Starting from Apple as your first provider sidesteps that entirely. Supabase then gives you a real Postgres row for every user the moment they authenticate, so the same identity powers your database row-level security, file storage, and Edge Functions without a second identity system to reconcile. The trade-off: Supabase is a hosted dependency you do not control, and Sign in with Apple's private-relay emails mean you cannot assume you have a real address for marketing. Both are acceptable for most indie apps; neither is free of lock-in.

  • Sign in with Apple satisfies App Store guideline 4.8 from day one
  • One Supabase user ID keys auth, DB, storage, and Edge Functions
  • Private-relay emails are a real limitation for email marketing

The honest cost of doing it by hand

Every step above is doable in an afternoon if everything goes right. It rarely does. The Apple provider needs a Services ID, a Key ID, a Team ID, and a .p8 key entered correctly in two systems — a single mismatched field gives you a token-exchange failure with no useful error. Session restore has to win the race against your first view or users see a login flash. And the part nobody warns you about: wiring the same user identity into RevenueCat so entitlements survive reinstalls and device changes. The Swift Kit ships all of this behind a feature flag — auth, keychain session persistence, the Apple button, and the RevenueCat identity link are pre-wired and verified in the simulator, configured through the interactive ./setup.sh CLI. You are paying $99 once to delete the two days where this stack quietly does not work and you cannot tell why.

Add Supabase + Sign in with Apple to SwiftUI, step by step

Here is the from-zero path. Each step is real work you would do by hand; The Swift Kit collapses all seven into a single ./setup.sh run and a feature flag.

  1. 1

    Create a Supabase project and grab your keys

    Spin up a free Supabase project. Copy the project URL and the anon (public) key from Settings → API. The anon key is safe to ship; the service-role key is not and must stay server-side in Edge Functions.

    # .env or a config you never commit
    SUPABASE_URL=https://YOUR-REF.supabase.co
    SUPABASE_ANON_KEY=eyJhbGciOi...
  2. 2

    Add the supabase-swift package

    Add the official Swift SDK via Swift Package Manager. It gives you the auth client, session storage, and Postgres access from one dependency.

    // Package.swift dependency
    .package(url: "https://github.com/supabase/supabase-swift", from: "2.0.0")
  3. 3

    Enable Sign in with Apple in two places

    In Xcode, add the Sign in with Apple capability to your target. In the Supabase dashboard under Authentication → Providers, enable Apple and paste your Services ID, Team ID, Key ID, and the .p8 private key. Both halves must match or the token exchange fails silently.

  4. 4

    Initialize a single shared client

    Create one SupabaseClient for the whole app. It auto-persists the session to the keychain, so a returning user is already signed in on the next cold launch.

    import Supabase
    
    let supabase = SupabaseClient(
      supabaseURL: URL(string: Config.supabaseURL)!,
      supabaseKey: Config.supabaseAnonKey
    )
  5. 5

    Present the Apple button and exchange the token

    Show SignInWithAppleButton, take the identity token Apple returns, and hand it to Supabase. Supabase verifies it and mints its own session — now you have one user identity across auth, database, and storage.

    import AuthenticationServices
    
    SignInWithAppleButton(.signIn) { req in
      req.requestedScopes = [.fullName, .email]
    } onCompletion: { result in
      guard case let .success(auth) = result,
            let cred = auth.credential as? ASAuthorizationAppleIDCredential,
            let token = cred.identityToken,
            let idToken = String(data: token, encoding: .utf8) else { return }
      Task {
        try await supabase.auth.signInWithIdToken(
          credentials: .init(provider: .apple, idToken: idToken)
        )
      }
    }
  6. 6

    Gate your UI on session state

    Observe the auth state and route between your login screen and the app. Restore the session on launch so the gate resolves before the first frame instead of flashing the login screen.

    @MainActor final class AuthModel: ObservableObject {
      @Published var session: Session?
      func bootstrap() async {
        for await (event, session) in supabase.auth.authStateChanges {
          if [.initialSession, .signedIn, .signedOut].contains(event) {
            self.session = session
          }
        }
      }
    }
  7. 7

    Link identity to your other services

    Use the Supabase user ID as the stable key for RevenueCat (entitlements follow the person, not the device) and TelemetryDeck. This is the step most tutorials skip and the one that breaks restores and analytics later.

Frequently Asked Questions

Do I have to add Sign in with Apple, or can I just use email login?
Email-only is fine on its own. But the moment you add any third-party login (Google, Facebook, etc.), App Store guideline 4.8 requires you to also offer Sign in with Apple as an equivalent option. Starting with Apple as your first provider avoids a rejection later. Supabase supports both email/password and Apple, so The Swift Kit ships both.
Why exchange the Apple identity token with Supabase instead of just using ASAuthorization directly?
ASAuthorization only proves the user signed in with Apple on this device. It does not give you a server-side user record, a session you can validate from an Edge Function, or row-level database security. Handing the identity token to Supabase via signInWithIdToken mints a real backend session and a Postgres user row, which is what you actually need to build a multi-device app.
Is the anon key safe to ship inside my app?
Yes. The Supabase anon (public) key is designed to live in the client and is protected by row-level security policies you define. The service-role key is the dangerous one and must never ship in the binary. In The Swift Kit, any privileged operation and all AI provider keys are proxied through Supabase Edge Functions so secrets stay server-side.
How does authentication tie into payments and entitlements?
You use the Supabase user ID as the appUserID for RevenueCat. That way a subscription follows the person across reinstalls and devices instead of being stranded on one device. This identity link is the step most tutorials omit; The Swift Kit wires it for you. See the paywall guide for the RevenueCat side.
What does The Swift Kit save me versus following this guide manually?
The manual path is roughly two focused days once you account for the Apple provider configuration across two systems, session-restore timing, keychain persistence, and the RevenueCat identity link. The Swift Kit ships all of it behind a feature flag, configured through ./setup.sh and verified in the simulator. It is a $99 one-time purchase with lifetime updates and a 14-day refund.

Keep exploring

Skip the auth plumbing

Supabase auth, Sign in with Apple, keychain sessions, and the RevenueCat identity link are pre-wired and simulator-verified in The Swift Kit. $99 one-time, lifetime updates, 14-day refund. Configure it in one ./setup.sh run.

Get The Swift Kit — $99

One-time purchase · Lifetime updates · 14-day refund