# Database Module
An SQLite database is used to store the data including the encrypted secrets. This document
describes the data model and database design.
## Entity-Relationship
The entity relationship model is simple. The database consists of multiple collections. Each
collection holds zero or more items that holds encrypted secrets. Each item is attached with zero or
more attributes of unencrypted name-value pairs that are used to search for and identify
secrets. This is as shown below:

## Encryption
The data is encrypted using [ChaCha20-Poly1305 AEAD
scheme](https://cryptobook.nakov.com/symmetric-key-ciphers/popular-symmetric-algorithms#symmetric-encryption-schemes-constructions).
The key needed for this is derived from the password that is either entered by the user, or obtained
from PAM. The password to key conversion is done using [Argon2 Key Derivation
Function](https://cryptobook.nakov.com/mac-and-key-derivation/argon2). The password is purged from
memory after the key is derived.
## Locking
The software implements two types of locking. One for collections and the other for items.
**Collections:** Collections are unlocked using password (as explained above). The user is prompted
for password using pinentry, unless it is already obtained from PAM. Once the password is obtained,
the key is derived and stored in memory. The collection is considered unlocked in this state. All
the item secrets under the collection are decrypted using this key.
When the collection is locked by the user or a program, the key is purged from memory. The secrets
cannot be decrypted unless the user providest the password again.
**Items:** Items implement a soft locking. Items are unlocked by default, unless `prompt_to_unlock`
is enabled. Locked items simply needs a confirmation from the user (no password needed) using
pinentry to unlock it.
If `prompt_to_unlock` is enabled for an item, then it starts as locked for each new session. Thus a
user confirmation is required per session for unlocking the item.
All this assumes that the collection of the item is already unlocked. If it's not, then an attempt
to unlock the item will trigger a password prompt using pinentry. Once the collection is unlocked,
the item will also be considered unlocked and no further prompts will be made.
## Database Schema
Based on the above requirements, the database schema is as follows:
**TABLE:** Collections
| PK | `name` | text |
| | `created_on` | text (ISO8601 datetime) |
**TABLE:** Items
| PK, Generated | `label` | text |
| FK to Collections | `collection` | text |
| | `parameters` | blob |
| | `value` | blob (encrypted) |
| | `content_type` | text |
| | `prompt_to_unlock` | bool |
| | `created_on` | text (ISO8601 datetime) |
**TABLE:**: Attributes
| PK, Generated | `id` | integer |
| FK to Items | `item` | text |
| | `name` | text |
| | `value` | text |
## In-Memory Data Representation
The data is read and written sparingly. Consequently, most of the data doesn't need to be stored in
memory. They can be accessed or written to disk on demand. Only minimal data representing the state
and keys to accessing collections and items need to be stored in memory. The attributes will be
stored in memory to make searches fast. It's as follows:
