Concepts
Library
A Library is the top-level container for all of your media. It owns the encryption keys, the operation log, and the album tree.
Users
A library can have several users but they all get full access to the library. However each user can have a different password.
Media
A Media represents a single media item (photo or video) stored in the library. Each media item is stored as a single encrypted file on the server. Each media item also gets a precomputed thumbnail, also encrypted and stored on the server.
A companion media item is a media record referenced by another item's apple_aae_media_id or
apple_live_photo_media_id. It stores an Apple .AAE edit sidecar or the video component of a
Live Photo. It is synced like ordinary media but hidden from normal Home, album, group, and Trash
listings. The lifecycle table below describes primary media.
Media has three lifecycle states:
| State | Browse visibility | Encrypted blobs |
|---|---|---|
| Active | Home and its live album/group memberships; Orphans when it has no such membership | Kept and synchronized |
| Trashed | Virtual Trash only | Kept and synchronized so Restore works on every device |
| Hard-deleted | Nowhere | Removed from local cache immediately and reclaimed from each remote after a later Push |
Hard deletion is permanent: its CRDT tombstone prevents late operations or a late creation from restoring the item.
Trash
Trash holds soft-deleted media. Moving media to Trash keeps its existing album and group memberships, so Restore returns it to those collections automatically. Its encrypted blobs remain synchronized until the user permanently deletes it.
Empty Trash permanently deletes every trashed record, including any hidden AAE and Live Photo companions.
The full protocol is specified in Media deletion.
Keys
Lasco uses a layered key hierarchy so that a single master key protects all content while per-media keys allow efficient granular encryption.
| Key | Full name | Purpose |
|---|---|---|
| KEK | Key Encryption Key | Per-user key derived from the password; wraps the master key |
| Master Key | Master Key | Root key; protects the entire library; stored as mk_{user}.enc |
| FileKey | File Encryption Key | Per-media key derived from the master key and the file UUID |
A salt.bin (32 random bytes, generated once at library creation) is mixed into all KEK derivations to ensure keys are unique per library even when passwords are reused.
Albums
Albums are used to gather media items (or groups of media items). Albums can hold other albums. Basically think about them like a folder arborescence.
A media item may be created without being assigned to an album. This is orphan media: it remains a normal, browsable item in the library and can later be added to one or more albums with AlbumMediaAdd operations. When a media item is removed from its last album, it becomes orphan media again. Clients should offer both an all-media view and an orphan-only view so unassigned media can be found and organized.
Groups
Groups can be added to albums, contain media items like albums, but cannot hold other groups or albums. We use them to keep many similar media items in an album, without showing all of them.
Operations
An Operation is the atomic unit of change in a library. Every action is recorded as an operation. Operations are immutable once written and are never modified in place.
Operations are bundled into OperationGroups: each group carries a unique ID, a timestamp, and one or more operations applied together. The group file is encrypted and stored on the server under operations/.
Clients merge immutable CRDT operations by dot into CrdtState. The merge is commutative,
associative, and idempotent, so devices converge after observing the same operation set without a
shared replay order.
Remote
A Remote is a storage backend (e.g. an S3 bucket or a compatible object store) where the library's encrypted blobs are kept. A library can have multiple remotes.
Device
A Device is any machine running a Lasco client. Each device maintains a full copy of all known operations, so the library state can be reconstructed offline. Only a subset of media blobs may be cached locally.