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.
- package/README.md +60 -159
- 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
|
-
|
|
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
|
|
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
|
-
|
|
67
|
+
Bare `sefy` opens a picker over everything in the vault:
|
|
68
68
|
|
|
69
69
|
```
|
|
70
|
-
$ sefy
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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 -
|
|
87
|
-
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
##
|
|
167
|
+
## Status
|
|
268
168
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
-
|
|
275
|
-
unoptimized build makes it several times slower still.
|
|
178
|
+
## Contributing
|
|
276
179
|
|
|
277
|
-
|
|
278
|
-
|
|
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
|
-
[
|
|
185
|
+
MIT (c) [Kirill Lakhtachev](https://lacodda.com)
|