Storage
A vault lives in a local folder or in an S3 bucket. The same two settings serve one machine and a server; on a server they hold every account's vaults.
A local folder
Set VAULT_PATH to a directory. It is made when missing.
- On one machine, the folder is the vault: plain
.mdfiles you can open in Obsidian, keep in git or read withcat. - On a server, the folder holds every vault, sealed; see What is stored. The Docker example uses
VAULT_PATH=/data/vaults, inside the container's volume.
VAULT_PATH wins over the S3_* settings when both are set.
An S3 bucket
Set all four of these; with any one missing, the bucket is not used:
| Variable | Example |
|---|---|
S3_ENDPOINT |
https://s3.example.com |
S3_BUCKET |
vault |
S3_ACCESS_KEY |
|
S3_SECRET_KEY |
S3_PREFIX puts the vault under a key prefix inside the bucket. S3_REGION defaults to us-east-1; some providers want another value, usually the bucket's region. S3_ENDPOINT is always needed, also for AWS S3, where it is the regional endpoint such as https://s3.eu-north-1.amazonaws.com.
Any S3-compatible store works that supports the calls below, for example AWS S3 or MinIO.
The bucket
Create the bucket before the first start: the server never creates one. Give its key these permissions on that bucket:
| Permission | Used for |
|---|---|
s3:ListBucket |
Listing the vault (ListObjectsV2). |
s3:GetObject |
Reading a note (GetObject, HeadObject). |
s3:PutObject |
Writing a note (PutObject), and the copy half of a move on one machine (CopyObject). |
s3:DeleteObject |
Deleting a note, and the other half of a move. |
A write that must not overwrite a newer version sends If-Match or If-None-Match: * with the PutObject. A store that refuses conditional writes gets a HeadObject before the write instead, and the server logs that once.
What is stored
On one machine, the folder or bucket holds the notes as written: markdown files under their own names.
On a server, every vault is sealed before it reaches storage, so the folder or bucket holds only opaque object names and ciphertext. Encryption explains the keys and what sealing protects. Under S3_PREFIX or VAULT_PATH, with VAULT_SUBJECT_PREFIX (default users) as <prefix>:
| Path | Holds |
|---|---|
<prefix>/<vault id>/ |
The vault's files. |
<prefix>/history/<vault id>/ |
A shared vault's earlier versions. |
<prefix>/indexes/<vault id>/ |
The vault's search index, with VAULT_INDEX_SNAPSHOTS=on. |
Turn on versioning for the bucket: sealing does not notice a file put back to an older version or removed, and versioning lets you recover it.
Each machine or server also keeps a search index per vault under VAULT_CACHE_DIR, which is not sealed; see Where the vectors live.