> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chappiesdk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Multiple ChatGPT Accounts in Your Swift App

> Use ChappieConfiguration to isolate Keychain credentials per user, share them across app extensions, and manage accessibility for background use cases.

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:)`:

```swift theme={null}
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.

<Warning>
  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.
</Warning>

***

## 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:

```swift theme={null}
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

| Parameter               | Type                           | Default                       | Description                                                                                       |
| ----------------------- | ------------------------------ | ----------------------------- | ------------------------------------------------------------------------------------------------- |
| `keychainService`       | `String`                       | `"com.chappie.sdk"`           | The Keychain service name; acts as a namespace for all Chappie items                              |
| `keychainAccount`       | `String`                       | `"default"`                   | The Keychain account name; set this to your app's user identifier to isolate credentials per user |
| `keychainAccessGroup`   | `String?`                      | `nil`                         | An optional access group for sharing credentials between your app and its extensions              |
| `keychainAccessibility` | `ChappieKeychainAccessibility` | `.whenUnlockedThisDeviceOnly` | Controls when the Keychain item is readable; see below                                            |
| `model`                 | `String`                       | SDK default                   | The ChatGPT model the client uses for requests                                                    |
| `harness`               | `ChappieHarness`               | `.default`                    | The assistant harness injected at the start of every conversation                                 |

### Putting it all together

```swift theme={null}
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:

| Value                             | When the item is readable                                                                   |
| --------------------------------- | ------------------------------------------------------------------------------------------- |
| `.whenUnlockedThisDeviceOnly`     | Only while the device is unlocked; item does not migrate to other devices via iCloud backup |
| `.afterFirstUnlockThisDeviceOnly` | After the device has been unlocked at least once since boot; allows background access       |

<Tip>
  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.
</Tip>

***

## 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:

```swift theme={null}
// 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.

***

<Note>
  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.
</Note>

***

## 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:

```swift theme={null}
@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
    }
}
```

<CardGroup cols={2}>
  <Card title="Auth Overview" icon="key" href="/authentication/overview">
    Understand the full auth lifecycle, state machine, and error types.
  </Card>

  <Card title="Sign-In Button" icon="person.badge.plus" href="/authentication/sign-in-button">
    Add a ready-made sign-in button to your SwiftUI views.
  </Card>
</CardGroup>
