# (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"](https://developer.apple.com/documentation/security/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** <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-bdc0997c38ced7c944ea089918006133f1a4052f%2Fconst.png?alt=media" alt="" data-size="line">

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

**(keychain?&#x20;*****obj*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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

**(make-keychain)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(make-keychain&#x20;*****service*****)**\
\&#xNAN;**(make-keychain&#x20;*****service group*****)**\
\&#xNAN;**(make-keychain&#x20;*****service group acc*****)**\
\&#xNAN;**(make-keychain&#x20;*****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](https://developer.apple.com/documentation/security/restricting-keychain-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&#x20;*****keychain*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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

**(keychain-access-group&#x20;*****keychain*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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

**(keychain-accessibility&#x20;*****keychain*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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

**(keychain-synchronized?&#x20;*****keychain*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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

## Keychain items

**(keychain-exists?&#x20;*****keychain key*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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&#x20;*****keychain key*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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.

**(keychain-ref-attributes&#x20;*****keychain key*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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&#x20;*****keychain key*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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&#x20;*****keychain key*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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!&#x20;*****keychain key value*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(keychain-set!&#x20;*****keychain key value label*****)**\
\&#xNAN;**(keychain-set!&#x20;*****keychain key value label comment*****)**\
\&#xNAN;**(keychain-set!&#x20;*****keychain key value label comment acc*****)**\
\&#xNAN;**(keychain-set!&#x20;*****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](https://developer.apple.com/documentation/security/restricting-keychain-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!&#x20;*****keychain key data*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(keychain-set-data!&#x20;*****keychain key data label*****)**\
\&#xNAN;**(keychain-set-data!&#x20;*****keychain key data label comment*****)**\
\&#xNAN;**(keychain-set-data!&#x20;*****keychain key data label comment acc*****)**\
\&#xNAN;**(keychain-set-data!&#x20;*****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!&#x20;*****keychain key str*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(keychain-set-string!&#x20;*****keychain key str label*****)**\
\&#xNAN;**(keychain-set-string!&#x20;*****keychain key str label comment*****)**\
\&#xNAN;**(keychain-set-string!&#x20;*****keychain key str label comment acc*****)**\
\&#xNAN;**(keychain-set-string!&#x20;*****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!&#x20;*****keychain key*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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

**(keychain-keys&#x20;*****keychain*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns all the keys of items accessible via *keychain*.

## Keychain utilities

**(available-keychain-services)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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

**(available-keychain-keys)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

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

**(make-password)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns a new randomly generated password.
