sefy-cli 0.7.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +60 -159
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  <a href="https://github.com/lacodda/sefy/blob/main/LICENSE"><img src="https://img.shields.io/crates/l/sefy?style=flat-square" alt="MIT"></a>
8
8
  </p>
9
9
 
10
- # sefy
10
+ > An encrypted store for notes, credentials and files that does not announce itself: one file with no header, no extension it must keep, and no name that gives it away.
11
11
 
12
12
  Every way of storing secrets announces itself. A `.kdbx` file says "password
13
13
  database". age and gpg write a header. VeraCrypt wants a container and a mount.
@@ -50,7 +50,7 @@ Master password:
50
50
  created /home/you/backups/notes.bak
51
51
  ```
52
52
 
53
- Put things in. Notes, logins, cards, ssh keys, and files kept byte for byte.
53
+ Put things in - notes, logins, cards, ssh keys, and files kept byte for byte:
54
54
 
55
55
  ```
56
56
  $ sefy add note "bank card" --text "PIN 4815" --tag money
@@ -64,142 +64,64 @@ $ sefy add file ~/.ssh/id_ed25519 --tag keys
64
64
  added "id_ed25519" as 3
65
65
  ```
66
66
 
67
- Look around.
67
+ Bare `sefy` opens a picker over everything in the vault:
68
68
 
69
69
  ```
70
- $ sefy ls
71
- 3 id_ed25519 file [keys]
72
- 2 mail login [mail]
73
- 1 bank card note [money]
74
-
75
- $ sefy show mail
76
- id: 2
77
- title: mail
78
- kind: login
79
- tags: mail
80
- login: someone@example.com
81
- password: <hidden — use sefy get>
82
- url: https://mail.example.com
70
+ $ sefy
71
+ ? Item >
72
+ > bank card note [money]
73
+ mail login [mail]
74
+ id_ed25519 file [keys]
83
75
  ```
84
76
 
85
77
  Take a secret out. It goes to the clipboard and is taken back off after 45
86
- seconds - sefy clears it only if the secret is still what is sitting there, so
87
- anything you copied meanwhile is left alone.
78
+ seconds - and only if the secret is still what is sitting there, so anything
79
+ you copied meanwhile is left alone.
88
80
 
89
81
  ```
90
82
  $ sefy get mail
91
83
  copied password of "mail" to the clipboard; clearing in 45s
92
84
  clipboard cleared
93
-
94
- $ sefy get "bank card" --stdout
95
- PIN 4815
96
- ```
97
-
98
- Items are addressed by title, by an exact id, or by text to search for. When
99
- your words could mean more than one thing, sefy shows what they could mean
100
- instead of guessing:
101
-
102
- ```
103
- $ sefy get ma
104
- error: 2 items match "ma":
105
- 4 mailing list note
106
- 2 mail login
107
- narrow the text, or use an id
108
- ```
109
-
110
- Several machines? `sefy sync` carries the vault through a transport and folds
111
- what comes back into this one:
112
-
113
- ```
114
- $ sefy sync
115
- Master password:
116
- synced "vault" through github
117
- merged: 2 added, 0 updated, 14 unchanged
118
- ```
119
-
120
- Or fold in a copy you carried across by hand. Either way, where the two disagree
121
- about the same item, sefy keeps both versions rather than letting a timestamp
122
- decide which password you get to keep:
123
-
124
- ```
125
- $ sefy merge ~/from-laptop.bak
126
- Password for /home/you/from-laptop.bak:
127
- merged: 1 added, 1 updated, 1 unchanged
128
-
129
- 1 item changed on both sides and could not be resolved here.
130
- This vault's version was kept; the incoming one is beside it:
131
- "mail" → also kept as "mail (conflicted copy)"
132
- Compare them, keep the right one, and remove the other.
133
- ```
134
-
135
- A vault is never a trap. `sefy export` writes everything back out as plain
136
- JSON - which is exactly as sensitive as the vault and protects nothing, so the
137
- command makes you say so out loud:
138
-
139
85
  ```
140
- $ sefy export -o backup.json
141
- error: export writes every secret in this vault in the clear
142
- the resulting file protects nothing — encrypt it, or delete it when done
143
- pass --i-know-this-writes-plaintext to go ahead
144
- ```
145
-
146
- Full command reference: **[lacodda.github.io/sefy](https://lacodda.github.io/sefy/)**.
147
86
 
148
- ## Transports
149
-
150
- Carrying a vault to another machine is the job of a **plugin**: any executable
151
- named `sefy-plugin-*`, found in sefy's data directory or on `PATH`. sefy knows
152
- nothing about git, FTP or any cloud drive - it asks a plugin what it can do and
153
- what happened.
154
-
155
- Two transports ship alongside the CLI, and neither stores a credential of its
156
- own - each authenticates the way the machine already does:
157
-
158
- - **github** keeps the vault in a git repository. Point `SEFY_GITHUB_REPO` at
159
- one; version history comes free with it.
160
- - **sftp** keeps it on a server you control, over OpenSSH. Point
161
- `SEFY_SFTP_DESTINATION` at `you@server:/path`; nothing lands there but the
162
- blob.
87
+ A new account needs a new password, and `sefy gen` makes one and keeps it in
88
+ the same breath - stored as a login, then put on the clipboard for the sign-up
89
+ form:
163
90
 
164
91
  ```
165
- $ sefy plugin list
166
- future 9.0.0 unusable: it speaks protocol 99 and this build speaks 1
167
- github 0.7.0 pull, push
168
- sftp 0.7.0 pull, push
92
+ $ sefy gen --save forum --login someone@example.com --url https://forum.example.com
93
+ added "forum" as 4
94
+ generated 20 characters: 130 bits of entropy, strength 4/4
95
+ copied it to the clipboard; clearing in 45s
169
96
  ```
170
97
 
171
- With more than one installed, sefy asks which rather than choosing where your
172
- vault goes: `sefy sync --transport sftp`, or `SEFY_TRANSPORT=sftp` once.
173
-
174
- A transport is handed the **path of the sealed file** and nothing else - no
175
- master password, no key, no item. What it carries is what anyone would find on
176
- your disk: a blob it cannot read. That is also why a plugin cannot merge: it
177
- moves the other copy to a file, and sefy folds the two together itself, where
178
- both sides can actually be read.
98
+ Items are addressed by title, by an exact id, or by text to search for; when
99
+ the words could mean more than one thing, sefy shows what they could mean
100
+ rather than guessing. `sefy open` loads the site and puts the password on the
101
+ clipboard in one step, `sefy sync` carries the vault through a transport and
102
+ folds what comes back into this one, and `sefy status` says what you are
103
+ holding without saying what is in it.
179
104
 
180
- Broken plugins are listed with the reason rather than skipped: an omitted line
181
- would look exactly like a plugin that was never installed.
105
+ Every command, with its flags: **[the reference](https://lacodda.github.io/sefy/reference/commands/)**.
182
106
 
183
- The protocol is small enough to implement in a shell script - manifest on
184
- `--manifest`, one JSON request on stdin for `run`. Writing one:
185
- [plugin reference](https://lacodda.github.io/sefy/reference/plugin/) ·
186
- [ADR-0002](https://github.com/lacodda/sefy/blob/main/docs/adr/0002-plugin-protocol.md).
107
+ ## What you get
187
108
 
188
- ## How it works
189
-
190
- - The master password is stretched into a key with **Argon2id**.
191
- - The whole SQLite database is sealed with **XChaCha20-Poly1305** (AEAD).
192
- - The file on disk is `salt ‖ nonce ‖ ciphertext`. Salt and nonce are fresh on
193
- every save, so two saves of identical content share no prefix - and the
194
- format version lives *inside* the ciphertext, because a version byte in the
195
- clear would be the signature the format exists to avoid.
196
- - The decrypted database exists **only in memory**. SQLite is never given a
197
- path, so no page, journal or temporary file lands on disk.
198
- - Saves are atomic: ciphertext goes to a temporary file, is synced, and is
199
- renamed over the vault. A crash leaves either the old vault or the new one,
200
- and never plaintext.
201
-
202
- Details and rationale: [ADR-0001](https://github.com/lacodda/sefy/blob/main/docs/adr/0001-vault-file-format-and-cryptography.md).
109
+ - **A file that looks like nothing.** No magic bytes, no header, no extension
110
+ convention - salt and nonce fresh on every save, so two saves of identical
111
+ content share no prefix.
112
+ - **Notes, logins, cards, ssh keys and files** in one vault, tagged and
113
+ searchable, with files kept byte for byte.
114
+ - **Passwords made where they are kept.** `sefy gen` draws random characters,
115
+ pronounceable ones or a diceware passphrase (English or Russian lists built
116
+ in), reports its exact entropy beside an offline zxcvbn score, and can save
117
+ the result as a login in the same command.
118
+ - **Transports, not lock-in.** `sefy sync` carries the vault through a
119
+ `sefy-plugin-*` executable - github and sftp ship today - and folds what
120
+ comes back in without a credential ever passing through the transport.
121
+ - **Merge instead of overwrite.** Where two copies disagree about an item,
122
+ both are kept rather than letting a timestamp pick a winner.
123
+ - **A vault that is never a trap.** `export` writes plaintext JSON only after
124
+ you say so explicitly.
203
125
 
204
126
  ## Install
205
127
 
@@ -234,51 +156,30 @@ place any transport the archive carries into sefy's plugins directory, so
234
156
  Shell completions: `sefy completions bash` (also `zsh`, `fish`, `powershell`,
235
157
  `elvish`).
236
158
 
237
- ## Stability
238
-
239
- The **vault file format is stable at version 1**. Files written by this release
240
- will stay readable: any future change to the format arrives as version 2, able
241
- to read version 1 and migrate it. The Argon2 parameters are part of that
242
- promise, not a tuning knob.
243
-
244
- The database inside the ciphertext is versioned separately, and it does move:
245
- 0.2.0 added an identity to items so two copies of a vault can be merged, and
246
- 0.7.0 replaced the credential table with named fields so that a kind of record
247
- costs a template rather than a table. A vault from an earlier release opens and
248
- is migrated on the way in; the file on disk does not change shape.
249
-
250
- What an older build makes of it afterwards depends on the change. The 0.2.0
251
- migration left everything readable by 0.1.x. The 0.7.0 one does not: a login is
252
- now a kind 0.6.0 has never heard of, so that build lists it, exports it and
253
- syncs it while saying to upgrade before reading it. That is the
254
- forward-compatibility contract from 0.6.0 doing its job rather than a break -
255
- nothing is lost, and the newer build reads everything - but it is why the
256
- rename happened before 1.0 rather than after.
257
-
258
- The **plugin protocol is at version 1** as of 0.3.0. 0.4.0 put it to work and
259
- 0.5.0 added a second transport of a different shape without changing a field of
260
- it, which is the evidence that it was not built around the first one. Optional
261
- fields may be added to the manifest without breaking a plugin that predates
262
- them; changing what an existing field means would arrive as version 2, with both
263
- accepted for a time.
159
+ ## Documentation
264
160
 
265
- Released versions and what landed in each: [CHANGELOG on the Releases page](https://github.com/lacodda/sefy/releases).
161
+ Full command reference, concepts and guides:
162
+ **[lacodda.github.io/sefy](https://lacodda.github.io/sefy/)** - including
163
+ [how the vault works](https://lacodda.github.io/sefy/concepts/vault-format/)
164
+ and the [plugin reference](https://lacodda.github.io/sefy/reference/plugin/)
165
+ for transports.
266
166
 
267
- ## Building
167
+ ## Status
268
168
 
269
- ```
270
- cargo build --release # workspace: sefy-core (library) + sefy (CLI)
271
- cargo test # unit, integration and doc tests
272
- ```
169
+ The vault file format is stable at version 1, and the plugin protocol at
170
+ version 1 since 0.3.0; both promises hold across every release below. The
171
+ database schema inside the ciphertext moves between releases, and older
172
+ builds keep reading a vault safely even when they cannot see everything in
173
+ it - the [versions and compatibility](https://lacodda.github.io/sefy/concepts/versions/)
174
+ page has the detail.
175
+
176
+ Released versions and what landed in each: [CHANGELOG on the Releases page](https://github.com/lacodda/sefy/releases).
273
177
 
274
- Use a release build for daily work: Argon2id is deliberately expensive, and an
275
- unoptimized build makes it several times slower still.
178
+ ## Contributing
276
179
 
277
- The library is published separately as [`sefy-core`](https://crates.io/crates/sefy-core)
278
- if you want vaults from your own code. The documentation site lives in
279
- [`docs/`](https://github.com/lacodda/sefy/tree/main/docs); architecture decision
280
- records are in [`docs/adr/`](https://github.com/lacodda/sefy/tree/main/docs/adr).
180
+ Building the workspace, repository layout and commit conventions:
181
+ [CONTRIBUTING.md](https://github.com/lacodda/sefy/blob/main/CONTRIBUTING.md).
281
182
 
282
183
  ## License
283
184
 
284
- [MIT](https://github.com/lacodda/sefy/blob/main/LICENSE)
185
+ MIT (c) [Kirill Lakhtachev](https://lacodda.com)
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "sefy-cli",
3
- "version": "0.7.1",
3
+ "version": "0.9.0",
4
4
  "sefy": {
5
- "binary": "v0.7.1"
5
+ "binary": "v0.9.0"
6
6
  },
7
7
  "description": "An inconspicuous encrypted store for notes, credentials and files",
8
8
  "license": "MIT",