When a user enables iCloud Keychain for the first time, the device establishes a circle of trust and creates a syncing identity for itself. The syncing identity consists of a private key and a public key. The public key of the syncing identity is put in the circle, and the circle is signed twice: first by the private key of the syncing identity, then again with an asymmetric elliptical key (using P-256) derived from the user’s iCloud account password. Also stored with the circle are the parameters (random salt and iterations) used to create the key that is based on the user’s iCloud password.
The signed syncing circle is placed in the user’s iCloud key-value storage area. It can’t be read without knowing the user’s iCloud password, and can’t be modified validly without having the private key of the syncing identity of its member.
When the user turns on iCloud Keychain on another device, iCloud Keychain notices that the user has a previously established syncing circle in iCloud that it isn’t a member of. The device creates its syncing identity key pair, then creates an application ticket to request membership in the circle. The ticket consists of the device’s public key of its syncing identity, and the user is asked to authenticate with their iCloud password. The elliptical key-generation parameters are retrieved from iCloud and generate a key that is used to sign the application ticket. Finally, the application ticket is placed in iCloud.
When the first device sees that an application ticket has arrived, it asks for the user to acknowledge that a new device is asking to join the syncing circle. The user enters their iCloud password, and the application ticket is verified as signed by a matching private key. Now, the users who generated the request to join the circle can join it.
Upon the user’s approval to add the new device to the circle, the first device adds the public key of the new member to the syncing circle, and signs it again with both its syncing identity and the key derived from the user’s iCloud password. The new syncing circle is placed in iCloud, where it’s similarly signed by the new member of the circle.
There are now two members of the signing circle, and each member has the public key of its peer. They now begin to exchange individual Keychain items through iCloud key-value storage or store them in CloudKit, whichever is most appropriate for the situation. If both circle members have the same item, the one with the most recent modification date is synced. If the other member has the item and the modification dates are identical, items are skipped. Each item that’s synced is encrypted so it can be decrypted only by a device within the user’s circle of trust; it can’t be decrypted by any other devices or by Apple.
This process is repeated as new devices join the syncing circle. For example, when a third device joins, the confirmation appears on both of the other user’s devices. The user can approve the new member from either of those devices. As new peers are added, each peer syncs with the new one to ensure that all members have the same Keychain items.
However, the entire Keychain isn’t synced. Some items are device specific, such as VPN identities, and shouldn’t leave the device. Only items with the kSecAttrSynchronizable attribute are synced. Apple has set this attribute for Safari user data (including user names, passwords, and credit card numbers), as well as for Wi-Fi passwords and HomeKit encryption keys.
Additionally, by default, Keychain items added by third-party apps don’t sync. Developers must set the kSecAttrSynchronizable attribute when adding items to the Keychain.