# Use iCloud Keychain for Approved Account Actions

Canonical: https://figment.so/icloud-keychain-api

Keychain Services gives a macOS app access to items allowed by its keychain access groups and item controls. Apple's supported third-party iCloud authorization covers Mail, Calendar, and Contacts. Apple offers system-mediated credential flows for specific app logins and transfers. Figment offers no public Keychain connector. [Apple's Keychain technote](https://developer.apple.com/documentation/technotes/tn3137-on-mac-keychains) · [Apple's iCloud account authorization guide](https://support.apple.com/en-us/121539)

## What iCloud Keychain stores

iCloud Keychain syncs passwords, passkeys, credit card numbers, and Wi-Fi credentials across a user's approved Apple devices ([Apple Support](https://support.apple.com/en-us/120758)). Enabling it requires turning on **Passwords & Keychain** in iCloud Settings on each device; a new device must be approved by an already-trusted device or the account passcode before it receives the synced keychain. The Passwords app — available starting with iOS 18, iPadOS 18, macOS Sequoia, and visionOS 2 — provides the user-facing view of this store. That app exists for the user; it is not a third-party API surface.

## How Apple restricts access

Keychain access rules depend on which of macOS's two keychain implementations you are targeting.

**Two implementations on macOS.** macOS has a file-based keychain and a data-protection keychain ([TN3137](https://developer.apple.com/documentation/technotes/tn3137-on-mac-keychains)). These two implementations use entirely different access control models. The data-protection keychain — which iCloud Keychain requires — uses keychain access groups derived from code-signing entitlements. The file-based keychain uses access control lists (`SecAccess`) with its own distinct rules. Code written for iOS typically targets the data-protection keychain; porting it to macOS without attention to this split is a common source of unexpected behavior.

**Access groups and entitlements (data-protection keychain).** For the data-protection keychain, macOS builds the list of available access groups from an app's signed entitlements, authorized by a provisioning profile ([TN3137](https://developer.apple.com/documentation/technotes/tn3137-on-mac-keychains)). The access-group string is prefixed by the developer team identifier; group membership is established through signed entitlements and a provisioning profile, not through any runtime grant or token. Apple's `securityd` daemon evaluates every read and write against those entitlements alongside `application-identifier` and `application-group` ([Apple Platform Security](https://support.apple.com/guide/security/keychain-data-protection-secb0694df1a/web)).

**User-login context requirement.** The data-protection keychain is only available to programs running in a user login context — apps, app extensions, and app-like command-line tools with the appropriate entitlements and bundle structure ([TN3137](https://developer.apple.com/documentation/technotes/tn3137-on-mac-keychains)). A `launchd` daemon runs outside of a user context and must use the file-based keychain instead.

**kSecAttrSynchronizable opt-in.** A credential stored locally in the data-protection keychain does not automatically sync to iCloud. Setting `kSecAttrSynchronizable = true` is what opts an individual item into iCloud Keychain sync; it is also one of two ways to target the data-protection keychain in the first place (the other being `kSecUseDataProtectionKeychain`). An item that your app reads and writes locally does not require the synchronizable attribute unless you also want it to sync.

**Biometric and passcode ACLs.** Items protected by a Face ID, Touch ID, Optic ID, or passcode challenge require user presence at the moment of access. No remote or background flow can satisfy this silently.

## App-owned credentials versus user-saved passwords

The access model draws a hard line between two categories of keychain item.

**App-owned credentials** are items your app wrote into the keychain under an access group declared in its own signed entitlements. Your app — and any other app sharing that exact access-group string and team identifier — can read them back. This is what Keychain Services is designed for: secrets that belong to your application, persisted securely across launches.

**User-saved passwords and passkeys** are stored under system-managed access groups that no ordinary third-party app can join. Items added through Password AutoFill or the Passwords app are off-limits to arbitrary programs. A normal app cannot query the whole user store merely by signing in with an Apple Account, holding an OAuth token, or declaring any combination of entitlements.

**Passkey and password transfer on OS 26.** For an existing app account, Apple can also present a system prompt and return an approved saved password through `ASAuthorizationPasswordProvider`. Apple introduced `ASCredentialExportManager` in Authentication Services on iOS 26, iPadOS 26, macOS 26, and visionOS 26, allowing participating credential-provider extensions to facilitate user-initiated transfer of passwords and passkeys between credential managers ([WWDC25 session 279](https://developer.apple.com/videos/play/wwdc2025/279/)). The system acts as an intermediary, presents out-of-process confirmation UI, authenticates the user locally (using Face ID or equivalent local authentication), and does not write credential data to the file system. Using this API requires implementing a credential-provider extension with `SupportsCredentialExchange` declared in its Info.plist; each transfer requires explicit user action. This is not a silent keychain query and not a Figment feature.

## Workflow checklist: app-owned credentials

Use this checklist when your app controls a credential through an authorized access group.

| Step | Requirement | What blocks you if unmet |
|------|-------------|--------------------------|
| 1 — Access group declared | Credential is in your app's signed entitlement access group, authorized by a provisioning profile | Keychain read/write fails at OS level |
| 2 — Correct keychain targeted | Use `kSecUseDataProtectionKeychain = true` for the data-protection keychain; add `kSecAttrSynchronizable = true` only if the item should also sync to iCloud | Item targets wrong implementation or does not sync when expected |
| 3 — User-login context | App or app-like tool runs in a user session; `launchd` daemons must use the file-based keychain | Data-protection keychain unavailable outside user context |
| 4 — Destination and action approved | User has explicitly approved the target action and destination | Action must not proceed |
| 5 — Read and write separate | Each direction of access is independently granted | Do not infer write permission from read approval |
| 6 — Biometric gate satisfied | User is present if the item carries a biometric ACL | Cannot be automated without user presence |

A credential that clears all relevant steps is one your app controls, used for a specific user-approved action. It is not a general export of the user's iCloud Keychain, and it is not access to Passwords-app items.

## What Figment currently offers

Figment does not offer a Keychain credential-use connector or endpoint. The available Figment integrations are:

- **iMessage** — read, search, and send through the iMessage REST API. The developer pays $29/month per active live connection; sandbox access is free. Access starts after setup.
- **Contacts, Calendar, Reminders** — a synthetic read-only sandbox is available for integration testing. No live customer access is currently offered for these services.

Figment's consent model governs how your application receives a scoped grant for the services listed above. It does not extend to Keychain data.

---

Ready to build with Figment's available Apple integrations? [Connect Apple Account →](/apple-connect/developers) to access the iMessage API and the synthetic sandbox environment.
