Skip to main content
Chappie is a pure in-process Swift SDK — credentials and conversation data stay on the user’s device. There is no intermediate Chappie proxy server. Requests travel directly from the user’s device to the ChatGPT/Codex backend, and credentials are stored only in the device Keychain.

Trust boundary

Chappie connects directly from the user’s device to the ChatGPT/Codex backend using credentials that the user established through the OAuth device flow. There is no Chappie cloud service, no relay, and no server-side credential custody. This means:
  • Credential refresh happens on-device without any Chappie intermediary.
  • Conversation content is never routed through Chappie infrastructure.
  • Your users’ ChatGPT credentials never leave the device (unless the user opts in to iCloud Keychain sync, which the default accessibility level prevents).
A pure in-process SDK cannot make credentials impossible for a hostile host app to obtain. The SDK runs inside the host app process and uses the host app’s Keychain entitlement context. Keychain storage prevents accidental leakage and protects against other apps, but it is not a trust boundary between an app and a framework loaded inside that app.

What Chappie does not expose

Chappie’s public API never surfaces raw OAuth tokens, refresh tokens, ID tokens, or authorization headers to host app code. The two primary SDK objects expose only safe, derived data:
ObjectWhat it exposes
ChappieAuthSessionAuth state enum (.signedIn, .signedOut, etc.) and ChappieAccountInfo (email, user ID, account ID, plan)
ChappieClientResponse text, streaming events, usage limits, model list, account metadata
This design prevents accidental logging or network transmission of bearer-token material through app code.

Credential refresh and reauthentication

Chappie refreshes expired tokens automatically before every request and retries once on an unexpected 401 after refreshing. Your app never needs to manage token refresh manually. When Chappie cannot refresh silently — because the refresh token is missing, or the token endpoint returns 400, 401, or 403 — it surfaces the ChappieAuthState.reauthenticationRequired state on the auth session. Handle this state by showing your sign-in UI:
switch authSession.state {
case .reauthenticationRequired:
    showSignInSheet()
default:
    break
}
The corresponding error type is ChappieAuthError with requiresReauthentication == true for .missingRefreshToken and .tokenExchangeFailed with those status codes.

Keychain storage

Credentials are stored as a generic-password Keychain item with the following defaults:
  • Accessibility: kSecAttrAccessibleWhenUnlockedThisDeviceOnly — the item is readable only while the device is unlocked and never migrates to another device, iCloud Keychain, or a backup.
  • Service: "com.chappie.sdk" — change this to your own reverse-DNS identifier via ChappieConfiguration.keychainService.
Apps that need background credential access can opt in to ChappieKeychainAccessibility.afterFirstUnlockThisDeviceOnly, but foreground-only apps should keep the default.

Privacy manifest

The SDK bundles PrivacyInfo.xcprivacy inside the ChappieSDK package target. It declares:
  • Collected data type: Linked account identifiers and email, used for app functionality.
  • Tracking: None. No tracking domains are declared.
Review the manifest before App Store distribution and update it if your integration of the SDK introduces additional data collection or uses required-reason APIs.

Transcript storage (ChappieSDKRuntime)

ChappieFileThreadStore persists complete ChappieThread JSON to the app support directory. That JSON can contain user input text, assistant output text, tool-call argument payloads, tool outputs, raw API payloads, runtime errors, and compaction summaries. The file store does not redact or classify content. The default storage policy applies these filesystem controls automatically:
1

Backup exclusion

Transcript directories and JSON files are excluded from iCloud and iTunes device backups.
2

iOS file protection

Transcript directories and files use NSFileProtectionComplete on iOS, so they are inaccessible while the device is locked.
3

macOS sandbox

On macOS, Chappie relies on the app sandbox and platform filesystem protections. There is no macOS equivalent to iOS Data Protection classes.
If your app should not persist specific fields (for example, sensitive tool arguments or PII in user messages), redact those fields before saving or implement a custom ChappieThreadStore that filters content at write time. Apps that need to read transcripts in the background before the device is unlocked can choose a less restrictive file-protection level:
import ChappieSDKRuntime

let store = ChappieFileThreadStore(
    storagePolicy: ChappieFileThreadStoreStoragePolicy(
        fileProtection: .completeUntilFirstUserAuthentication
    )
)

Harness guardrail

The default ChappieHarness.default includes system instructions that prevent the model from presenting itself as the Codex desktop app or other Codex surfaces. This keeps the assistant clearly scoped to your app’s context and avoids product boundary confusion for users.

Product boundary

Chappie’s product shape is an in-app harness for interacting with OpenAI/ChatGPT directly. It is not a local Codex Desktop control-plane client, a JSON-RPC app-server, or a third-party proxy API. Apps that need server-side custody of OpenAI credentials should build that as a separate backend product outside the SDK.

Production hardening checklist

Keep default Keychain accessibility

Use .whenUnlockedThisDeviceOnly unless you have a confirmed background-access requirement. It prevents credential migration and restricts readability to foreground contexts.

Link ChappieSDKRuntime only if needed

ChappieSDKRuntime adds file-backed transcript storage. If your app does not need durable conversation history, omit it to reduce your attack surface.

Redact before storing

If you use a custom ChappieThreadStore or inspect thread JSON, redact PII and sensitive tool arguments before they reach persistent storage.

Use distinct Keychain accounts

For multi-user apps, pass a stable per-user identifier as keychainAccount in ChappieConfiguration. Shared slots allow one user’s credentials to overwrite another’s.