fuchsia.identity.keys

Defines protocols to manage and access key material that is consistent across all devices provisioned with a particular identity.

Acheiving consistency implies synchonization between devices and this synchronization is not instantaneous. For some implementations synchronization may take many minutes, or even longer when devices are offline. The library provides information about the progress of the sychronization.

PROTOCOLS

KeyManager

Defined in fuchsia.identity.keys/key_manager.fidl

KeyManager provides access to key material that is consistent across all devices provisioned with the identity that the KeyManager was acquired from, such as a Fuchsia Persona.

Acheiving consistency implies synchonization between devices and this synchronization is not instantaneous. For some implementations synchronization may take many minutes or even longer when devices are offline. The KeyManager is able to report information about the progress of this synchronization via SynchonizationState.

WatchOrCreateKeySingleton

Returns the KeySingleton with the name supplied in properties or creates a new KeySingleton if this name does not exist.

This method follows the hanging get pattern and does not return until the response would be different than the previous request for the same name. Errors are always returned as soon as they are detected.

properties The properties of the new KeySingleton.

Returns: properties The KeySingletonProperties supplied at creation, with uid populated. state The SychronizationState for the KeySingleton. key The Key for the KeySingleton.

Request

NameType
properties KeySingletonProperties

Response

NameType
result KeyManager_WatchOrCreateKeySingleton_Result

WatchKeySingleton

Returns the KeySingleton with the specified name.

Fails with NOT_FOUND if the requested name does not exist. This method follows the hanging get pattern and does not return until the response would be different than the previous request for the same name. Errors are always returned as soon as they are detected.

name The name of the requested KeySingleton.

Returns: properties The KeySingletonProperties supplied at creation, with uid populated. state The SychronizationState for the KeySingleton. key The Key for the KeySingleton.

Request

NameType
name string[128]

Response

NameType
result KeyManager_WatchKeySingleton_Result

DeleteKeySingleton

Deletes a previously created KeySingleton.

Fails with NOT_FOUND if the requested name does not exist. This method returns once the deletion has been recorded locally and this does not guarantee that the deletion will be successfully committed.

name The name of the key singleton.

Request

NameType
name string[128]

Response

NameType
result KeyManager_DeleteKeySingleton_Result

GetOrCreateKeySet

Connects a channel to the KeySet with the name supplied in properties or creates a new KeySet containing a single Key if this name does not exist.

properties The properties of the new KeySet. key_set_to_freeze If this string is the name of another KeySet that is in the LIVE state, and if this method causes a new KeySet to be created, the other KeySet will be moved to the FROZEN state atomically with the new KeySet reaching the LIVE state. key_set The server end of a KeySet channel.

Request

NameType
properties KeySetProperties
key_set_to_freeze string[128]?
key_set request<KeySet>

Response

NameType
result KeyManager_GetOrCreateKeySet_Result

GetKeySet

Connects a channel to a previously created KeySet.

Fails with NOT_FOUND if the requested name does not exist.

name The name of the key set. key_set The server end of a KeySet channel.

Request

NameType
name string[128]
key_set request<KeySet>

Response

NameType
result KeyManager_GetKeySet_Result

FreezeKeySet

Freezes a previously created KeySet.

Fails with NOT_FOUND if the requested name does not exist. The method returns once the freeze has been recorded locally and this does not guarantee that the freeze will be successfully committed. If the KeySet is already in the PENDING_FROZEN_ADDITION, PENDING_FREEZE, or FROZEN state this operation has no effect.

name The name of the key set.

Request

NameType
name string[128]

Response

NameType
result KeyManager_FreezeKeySet_Result

DeleteKeySet

Deletes a previously created KeySet.

Fails with NOT_FOUND if the requested name does not exist. Once the deletion has been successfully committed any KeySet channels referring to it will be closed. The method returns once the deletion has been recorded locally and this does not guarantee that the deletion will be successfully committed.

name The name of the key set.

Request

NameType
name string[128]

Response

NameType
result KeyManager_DeleteKeySet_Result

KeySet

Defined in fuchsia.identity.keys/key_manager.fidl

KeySet provides access to a set of keys that is consistent across devices provisioned with the identity that it applies to.

The keys within a key set are typically all used for the same purpose, such as encrypting a sensitive dataset. A recent key can be used to encrypt new data but older keys remain available to decrypt older data.

All keys in the set are of the same size and each is identified by a monotonically increasing KeyId starting at one. A new key is added into the set on each rotation event. These rotation events may either occur "automatically" or "manually":

  • An automatic rotation occurs when a device's access to the identity is remotely revoked (we trust a device that performs its own recovation to also securely delete the key material it is holding). The newly added key is not supplied to the device whose access was revoked. The account system may combine the revocation of multiple devices into a single rotation event.
  • A manual rotation occurs when a client calls the AddKey method.

Old keys are deleted from the set automatically to avoid exceeding its maximum size, clients may also delete keys using the DeleteKey method.

Optionally, a client may "mark" specific keys in the KeySet to track its processing of individual keys. The account system will report the latest key that has been marked on any device.

A key set may be frozen, after which no further keys will be added and no further mark operations may be performed. Keys may still be deleted from a frozen key set.

WatchSynchronizationState

Returns the SynchronizationState for the entire KeySet. Refer to the documentation on SynchronizationState for the available states and state transitions.

This method follows the hanging get pattern and does not return until the response would be different than the previous request.

Request

NameType

Response

NameType
state SynchronizationState

GetProperties

Returns the KeySetProperties for this key set.

These properties are fixed and will not change through the life of the key set.

Request

NameType

Response

NameType
properties KeySetProperties

WatchSynchronizedIds

Return a vector of the KeyId for all keys in the key set with SynchronizationState == LIVE.

The returned vector is ordered by id. This method follows the hanging get pattern and does not return until the response would be different than the previous request.

Request

NameType

Response

NameType
result KeySet_WatchSynchronizedIds_Result

WatchAllIds

Return a vector of the KeyId for all keys in the key set, whatever their SynchronizationState.

The returned vector is ordered by id. This method follows the hanging get pattern and does not return until the response would be different than the previous request.

Note: Worst case this vector will be twice the maximum size of the key set. Consider a full key set that contains N LIVE keys. N manual rotations are now performed before the first succeeds. Each rotation moves a key from the LIVE state to the PENDING_DELETION state and adds a new key in the PENDING_ADDITION state.

Request

NameType

Response

NameType
result KeySet_WatchAllIds_Result

WatchKey

Returns a Key from the key set.

Fails with NOT_FOUND if the requested key does not exist. This method follows the hanging get pattern and does not return until the response would be different than the previous request for this id.

id The KeyId of the requested key.

Returns: key The requested Key. state The current SynchronizationState of the key. Note that keys in PENDING_ADDITION are not final: they might never reach other devices and the same KeyId might be reused for a different Key in the future.

Request

NameType
id KeyId

Response

NameType
result KeySet_WatchKey_Result

DeleteKey

Deletes a Key from the key set.

Fails with NOT_FOUND if the requested key does not exist. The method returns once the deletion has been recorded locally and this does not guarantee that the deletion will be successfully committed.

id The KeyId of the requested key.

Request

NameType
id KeyId

Response

NameType
result KeySet_DeleteKey_Result

AddKey

Adds a new Key to the key set, i.e. performs a manual key rotation.

The method returns once the addition has been recorded locally and this does not guarantee that the addition will be successfully committed.

Fails with UNSUPPORTED_OPERATION if KeySetProperties.manual_rotation is false or with FROZEN if the key set has been frozen.

Request

NameType

Response

NameType
result KeySet_AddKey_Result

MarkId

Performs a "Mark" operation on a key, such that it is eligible to be returned by GetMaxMarkedId.

The largest KeyId on which a mark operation has been performed is synchronized across devices.

Fails with FROZEN if the key set has been frozen.

id The KeyId of the requested key. The method will fail with NOT_FOUND if this key does not exist.

Request

NameType
id KeyId

Response

NameType
result KeySet_MarkId_Result

WatchMaxCommittedMarkedId

Returns the maximum KeyId on which MarkId has been called and successfully commited.

This method follows the hanging get pattern and does not return until the response would be different than the previous request.

Returns: id The largest KeyId for which a MarkId call has been made and successfully committed, or zero if no MarkId calls have been committed.

Request

NameType

Response

NameType
result KeySet_WatchMaxCommittedMarkedId_Result

WatchMaxPendingMarkedId

Returns the maximum KeyId on which MarkId has been called, even if this has not yet been successfully committed.

This method follows the hanging get pattern and does not return until the response would be different than the previous request.

Returns: id The largest KeyId for which a MarkId call has been made, or zero if no MarkId calls have been made.

Request

NameType

Response

NameType
result KeySet_WatchMaxPendingMarkedId_Result

STRUCTS

KeyManager_WatchOrCreateKeySingleton_Response

generated

NameTypeDescriptionDefault
properties KeySingletonProperties No default
state SynchronizationState No default
key Key No default

KeyManager_WatchKeySingleton_Response

generated

NameTypeDescriptionDefault
properties KeySingletonProperties No default
state SynchronizationState No default
key Key No default

KeyManager_DeleteKeySingleton_Response

generated

NameTypeDescriptionDefault

KeyManager_GetOrCreateKeySet_Response

generated

NameTypeDescriptionDefault

KeyManager_GetKeySet_Response

generated

NameTypeDescriptionDefault

KeyManager_FreezeKeySet_Response

generated

NameTypeDescriptionDefault

KeyManager_DeleteKeySet_Response

generated

NameTypeDescriptionDefault

KeySet_WatchSynchronizedIds_Response

generated

NameTypeDescriptionDefault
ids vector<uint32>[64] No default

KeySet_WatchAllIds_Response

generated

NameTypeDescriptionDefault
ids vector<uint32>[128] No default

KeySet_WatchKey_Response

generated

NameTypeDescriptionDefault
key Key No default
state SynchronizationState No default

KeySet_DeleteKey_Response

generated

NameTypeDescriptionDefault

KeySet_AddKey_Response

generated

NameTypeDescriptionDefault

KeySet_MarkId_Response

generated

NameTypeDescriptionDefault

KeySet_WatchMaxCommittedMarkedId_Response

generated

NameTypeDescriptionDefault
id KeyId No default

KeySet_WatchMaxPendingMarkedId_Response

generated

NameTypeDescriptionDefault
id KeyId No default

ENUMS

Error

Type: uint32

Defined in fuchsia.identity.keys/key_manager.fidl

Specifies the reason that a fuchsia.identity.keys method failed.

NameValueDescription
UNKNOWN 1

Some other problem occurred that cannot be classified using one of the more specific statuses. Retry is optional.

INTERNAL 2

An internal error occurred. This usually indicates a bug within the account system itself. Retry is optional.

UNSUPPORTED_OPERATION 3

The requested operation is not supported. This generally indicates that implementation of a new feature is not yet complete. The request should not be retried.

INVALID_REQUEST 4

The request was malformed in some way, such as using an invalid key size. The request should not be retried.

RESOURCE 5

A local resource error occurred such as I/O, FIDL, or memory allocation failure. Retry, after a delay, is recommended.

NOT_FOUND 7

The requested key or key set is not present. The request should not be retried.

FROZEN 8

The request would require an illegal change to an entry that is in a frozen state.

SynchronizationState

Type: uint32

Defined in fuchsia.identity.keys/key_manager.fidl

Summarizes the sychronization between the device's local state and the master definition for some item (such as a KeySingleton or KeySet) in an identity. Depending on the identity and implementation this "master definition" might take one of many forms such as the device itself, a server, a blockchain, a transparency directory, or a quorum of devices.

Synchronization follows the state machine illustrated below. Only KeySet supports the PENDING_FROZEN_ADDITION, PENDING_FREEZE, and FROZEN states:

            +------------------------+                 --\
            |                        |                   |
            |   +----------------+   | [commit           |
            |   | PENDING_FROZEN |   |  success]         |
            |   |   _ADDITION    |---|----------\        \ Present on
            |   +----------------+   |          |        / local device
            |     ^                  | Delete   |        |
            |     | Freeze locally   | locally  |        |
  Add       |     |                  |----------|--\     |
  locally   |  +------------------+  | [commit  |  |     |
  ----------|->| PENDING_ADDITION |  |  fail]   |  |     |
            |  +------------------+  |          |  |     |
            |          |             |          |  |     |
  Add       +----------|-------------+          |  |     |
  remotely             |                        |  |     |
  ----------------+    | [commit success]       |  |     |
                  |    |                        |  |     |  --\
            +-----|----|------------+           |  |     |    |
            |     v    v            |           |  |     |    |
            |  +-----------------+  |           |  |     |    |
  +----------->|     LIVE        |  |           |  |     |    |
  |         |  +-----------------+  |           |  |     |    |
  |         |         | ^           |           |  |     |    |
  |         |  Freeze | | [commit   |           |  |     |    |
  |         | locally | |  fail]    |           |  |     |    |
  |         |         v |           | Delete    |  |     |    |
  |         |  +-----------------+  | Remotely  |  |     |    |
  |         |  | PENDING_FREEZE  |  |-----------|--+     |    |
  |         |  +-----------------+  |           |  |     |    |
  |         |          |            |           |  |     |    |
  |         |          | [commit    |           |  |     |    |
  |         |          |  success]  |           |  |     |    |
  |         |          v            |           |  |     |    |
  |         |  +-----------------+  |           |  |     |    |
  | +--------->|    FROZEN       |<-------------/  |     |    |
  | |       |  +-----------------+  |              |     |    |
  | |       |    ^                  |              |     |    |
  | |       |    | Freeze remotely  |              |     |    |
  | |       |    |                  |              |     |    |
  | |       +----+------------------+              |     |    |
  | |                    |                         |     |    |
  | | [previous state    | Delete                  |   --/    |
  | |  == FROZEN]        | locally                 |          |
  | |                    v            Delete       |          \ Present
  | +----+      +------------------+  remotely     |          / in master
  |      |      | PENDING_DELETION |---------------+          | definition
  |      ^      +------------------+  [commit      |          |
  |     / \              |             success]    |        --/
  +----<   >-------------+                         V
[else]  \ /   [commit fail]                   +---------+
         v                                    | INVALID |
                                              +---------+
NameValueDescription
PENDING_ADDITION 1

The item is present and not frozen on the current device but has not yet been committed into the master definition. Items in this state might not reach other devices and might become invalid if committing the addition fails.

PENDING_FROZEN_ADDITION 2

The item is present and frozen on the current device but has not yet been committed into the master definition. Items in this state might not reach other devices and might become invalid if committing the addition fails. If committing the item succeeds it will enter the FROZEN state directly without passing through LIVE.

LIVE 3

The item is present and not frozen both on the current device and in the master definition of the identity. It should eventually be consistent across all devices with access to the identity.

PENDING_FREEZE 4

The item has been frozen on the current device but this operation has not yet been committed. Items in this state might return to the LIVE state if committing the freeze fails.

FROZEN 5

The item is present and frozen both on the current device and in the master definition of the identity. Mutations are no longer possible but deletions are still allowed.

PENDING_DELETION 6

The item is present in the master definition of the identity, but has been deleted from the current device and this deletion has not yet been committed. Items in this state might return to the LIVE or FROZEN state if committing the deletion fails.

TABLES

KeySingletonProperties

Defined in fuchsia.identity.keys/key_manager.fidl

Specifies the properties of a KeySingleton. These properties are provided when the KeySingleton is created and do not change during its lifetime.

OrdinalNameTypeDescription
1 name string[128]

A name of the KeySingleton. Unique within the KeyManager that supplied it at a single point in time.

2 uid uint64

A numeric identifier for the KeySingleton that is unique within the KeyManager that created it. The same name might be reused for different key singletons during the lifetime of a KeyManager but these will have different uid values.

This field is set by the account system and must not be supplied in KeyManager.CreateKeySingleton.

3 metadata vector<uint8>[128]

Optional metadata associated with the KeySingleton. This is supplied by the client and is opaque to the account system.

4 key_length uint32

The size of the key material in this KeySingleton in bytes. The value must be between one and MAX_KEY_LEN inclusive.

KeySetProperties

Defined in fuchsia.identity.keys/key_manager.fidl

Specifies the properties of a KeySet. These properties are provided when the KeySet is created and do not change during its lifetime.

OrdinalNameTypeDescription
1 name string[128]

A name of the KeySet. Unique within the KeyManager that supplied it at a single point in time.

2 uid uint64

A numeric identifier for the KeySet that is unique within the KeyManager that created it. The same name might be reused for different key sets during the lifetime of a KeyManager but these will have different uid values.

This field is set by the account system and must not be supplied in KeyManager.CreateKeySet.

3 metadata vector<uint8>[128]

Optional metadata associated with the KeySet. This is supplied by the client and is opaque to the account system.

4 key_length uint32

The size of the keys in this KeySet in bytes. The value must be between one and MAX_KEY_LEN inclusive.

5 max_keys uint32

The maximum number of keys within this KeySet. Old keys will be automatically deleted to prevent this limit being exceeded. The value must be between one and MAX_KEYSET_SIZE inclusive.

6 automatic_rotation bool

If true, a new key will be added to this KeySet each time a device with access to the identity is remotely revoked. automatic_rotation and manual_rotation cannot both be false.

7 manual_rotation bool

If true, users of this KeySet may cause new keys to be added by calling KeySet.AddKey. automatic_rotation and manual_rotation cannot both be false.

UNIONS

KeyManager_WatchOrCreateKeySingleton_Result

generated

NameTypeDescription
response KeyManager_WatchOrCreateKeySingleton_Response
err Error

KeyManager_WatchKeySingleton_Result

generated

NameTypeDescription
response KeyManager_WatchKeySingleton_Response
err Error

KeyManager_DeleteKeySingleton_Result

generated

NameTypeDescription
response KeyManager_DeleteKeySingleton_Response
err Error

KeyManager_GetOrCreateKeySet_Result

generated

NameTypeDescription
response KeyManager_GetOrCreateKeySet_Response
err Error

KeyManager_GetKeySet_Result

generated

NameTypeDescription
response KeyManager_GetKeySet_Response
err Error

KeyManager_FreezeKeySet_Result

generated

NameTypeDescription
response KeyManager_FreezeKeySet_Response
err Error

KeyManager_DeleteKeySet_Result

generated

NameTypeDescription
response KeyManager_DeleteKeySet_Response
err Error

KeySet_WatchSynchronizedIds_Result

generated

NameTypeDescription
response KeySet_WatchSynchronizedIds_Response
err Error

KeySet_WatchAllIds_Result

generated

NameTypeDescription
response KeySet_WatchAllIds_Response
err Error

KeySet_WatchKey_Result

generated

NameTypeDescription
response KeySet_WatchKey_Response
err Error

KeySet_DeleteKey_Result

generated

NameTypeDescription
response KeySet_DeleteKey_Response
err Error

KeySet_AddKey_Result

generated

NameTypeDescription
response KeySet_AddKey_Response
err Error

KeySet_MarkId_Result

generated

NameTypeDescription
response KeySet_MarkId_Response
err Error

KeySet_WatchMaxCommittedMarkedId_Result

generated

NameTypeDescription
response KeySet_WatchMaxCommittedMarkedId_Response
err Error

KeySet_WatchMaxPendingMarkedId_Result

generated

NameTypeDescription
response KeySet_WatchMaxPendingMarkedId_Response
err Error

XUNIONS

Key

Defined in fuchsia.identity.keys/key_manager.fidl

Defines the key material in a KeySingleton or each member of a KeySet.

Note: Currently all keys are defined as fixed length arrays of random data but we use an xunion to potentially allow more structured key types in a future version of the API.

NameTypeDescription
random_key vector<uint8>[64]

An unstructured random key of the length specified in KeySingletonProperties.key_length or KeySetProperties.key_length.

CONSTANTS

NameValueTypeDescription
MAX_NAME_LEN 128 uint32

The maximum length of a KeySingleton or KeySet name, in bytes.

MAX_METADATA_LEN 128 uint32

The maximum length of metadata in a KeySingleton or KeySet, in bytes.

MAX_KEY_LEN 64 uint32

The maximum length of an unstructured random Key, in bytes.

MAX_KEYSET_SIZE 64 uint32

The maximum number of Key objects in a KeySet.

TWICE_MAX_KEYSET_SIZE 128 uint32

Two times the maximum number of Key objects in a KeySet.

TYPE ALIASES

NameValueDescription
KeyId uint32