Configure Authentication in Palmier Pro: Clerk, Convex, and AccountService Setup

Palmier Pro authenticates users via Clerk OAuth (Google) and Convex backend services, requiring three Info.plist keys and initialization through the AccountService singleton to enable AI features and credit management.

Palmier Pro integrates Clerk for identity management and Convex for real-time user data persistence. To configure authentication in Palmier Pro, developers must supply backend credentials in the app's Info.plist, initialize the central AccountService, and implement the OAuth flow. This guide covers the complete implementation based on the palmier-io/palmier-pro repository.

Supply Backend Credentials in Info.plist

The authentication stack requires three environment-specific keys stored in your target's Info.plist. According to Sources/PalmierPro/Account/BackendConfig.swift, the BackendConfig struct reads these values at runtime:

  • PalmierClerkPublishableKey: Your Clerk publishable key for OAuth initialization.
  • PalmierConvexDeploymentURL: The Convex WebSocket URL for real-time auth state.
  • PalmierConvexHttpURL: The Convex HTTP endpoint for AI client requests.

If any key is missing, AccountService.isMisconfigured returns true and AI features are automatically disabled.

<!-- Add to Info.plist -->
<key>PalmierClerkPublishableKey</key>
<string>pk_test_...</string>
<key>PalmierConvexDeploymentURL</key>
<string>https://my-deployment.convex.cloud</string>
<key>PalmierConvexHttpURL</key>
<string>https://my-deployment.convex.cloud</string>

Initialize the AccountService

The AccountService singleton acts as the central coordinator for authentication. In Sources/PalmierPro/App/main.swift, the system calls AccountService.shared.configure() at launch to wire Clerk and Convex together.

The configure() method performs three critical operations:

  1. Configures Clerk with the publishable key from BackendConfig.
  2. Instantiates a ConvexClientWithAuth using ClerkConvexAuthProvider to automatically inject Clerk JWT tokens into Convex requests.
  3. Starts startAuthObservation() to monitor the Convex auth state stream and startAccountSubscription() to fetch the user record via the account:get query.
import PalmierPro

// Called automatically at application launch
AccountService.shared.configure()

Implement Google OAuth Sign-In

UI components bind to AccountService.shared to trigger authentication. When a user initiates sign-in, the app calls signInWithGoogle(), which executes Clerk.shared.auth.signInWithOAuth(provider: .google).

Upon successful OAuth completion, the Convex subscription automatically invokes the users:upsertFromAuth mutation to create or update the user document in the backend.

// Trigger Google OAuth from your UI
Task {
    await AccountService.shared.signInWithGoogle()
}

Monitor Authentication State and Credits

The AccountService exposes UI-friendly flags that drive feature availability. The startAuthObservation() method updates authState through three phases: loading, authenticated, and unauthenticated.

After authentication, startAccountSubscription() maintains a live connection to the account:get query, exposing isSignedIn, remainingCredits, and hasCredits. Views like GenerationView read these values to enable AI generation and display credit warnings.

// Check authentication and credits before AI operations
if AccountService.shared.isSignedIn && AccountService.shared.hasCredits {
    // Proceed with AI generation
} else {
    // Present sign-in or purchase UI
}

Enforce Authentication in Network Clients

Low-level clients enforce authentication at the network layer. In Sources/PalmierPro/Agent/Clients/PalmierClient.swift, requests check the Clerk session and throw PalmierClientError.unauthenticated if the JWT is missing or invalid.

This ensures that AI generation requests and credit purchases cannot proceed without valid credentials, even if UI guards are bypassed.

// Sign out from settings
Task {
    await AccountService.shared.signOut()
}

Key Source Files for Authentication

Summary

  • Add three keys to Info.plist: PalmierClerkPublishableKey, PalmierConvexDeploymentURL, and PalmierConvexHttpURL.
  • Call AccountService.shared.configure() at launch to initialize Clerk and Convex.
  • Use signInWithGoogle() to initiate OAuth and automatically sync user data via users:upsertFromAuth.
  • Check isSignedIn and hasCredits before enabling AI features.
  • The PalmierClient enforces authentication at the network layer by validating Clerk sessions.

Frequently Asked Questions

What keys are required to configure authentication in Palmier Pro?

You must provide PalmierClerkPublishableKey, PalmierConvexDeploymentURL, and PalmierConvexHttpURL in your Info.plist. These are read by BackendConfig in Sources/PalmierPro/Account/BackendConfig.swift to initialize the Clerk and Convex clients.

How does Palmier Pro handle unauthenticated users?

The AccountService exposes an isSignedIn flag that disables AI features when false. Additionally, PalmierClient throws PalmierClientError.unauthenticated if requests are made without a valid Clerk JWT, preventing unauthorized access to backend resources.

Can I use authentication providers other than Google?

The current implementation in Sources/PalmierPro/Account/AccountService.swift specifically implements signInWithGoogle() using Clerk.shared.auth.signInWithOAuth(provider: .google). While Clerk supports multiple OAuth providers, you would need to extend AccountService to support additional providers like Apple or GitHub.

Where is the authentication state managed in the codebase?

Authentication state is managed by the AccountService singleton in Sources/PalmierPro/Account/AccountService.swift. It observes the Clerk session through startAuthObservation() and syncs user data via startAccountSubscription(), exposing reactive properties like authState, remainingCredits, and isSignedIn to the UI.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →