Skip to main content
By default, Chappie stores credentials under a single Keychain slot shared by all users of your app. If your app has its own user account system — or needs to let the same device support multiple ChatGPT identities — you can give each user a dedicated Keychain slot by passing a ChappieConfiguration with a distinct keychainAccount value. The SDK stores and retrieves credentials independently for each account string, so sessions never bleed across users.

One configuration per user

Create a ChappieConfiguration keyed to your app’s current user identifier, then pass it to both Chappie.authSession(configuration:) and Chappie.client(configuration:):
let config = ChappieConfiguration(
    keychainAccount: currentUser.id
)

let authSession = Chappie.authSession(configuration: config)
let client = Chappie.client(configuration: config)
When the user signs out of your app, call authSession.signOut() to remove their ChatGPT credential from Keychain. The credential is stored under their keychainAccount key and does not affect any other user’s session.
The auth session and client must use the same ChappieConfiguration value to share credentials. If they use different configurations, the client cannot find the credential that the auth session stored and every request will fail with an authentication error.

Sharing credentials across app extensions

If your app and a widget, share extension, or app clip need access to the same ChatGPT credential, add a Keychain Access Groups entitlement to your targets and set keychainAccessGroup in the configuration:
let config = ChappieConfiguration(
    keychainAccount: currentUser.id,
    keychainAccessGroup: "TEAMID.com.example.shared"
)

let authSession = Chappie.authSession(configuration: config)
let client = Chappie.client(configuration: config)
Replace TEAMID with your Apple Developer team identifier and com.example.shared with the access group name declared in your entitlements file. All targets that share this access group can read and write the same Keychain item.

ChappieConfiguration parameters

ParameterTypeDefaultDescription
keychainServiceString"com.chappie.sdk"The Keychain service name; acts as a namespace for all Chappie items
keychainAccountString"default"The Keychain account name; set this to your app’s user identifier to isolate credentials per user
keychainAccessGroupString?nilAn optional access group for sharing credentials between your app and its extensions
keychainAccessibilityChappieKeychainAccessibility.whenUnlockedThisDeviceOnlyControls when the Keychain item is readable; see below
modelStringSDK defaultThe ChatGPT model the client uses for requests
harnessChappieHarness.defaultThe assistant harness injected at the start of every conversation

Putting it all together

let config = ChappieConfiguration(
    keychainService: "com.example.myapp",
    keychainAccount: currentUser.id,
    keychainAccessGroup: "TEAMID.com.example.shared",
    keychainAccessibility: .whenUnlockedThisDeviceOnly
)

Keychain accessibility

The keychainAccessibility setting determines when the operating system allows your app to read the stored credential:
ValueWhen the item is readable
.whenUnlockedThisDeviceOnlyOnly while the device is unlocked; item does not migrate to other devices via iCloud backup
.afterFirstUnlockThisDeviceOnlyAfter the device has been unlocked at least once since boot; allows background access
Keep the default .whenUnlockedThisDeviceOnly unless your app genuinely needs to access ChatGPT credentials from a background task or extension that runs before the user has unlocked the device. The narrower accessibility is more secure because it prevents credential access during the window between device boot and first unlock.

Switching between accounts at runtime

Because each configuration is independent, you can hold multiple auth sessions in memory and switch between them as your app’s current user changes:
// At login time
let config = ChappieConfiguration(keychainAccount: user.id)
self.authSession = Chappie.authSession(configuration: config)
self.client = Chappie.client(configuration: config)

// At logout time — clear only this user's credential
authSession.signOut()
Each call to Chappie.authSession(configuration:) creates a new, independent session object. It reads from Keychain at init time, so a returning user is signed in automatically without any additional sign-in steps.
Raw access and refresh tokens are never exposed through Chappie’s public API. ChappieAccountInfo provides only identity metadata — email, user ID, account ID, and plan — derived from the stored credential. Chappie is an in-process SDK, not a server-side token vault; treat it accordingly when designing your app’s trust model.

Example: multi-user app

The following example wires a UserSession observable to a ChappieAuthSession so that signing in or out of your app automatically creates or destroys the corresponding ChatGPT session:
@MainActor
final class UserSession: ObservableObject {
    @Published private(set) var authSession: ChappieAuthSession?
    @Published private(set) var client: ChappieClient?

    func signIn(as user: AppUser) {
        let config = ChappieConfiguration(keychainAccount: user.id)
        authSession = Chappie.authSession(configuration: config)
        client = Chappie.client(configuration: config)
    }

    func signOut() {
        authSession?.signOut()
        authSession = nil
        client = nil
    }
}

Auth Overview

Understand the full auth lifecycle, state machine, and error types.

Sign-In Button

Add a ready-made sign-in button to your SwiftUI views.