@mstone6969/vault 0.2.0 → 0.5.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 (58) hide show
  1. package/README.md +198 -6
  2. package/dist/crypto.d.ts +99 -2
  3. package/dist/crypto.d.ts.map +1 -1
  4. package/dist/errors.d.ts +122 -4
  5. package/dist/errors.d.ts.map +1 -1
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +447 -33
  9. package/dist/index.js.map +9 -7
  10. package/dist/providers.d.ts +131 -0
  11. package/dist/providers.d.ts.map +1 -0
  12. package/dist/stores/file.d.ts +190 -0
  13. package/dist/stores/file.d.ts.map +1 -0
  14. package/dist/stores/file.js +1 -0
  15. package/dist/stores/memory.d.ts +98 -7
  16. package/dist/stores/memory.d.ts.map +1 -1
  17. package/dist/stores/sqlite.d.ts +140 -9
  18. package/dist/stores/sqlite.d.ts.map +1 -1
  19. package/dist/stores/sqlite.js +47 -12
  20. package/dist/stores/sqlite.js.map +3 -3
  21. package/dist/types.d.ts +408 -17
  22. package/dist/types.d.ts.map +1 -1
  23. package/dist/vault.d.ts +554 -19
  24. package/dist/vault.d.ts.map +1 -1
  25. package/docs/README.md +10 -0
  26. package/docs/index/README.md +48 -0
  27. package/docs/index/classes/FileStore.md +341 -0
  28. package/docs/index/classes/MemoryStore.md +240 -0
  29. package/docs/index/classes/Vault.md +805 -0
  30. package/docs/index/classes/VaultError.md +371 -0
  31. package/docs/index/classes/VaultKeyError.md +370 -0
  32. package/docs/index/functions/envKey.md +43 -0
  33. package/docs/index/functions/fileKey.md +46 -0
  34. package/docs/index/functions/generateKey.md +39 -0
  35. package/docs/index/functions/importKey.md +49 -0
  36. package/docs/index/functions/isKeyProvider.md +43 -0
  37. package/docs/index/functions/open.md +67 -0
  38. package/docs/index/functions/randomValue.md +53 -0
  39. package/docs/index/functions/seal.md +56 -0
  40. package/docs/index/functions/staticKey.md +39 -0
  41. package/docs/index/type-aliases/Generator.md +58 -0
  42. package/docs/index/type-aliases/HistoryEntry.md +65 -0
  43. package/docs/index/type-aliases/KeyProvider.md +74 -0
  44. package/docs/index/type-aliases/PutOptions.md +141 -0
  45. package/docs/index/type-aliases/RekeyReport.md +37 -0
  46. package/docs/index/type-aliases/RotationContext.md +49 -0
  47. package/docs/index/type-aliases/RotationPolicy.md +142 -0
  48. package/docs/index/type-aliases/SecretRecord.md +214 -0
  49. package/docs/index/type-aliases/SecretSummary.md +56 -0
  50. package/docs/index/type-aliases/VaultEvent.md +95 -0
  51. package/docs/index/type-aliases/VaultOptions.md +142 -0
  52. package/docs/index/type-aliases/VaultStore.md +156 -0
  53. package/docs/index/variables/DEFAULT_ALPHABET.md +29 -0
  54. package/docs/index/variables/DEFAULT_HISTORY_LIMIT.md +28 -0
  55. package/docs/index/variables/DEFAULT_PREFIX.md +23 -0
  56. package/docs/stores/sqlite/README.md +11 -0
  57. package/docs/stores/sqlite/classes/SqliteStore.md +307 -0
  58. package/package.json +15 -5
@@ -0,0 +1,341 @@
1
+ [**@mstone6969/vault**](../../README.md)
2
+
3
+ ***
4
+
5
+ [@mstone6969/vault](../../README.md) / [index](../README.md) / FileStore
6
+
7
+ # Class: FileStore
8
+
9
+ Defined in: cron/vault/src/stores/file.ts:58
10
+
11
+ Keeps every record in one encrypted file.
12
+
13
+ The other stores seal values and leave the rest in the open: SQLite has an
14
+ `owner` column and a `name` column, and anyone who can read the file learns
15
+ what you keep even if they cannot read it. Here the whole index — owners,
16
+ names, metadata, timestamps, everything — is inside a single AES-256-GCM
17
+ envelope. What leaks from the file at rest is its size.
18
+
19
+ The trade is that it is loaded and written whole, so it suits hundreds of
20
+ secrets rather than millions, and one writer rather than several. Writes go
21
+ to a temporary file and are renamed into place, so a crash mid-write leaves
22
+ the previous file rather than half of a new one.
23
+
24
+ ## Remarks
25
+
26
+ The store is encrypted under its own key, separate from the master key the
27
+ [Vault](Vault.md) seals values with, so the file is two layers deep: the index
28
+ under the store's key, each value under its own data key under the vault's.
29
+ Handing both layers the same key is allowed and sometimes what you want, but
30
+ then one key opens both.
31
+
32
+ The key is resolved on the first read or write, not at construction, so a
33
+ provider that reaches for a file or a network service is asked once and only
34
+ when a record is actually wanted. A bad key surfaces from that first
35
+ operation as a [VaultKeyError](VaultKeyError.md), not from `new`.
36
+
37
+ Nothing here locks the file. Two stores writing the same path — two
38
+ processes, or two instances in one — each hold their own copy of the index
39
+ and write it whole, so the last save wins and the other's writes are gone.
40
+ Keep one writer per file.
41
+
42
+ ## Example
43
+
44
+ A vault whose names are as hidden as its values. The store's key opens the
45
+ file; the vault's key seals what is inside it.
46
+ ```ts
47
+ import { Vault, fileKey } from "@mstone6969/vault"
48
+ import { FileStore } from "@mstone6969/vault/stores/file"
49
+
50
+ const store = new FileStore("./secrets.vault", fileKey("/etc/vault-file.key"))
51
+ const vault = new Vault({ key: fileKey("/etc/vault-master.key"), store })
52
+
53
+ await vault.put("alice", "db", "hunter2") // the file is written here
54
+ await vault.open("alice", "db") // "hunter2"
55
+ ```
56
+
57
+ ## See
58
+
59
+ [VaultStore](../type-aliases/VaultStore.md) for what a store owes the vault, and `MemoryStore`
60
+ and `SqliteStore` for the two that keep their index in the open.
61
+
62
+ ## Implements
63
+
64
+ - [`VaultStore`](../type-aliases/VaultStore.md)
65
+
66
+ ## Constructors
67
+
68
+ ### Constructor
69
+
70
+ > **new FileStore**(`path`, `key`): `FileStore`
71
+
72
+ Defined in: cron/vault/src/stores/file.ts:81
73
+
74
+ #### Parameters
75
+
76
+ ##### path
77
+
78
+ `string`
79
+
80
+ Where to keep the file. Created on first write, so a path
81
+ that does not exist yet is an empty store rather than an error.
82
+
83
+ ##### key
84
+
85
+ `string` \| `CryptoKey` \| [`KeyProvider`](../type-aliases/KeyProvider.md)
86
+
87
+ The key the *file* is encrypted with: base64, already
88
+ imported, or a [KeyProvider](../type-aliases/KeyProvider.md) that finds one. Give it one of its
89
+ own, or hand it the vault's — sharing means one key opens both layers.
90
+
91
+ #### Returns
92
+
93
+ `FileStore`
94
+
95
+ #### Example
96
+
97
+ ```ts
98
+ import { generateKey } from "@mstone6969/vault"
99
+ import { FileStore } from "@mstone6969/vault/stores/file"
100
+
101
+ // Nothing is read or written until the first call.
102
+ const store = new FileStore("./secrets.vault", generateKey())
103
+ ```
104
+
105
+ ## Methods
106
+
107
+ ### get()
108
+
109
+ > **get**(`owner`, `name`): `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md) \| `null`\>
110
+
111
+ Defined in: cron/vault/src/stores/file.ts:192
112
+
113
+ One record, or null when there is none under that name.
114
+
115
+ #### Parameters
116
+
117
+ ##### owner
118
+
119
+ `string`
120
+
121
+ Whose record to look for.
122
+
123
+ ##### name
124
+
125
+ `string`
126
+
127
+ What it is called.
128
+
129
+ #### Returns
130
+
131
+ `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md) \| `null`\>
132
+
133
+ The record, or null.
134
+
135
+ #### Throws
136
+
137
+ [VaultKeyError](VaultKeyError.md) on the first call if the file is not a vault file,
138
+ or the key does not open it.
139
+
140
+ #### Implementation of
141
+
142
+ `VaultStore.get`
143
+
144
+ ***
145
+
146
+ ### list()
147
+
148
+ > **list**(`owner`): `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)[]\>
149
+
150
+ Defined in: cron/vault/src/stores/file.ts:206
151
+
152
+ Every record one owner holds.
153
+
154
+ The filtering happens in memory, over the whole index — there is no
155
+ per-owner slice of the file to read on its own.
156
+
157
+ #### Parameters
158
+
159
+ ##### owner
160
+
161
+ `string`
162
+
163
+ Whose records to return.
164
+
165
+ #### Returns
166
+
167
+ `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)[]\>
168
+
169
+ That owner's records, in whatever order they were written.
170
+
171
+ #### Throws
172
+
173
+ [VaultKeyError](VaultKeyError.md) on the first call if the file cannot be opened.
174
+
175
+ #### Implementation of
176
+
177
+ `VaultStore.list`
178
+
179
+ ***
180
+
181
+ ### all()
182
+
183
+ > **all**(): `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)[]\>
184
+
185
+ Defined in: cron/vault/src/stores/file.ts:229
186
+
187
+ Every record, whoever owns it.
188
+
189
+ #### Returns
190
+
191
+ `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)[]\>
192
+
193
+ All of them. Only `rekey` and `purgeExpired` need this.
194
+
195
+ #### Throws
196
+
197
+ [VaultKeyError](VaultKeyError.md) on the first call if the file cannot be opened.
198
+
199
+ #### Example
200
+
201
+ Check a file opens under the key you think it does, before trusting it.
202
+ ```ts
203
+ import { VaultKeyError } from "@mstone6969/vault"
204
+ import { FileStore } from "@mstone6969/vault/stores/file"
205
+
206
+ try {
207
+ await new FileStore("./secrets.vault", process.env.VAULT_FILE_KEY!).all()
208
+ } catch (error) {
209
+ if (error instanceof VaultKeyError) console.error(error.message)
210
+ }
211
+ ```
212
+
213
+ #### Implementation of
214
+
215
+ `VaultStore.all`
216
+
217
+ ***
218
+
219
+ ### put()
220
+
221
+ > **put**(`record`): `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)\>
222
+
223
+ Defined in: cron/vault/src/stores/file.ts:245
224
+
225
+ Writes a record, replacing any under the same owner and name.
226
+
227
+ The whole file is re-sealed and rewritten, so writes cost the size of the
228
+ store rather than of the record.
229
+
230
+ #### Parameters
231
+
232
+ ##### record
233
+
234
+ [`SecretRecord`](../type-aliases/SecretRecord.md)
235
+
236
+ The record to keep. Stored as given: finality, expiry and
237
+ history are the vault's rules, not the store's.
238
+
239
+ #### Returns
240
+
241
+ `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)\>
242
+
243
+ The same record, so callers can chain.
244
+
245
+ #### Throws
246
+
247
+ [VaultKeyError](VaultKeyError.md) if the file cannot be opened, or the key cannot be
248
+ resolved.
249
+
250
+ #### Implementation of
251
+
252
+ `VaultStore.put`
253
+
254
+ ***
255
+
256
+ ### remove()
257
+
258
+ > **remove**(`owner`, `name`): `Promise`\<`boolean`\>
259
+
260
+ Defined in: cron/vault/src/stores/file.ts:272
261
+
262
+ Deletes a record, returning false when there was nothing to delete.
263
+
264
+ #### Parameters
265
+
266
+ ##### owner
267
+
268
+ `string`
269
+
270
+ Whose record to delete.
271
+
272
+ ##### name
273
+
274
+ `string`
275
+
276
+ What it is called.
277
+
278
+ #### Returns
279
+
280
+ `Promise`\<`boolean`\>
281
+
282
+ Whether a record was there to delete. The file is only rewritten
283
+ when one was.
284
+
285
+ #### Throws
286
+
287
+ [VaultKeyError](VaultKeyError.md) if the file cannot be opened.
288
+
289
+ #### Implementation of
290
+
291
+ `VaultStore.remove`
292
+
293
+ ***
294
+
295
+ ### forget()
296
+
297
+ > **forget**(): `void`
298
+
299
+ Defined in: cron/vault/src/stores/file.ts:306
300
+
301
+ Forgets what it read, so the next call goes back to the file.
302
+
303
+ The point of a store that holds its whole index in memory is that reads
304
+ are free; the cost is that a file another process rewrote is invisible
305
+ until you say this. It also drops the decrypted index, which is the only
306
+ place the names live in the clear.
307
+
308
+ #### Returns
309
+
310
+ `void`
311
+
312
+ #### Example
313
+
314
+ ```ts
315
+ import { FileStore } from "@mstone6969/vault/stores/file"
316
+
317
+ const store = new FileStore("./secrets.vault", process.env.VAULT_FILE_KEY!)
318
+ await store.all() // reads and decrypts the file
319
+ store.forget()
320
+ await store.all() // reads it again
321
+ ```
322
+
323
+ ***
324
+
325
+ ### destroy()
326
+
327
+ > **destroy**(): `Promise`\<`void`\>
328
+
329
+ Defined in: cron/vault/src/stores/file.ts:319
330
+
331
+ Deletes the file and everything in it.
332
+
333
+ The in-memory index is emptied first, so a store that is used again
334
+ writes a fresh file rather than resurrecting what was there.
335
+
336
+ #### Returns
337
+
338
+ `Promise`\<`void`\>
339
+
340
+ Nothing. A file that is already gone is the outcome wanted, not
341
+ an error.
@@ -0,0 +1,240 @@
1
+ [**@mstone6969/vault**](../../README.md)
2
+
3
+ ***
4
+
5
+ [@mstone6969/vault](../../README.md) / [index](../README.md) / MemoryStore
6
+
7
+ # Class: MemoryStore
8
+
9
+ Defined in: cron/vault/src/stores/memory.ts:24
10
+
11
+ Keeps sealed values in a Map. Handy for tests and short-lived processes.
12
+
13
+ Nothing is written anywhere: when the process ends every record goes with it.
14
+ That is the point — a test gets a clean vault per run without a file to
15
+ create and delete, and a short-lived worker holding a few credentials in
16
+ memory leaves nothing behind on disk.
17
+
18
+ ## Remarks
19
+
20
+ Like every [VaultStore](../type-aliases/VaultStore.md), this persists records exactly as given and
21
+ enforces nothing: finality, expiry and history are rules the [Vault](Vault.md)
22
+ applies before it calls [MemoryStore.put](#put).
23
+
24
+ ## Example
25
+
26
+ ```ts
27
+ import { generateKey, MemoryStore, Vault } from "@mstone6969/vault"
28
+
29
+ const vault = new Vault({ key: generateKey(), store: new MemoryStore() })
30
+ await vault.put("alice", "db-password", "hunter2")
31
+ ```
32
+
33
+ ## See
34
+
35
+ [FileStore](FileStore.md) for a store that survives the process.
36
+
37
+ ## Implements
38
+
39
+ - [`VaultStore`](../type-aliases/VaultStore.md)
40
+
41
+ ## Constructors
42
+
43
+ ### Constructor
44
+
45
+ > **new MemoryStore**(): `MemoryStore`
46
+
47
+ Defined in: cron/vault/src/stores/memory.ts:41
48
+
49
+ Makes an empty store.
50
+
51
+ #### Returns
52
+
53
+ `MemoryStore`
54
+
55
+ #### Remarks
56
+
57
+ Takes nothing: there is no file to name and no key to hand it, since
58
+ records never leave the process.
59
+
60
+ #### Example
61
+
62
+ ```ts
63
+ import { MemoryStore } from "@mstone6969/vault"
64
+
65
+ const store = new MemoryStore()
66
+ ```
67
+
68
+ ## Methods
69
+
70
+ ### get()
71
+
72
+ > **get**(`owner`, `name`): `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md) \| `null`\>
73
+
74
+ Defined in: cron/vault/src/stores/memory.ts:73
75
+
76
+ One record, or null when there is none under that name.
77
+
78
+ #### Parameters
79
+
80
+ ##### owner
81
+
82
+ `string`
83
+
84
+ Whose entry to look for.
85
+
86
+ ##### name
87
+
88
+ `string`
89
+
90
+ What the entry is called.
91
+
92
+ #### Returns
93
+
94
+ `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md) \| `null`\>
95
+
96
+ The stored record, or null if this owner has nothing by that
97
+ name. The record itself is returned, not a copy, so callers must not
98
+ mutate it.
99
+
100
+ #### Example
101
+
102
+ ```ts
103
+ import { MemoryStore } from "@mstone6969/vault"
104
+
105
+ const store = new MemoryStore()
106
+ const record = await store.get("alice", "db-password") // null
107
+ ```
108
+
109
+ #### Implementation of
110
+
111
+ `VaultStore.get`
112
+
113
+ ***
114
+
115
+ ### list()
116
+
117
+ > **list**(`owner`): `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)[]\>
118
+
119
+ Defined in: cron/vault/src/stores/memory.ts:85
120
+
121
+ Every record one owner holds.
122
+
123
+ #### Parameters
124
+
125
+ ##### owner
126
+
127
+ `string`
128
+
129
+ Whose entries to return.
130
+
131
+ #### Returns
132
+
133
+ `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)[]\>
134
+
135
+ That owner's records, in no particular order — the vault's
136
+ `list` sorts them. Empty for an owner the store has never heard of.
137
+
138
+ #### See
139
+
140
+ [MemoryStore.all](#all) when the caller needs every owner's records.
141
+
142
+ #### Implementation of
143
+
144
+ `VaultStore.list`
145
+
146
+ ***
147
+
148
+ ### all()
149
+
150
+ > **all**(): `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)[]\>
151
+
152
+ Defined in: cron/vault/src/stores/memory.ts:99
153
+
154
+ Every record, whoever owns it.
155
+
156
+ #### Returns
157
+
158
+ `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)[]\>
159
+
160
+ All records the store holds, in no particular order.
161
+
162
+ #### Remarks
163
+
164
+ This is the only place anything reaches across owners, and it exists for
165
+ the vault-wide operations — `rekey`, `reseal` and `purgeExpired` — which
166
+ have to touch every entry. Ordinary reads go through
167
+ [MemoryStore.list](#list).
168
+
169
+ #### Implementation of
170
+
171
+ `VaultStore.all`
172
+
173
+ ***
174
+
175
+ ### put()
176
+
177
+ > **put**(`record`): `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)\>
178
+
179
+ Defined in: cron/vault/src/stores/memory.ts:113
180
+
181
+ Writes a record, replacing any under the same owner and name.
182
+
183
+ #### Parameters
184
+
185
+ ##### record
186
+
187
+ [`SecretRecord`](../type-aliases/SecretRecord.md)
188
+
189
+ The record to keep, stored as given.
190
+
191
+ #### Returns
192
+
193
+ `Promise`\<[`SecretRecord`](../type-aliases/SecretRecord.md)\>
194
+
195
+ The same record, so a caller can write and use the result in one
196
+ step.
197
+
198
+ #### Remarks
199
+
200
+ An `isFinal` record is replaced here without complaint: refusing that is
201
+ the vault's job, and it checks before it calls this.
202
+
203
+ #### Implementation of
204
+
205
+ `VaultStore.put`
206
+
207
+ ***
208
+
209
+ ### remove()
210
+
211
+ > **remove**(`owner`, `name`): `Promise`\<`boolean`\>
212
+
213
+ Defined in: cron/vault/src/stores/memory.ts:126
214
+
215
+ Deletes a record, returning false when there was nothing to delete.
216
+
217
+ #### Parameters
218
+
219
+ ##### owner
220
+
221
+ `string`
222
+
223
+ Whose entry to delete.
224
+
225
+ ##### name
226
+
227
+ `string`
228
+
229
+ What the entry is called.
230
+
231
+ #### Returns
232
+
233
+ `Promise`\<`boolean`\>
234
+
235
+ True if a record was removed, false if there was none — so a
236
+ caller can tell a delete from a no-op.
237
+
238
+ #### Implementation of
239
+
240
+ `VaultStore.remove`