# LispKit System Keychain

Library `(lispkit system keychain)` provides an API for accessing the macOS and iOS keychain. The keychain allows for centrally storing small bits of confidential user data in an encrypted database. Such keychain items consist of encrypted binary data as well as unencrypted meta-data. Once stored in the keychain, keychain items, by default, are only readable by the application hosting the LispKit interpreter app. While the system keychain supports different types of keychain items, library `(lispkit system keychain)` only handles generic password keychain items.

Access to items in a keychain is provided by `keychain` client objects. A `keychain` client enables accessing all keychain items that belong to a given service. The service is typically a string identifier for the program storing and accessing secrets in the keychain. By default, this is the main bundle identifier of the macOS or iOS application hosting the LispKit interpreter. But the API supports specifying any arbitrary service. To share keychain items between applications, it is possible to specify a shared access group identifier which can be used across applications.

`keychain` clients also specify the security level of their keychain storage. Such access policies are defined via symbolic constants which can be parameterized with an authentication prompt and an authentication policy, which again is a symbolic identifier. By default, access policy `when-unlocked` is used. It is one of the most restrictive options, providing good data protection since keychain items can only be accessed while the device is unlocked. More details on the access policy model can be found in the article “Restricting keychain item accessibility”.

Finally, each keychain object defines whether the keychain items that are accessible via this object are synchronized via iCloud and thus accessible on other systems and devices.

Keychain items accessible via a keychain client object are identified by a key, which is an arbitrary string. The API provides means to read and write keychain items, both data and meta-data (so called attributes). There is functionality for deleting keychain items as well as listing all the keys of the items belonging to the service of the keychain object. Via procedure `available-keychain-services`, all available services can be listed. Alternatively, all available service/key combinations can be returned via procedure `available-keychain-keys`.

## Keychains

keychain-type-tag [constant]

Symbol representing the `keychain` type. The `type-for` procedure of library `(lispkit type)` returns this symbol for all keychain objects.

(keychain? obj) [procedure]

Returns `#t` if obj is a keychain object; `#f` otherwise.

(make-keychain) [procedure]
(make-keychain service)
(make-keychain service group)
(make-keychain service group acc)
(make-keychain service group acc sync)

Returns a new keychain client for the given service and access group. service is a string identifier for the program storing and accessing secrets in the keychain. By default, this is the main bundle identifier of the macOS or iOS application. A shared access group identifier (a string) can be used to share keychain items across programs. `#f` specifies the default for service (the application) and group (none).

acc specifies access policies. The following access policy specifiers are supported:

- `symbol`: Symbols specify the item accessibility. Supported are `when-unlocked`, `after-first-unlockl`, `always`, `when-unlocked-this-device-only`, `after-first-unlock-this-device-only`, `always-this-device-only`.
- `(prompt)`: An authentication prompt (a string) is provided, which is shown to the user. Default item accessibility is used.
- `(prompt access)`: An authentication prompt (a string) is provided, which is shown to the user. access specifies the item accessibility via a symbol (see previous bullet point).
- `(prompt access policy ...)`: An authentication prompt (a string) is provided, which is shown to the user. access specifies the item accessibility via a symbol (see previous bullet point). policy … are access policy specifiers (symbols) which determine what authentication methods should be allowed. Supported are `user-presence`, `biometry-any`, `biometry-current-set`, `device-passcode`, `watch`, `or`, `and`, `private-key-usage`, and `application-password`.

sync is a boolean argument. If set to `#t`, keychain items managed via the keychain client will be synchronized across iCloud.

(keychain-service keychain) [procedure]

Returns the keychain service (a string) for the given keychain client.

(keychain-access-group keychain) [procedure]

Returns the access group identifier (a string) for the given keychain client. If no access group is defined, `#f` is returned.

(keychain-accessibility keychain) [procedure]

Returns the item accessibility specifier for the given keychain client. See `make-keychain` for the supported symbols.

(keychain-synchronized? keychain) [procedure]

Returns `#t` if the given keychain client synchronizes keychain item updates across iCloud; `#f` otherwise.

## Keychain items

(keychain-exists? keychain key) [procedure]

Returns `#t` if keychain contains an item for the given key, `#f` otherwise. keychain is a keychain client object, key is a string.

(keychain-ref keychain key) [procedure]
(keychain-ref keychain key default)

With `keychain-ref` it is possible to retrieve the value set via `keychain-set!` from the item in keychain identified via `key`. Such values are stored in the keychain in serialized fashion. `keychain-ref` deserializes the data and returns the result of this operation. keychain is a keychain client object, key is a string. If the key is unknown, default is returned. If default is not provided, `#f` is used.

(keychain-ref-attributes keychain key) [procedure]

Returns metadata associated with the item in keychain identified via key. keychain is a keychain client object, key is a string. Metadata is returned in form of an association list which uses the following keys:

- `access-group`
- `accessibility`
- `comment`
- `creation-date`
- `key`
- `label`
- `modification-date`
- `service`
- `synchronizable`
- `value`

(keychain-ref-data keychain key) [procedure]

Returns the item in keychain identified by string key as a bytevector. If the data in the item cannot be represented as a bytevector, `#f` is returned.

(keychain-ref-string keychain key) [procedure]

Returns the item in keychain identified by string key as a string. If the data in the item cannot be represented by a string, `#f` is returned.

(keychain-set! keychain key value) [procedure]
(keychain-set! keychain key value label)
(keychain-set! keychain key value label comment)
(keychain-set! keychain key value label comment acc)
(keychain-set! keychain key value label comment acc sync)

Creates or overwrites an item identified via string key in keychain with value. value can be any serializable expression. Optional argument label defines a string label for this new keychain item (by default, label is `#f`), comment specifies a string comment that is stored as metadata (default is `#f`), acc specifies access policies. The following access policy specifiers are supported:

- `()` or `#f`: The keychain client defines the access policies to use.
- `symbol`: Symbols specify the item accessibility. Supported are `when-unlocked`, `after-first-unlockl`, `always`, `when-unlocked-this-device-only`, `after-first-unlock-this-device-only`, `always-this-device-only`.
- `(prompt)`: An authentication prompt (a string) is provided, which is shown to the user. Default item accessibility is used.
- `(prompt access)`: An authentication prompt (a string) is provided, which is shown to the user. access specifies the item accessibility via a symbol (see previous bullet point).
- `(prompt access policy ...)`: An authentication prompt (a string) is provided, which is shown to the user. access specifies the item accessibility via a symbol (see previous bullet point). policy … are access policy specifiers (symbols) which determine what authentication methods should be allowed. Supported are `user-presence`, `biometry-any`, `biometry-current-set`, `device-passcode`, `watch`, `or`, `and`, `private-key-usage`, and `application-password`.

The access policies specified via argument acc override the ones defined by the keychain client object. sync is a boolean argument. If set to `#t`, this keychain item will be synchronized across iCloud. If set to `#f`, this keychain item will only be stored locally. By default, sync is the empty list, which denotes that the keychain client defines whether to sync the item or not.

(keychain-set-data! keychain key data) [procedure]
(keychain-set-data! keychain key data label)
(keychain-set-data! keychain key data label comment)
(keychain-set-data! keychain key data label comment acc)
(keychain-set-data! keychain key data label comment acc sync)

Creates or overwrites an item identified via string key in keychain with the binary content of bytevector data. Optional argument label defines a string label for this new keychain item (by default, label is `#f`), comment specifies a string comment that is stored as metadata (default is `#f`), acc specifies access policies. See the description of `keychain-set!` for the specification of access policies via argument acc. Finally, sync is a boolean argument. If set to `#t`, this keychain item will be synchronized across iCloud. If set to `#f`, this keychain item will only be stored locally. By default, sync is the empty list, which denotes that the keychain client defines whether to sync the item or not.

(keychain-set-string! keychain key str) [procedure]
(keychain-set-string! keychain key str label)
(keychain-set-string! keychain key str label comment)
(keychain-set-string! keychain key str label comment acc)
(keychain-set-string! keychain key str label comment acc sync)

Creates or overwrites an item identified via string key in keychain with the string str. Optional argument label defines a string label for this new keychain item (by default, label is `#f`), comment specifies a string comment that is stored as metadata (default is `#f`), acc specifies access policies. See the description of `keychain-set!` for the specification of access policies via argument acc. Finally, sync is a boolean argument. If set to `#t`, this keychain item will be synchronized across iCloud. If set to `#f`, this keychain item will only be stored locally. By default, sync is the empty list, which denotes that the keychain client defines whether to sync the item or not.

(keychain-remove! keychain key) [procedure]

Removes the item in keychain identified via string key. If the item does not exist, the keychain is left untouched.

(keychain-keys keychain) [procedure]

Returns all the keys of items accessible via keychain.

## Keychain utilities

(available-keychain-services) [procedure]

Returns all the services available in the system keychain as a list of strings.

(available-keychain-keys) [procedure]

Returns a list of service/key pairs for all items available in the system keychain.

(make-password) [procedure]

Returns a new randomly generated password.