Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/release-notes/v0.1.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Changes

- **Encrypted exports keep each entry's earlier secrets.** `sesh export` (and Export in `sesh ui`) now includes every entry's history, with when each earlier secret was replaced and, for a file, its name then; `sesh import --from sesh` brings them back, within `history.keep`. Moving a vault to another computer this way no longer loses them. Plain exports (`--format json` or `csv`) still leave them out. An export made by 0.1.1 or earlier imports as before, and 0.1.1 reading a new export takes its entries and ignores the history.
- **A damaged earlier secret no longer stops an export.** One that can't be read is left out, and the export names the entries it affects; everything else is exported.
- Import summaries say "earlier secrets" rather than "old passwords", since a sesh export's history can be files, keys or notes as well.

## For contributors

- `scripts/sesh-dev` builds the checkout and runs it on a vault, config and agent of its own, apart from an installed sesh; `AGENTS.md` says how to work on sesh.
- `internal/compat` holds a vault, an encrypted export and a sync folder made by v0.1.1, and tests that sesh still reads them.
4 changes: 2 additions & 2 deletions docs/SECURITY_MODEL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ The vault provides application-level encryption on top of file-system storage:
- **Audit logging**: The `audit_log` table records access, modification, and deletion events with timestamps (never the secrets). `sesh audit` shows it. Events older than `audit.retention_days` (default 90; `0` keeps everything) are removed when the vault is opened, and `sesh audit prune` removes them on demand. It's a record for the user, not tamper-proof: anyone who can write the vault file can change it
- **The trash**: a deleted entry stays in the vault file, encrypted as before, for `trash.keep_days` (default 30), so it can be restored; then it's deleted for good, as `sesh trash remove`, `sesh trash empty` and `--purge` do at once. Until then, someone with the vault file and the master password can read it, as they could before it was deleted. `0` sends no new deletion to the trash (each is for good), but leaves what's already there until it's removed or emptied
- **Password health** (`sesh health`): reads every password and API key once, in memory, recorded as one audit event. It holds no list of them: a secret used twice is found by its SHA-256, and each secret is wiped after it's checked, though rating a password's strength makes copies of it that can't be wiped (as rating a new password does). Nothing is sent over the network.
- **Password history**: an entry's earlier secrets (the newest `history.keep`, default 10) stay in the vault file, encrypted like its secret and bound to the entry by AES-GCM associated data of their own, so an old secret can't be read as the current one. Someone with the vault file and the master password can read them, as they could when each was current. `sesh history <id> --forget N` deletes one for good. `history.keep = 0` keeps no new ones, but leaves those already kept until they're forgotten
- **Password history**: an entry's earlier secrets (the newest `history.keep`, default 10) stay in the vault file, encrypted like its secret and bound to the entry by AES-GCM associated data of their own, so an old secret can't be read as the current one. Someone with the vault file and the master password can read them, as they could when each was current. `sesh history <id> --forget N` deletes one for good from the vault; an encrypted export made before then still holds it (importing that export brings it back), and so do backups made before then. `history.keep = 0` keeps no new ones, but leaves those already kept until they're forgotten
- **WAL mode**: Write-ahead logging for safe concurrent reads

##### The master password
Expand Down Expand Up @@ -188,7 +188,7 @@ Encrypted exports (`sesh export`, its default) are wrapped in a portable envelop
- **Random 32-byte salt** per export — the same password produces different ciphertext each time
- **Envelope format** (JSON): `{version, algorithm, salt, params, ciphertext}` — salt and params are public, as in the vault's key record

Plain exports (`sesh export --format json` or `--format csv`) write secrets in plaintext and are intended for local scripting. Encrypted exports are the right choice for backups, transferring between machines, or storing in any medium the user doesn't fully trust. The same brute-force threat model applies as with the master password, so the export password has its rules: at least 8 characters, and an easy one is warned about and asked about. An export to a file is written to a private temporary file beside it, made once the password has been asked and renamed into place once the export is whole (removed if it's interrupted by Ctrl-C or an interrupt, quit, hang-up or termination signal, though not one that can't be caught), and an existing one is replaced only with `--force`. A device or pipe named instead (`/dev/stdout`, a shell's `>(…)`) is written to as it is. An encrypted export's JSON is built in memory before it's encrypted; the buffer it ends in is wiped however the export ends, though copies left behind as it grew aren't, nor the strings each secret passes through on its way into JSON or CSV.
An encrypted export holds each entry's earlier secrets too (its history), so moving a vault with one keeps them. Plain exports (`sesh export --format json` or `--format csv`) write secrets in plaintext and are intended for local scripting; they leave earlier secrets out, to expose no more than the current ones. Encrypted exports are the right choice for backups, transferring between machines, or storing in any medium the user doesn't fully trust. The same brute-force threat model applies as with the master password, so the export password has its rules: at least 8 characters, and an easy one is warned about and asked about. An export to a file is written to a private temporary file beside it, made once the password has been asked and renamed into place once the export is whole (removed if it's interrupted by Ctrl-C or an interrupt, quit, hang-up or termination signal, though not one that can't be caught), and an existing one is replaced only with `--force`. A device or pipe named instead (`/dev/stdout`, a shell's `>(…)`) is written to as it is. An encrypted export's JSON is built in memory before it's encrypted; the buffer it ends in is wiped however the export ends, though copies left behind as it grew aren't, nor the strings each secret passes through on its way into JSON or CSV.

### Changing the master password (`sesh passwd`)

Expand Down
Loading
Loading