Data Storage – KeyValService

Many components need a way to persist small pieces of data across restarts, such as maintaining device state after a reboot or storing values like API keys and authentication tokens. For these scenarios, KOS provides a built-in lightweight data store called KeyValService, designed specifically for simple, reliable persistence without the overhead of a full database. The data stored in the service persists between boot cycles.

The data store works by saving information as key-value pairs. Each value is associated with a key (a user-defined name) and stored within a namespace. Namespaces act as logical groupings, typically representing a service, feature, or application domain (for example “org.group"), and ensure that keys remain unique within their scope. This prevents collisions and allows different parts of the system to safely reuse the same key names.

The store supports multiple data types. Simple string values can be stored directly, whereas more complex data structures can be persisted by serializing objects into JSON and reconstructing them upon retrieval. In addition, binary data is supported through byte arrays (blobs), enabling storage of non-text or raw data.

For sensitive data, optional encryption is available. Values can be stored in encrypted form and are automatically decrypted when accessed, making the process transparent to the caller. The effectiveness of this encryption depends entirely on how the encryption key and salt are managed. This feature is primarily intended to obscure sensitive data, such as API keys or tokens.

Using autowiring, the KeyValService can be accessed as follows:

Once the service is ready, storing and retrieving values is straightforward:

In addition, for set and get operations, the store supports functionality such as checking for the existence of keys, removing entries, and accessing all data within a namespace.

For convenience, a KeyValNameSpace wrapper is provided. It binds all operations to a specific namespace, allowing you to interact with the store without repeatedly specifying the namespace.

This data store is intentionally a lightweight storage and should not be treated as a general-purpose database. It does not provide features such as complex querying, indexing, or transactions. Instead, it is designed for small-scale persistence needs where simplicity, low overhead, and ease of use are the primary goals.