@mstone6969/vault 0.1.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.
- package/README.md +236 -10
- package/dist/crypto.d.ts +99 -2
- package/dist/crypto.d.ts.map +1 -1
- package/dist/errors.d.ts +122 -4
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +447 -32
- package/dist/index.js.map +9 -7
- package/dist/providers.d.ts +131 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/stores/file.d.ts +190 -0
- package/dist/stores/file.d.ts.map +1 -0
- package/dist/stores/file.js +1 -0
- package/dist/stores/memory.d.ts +98 -6
- package/dist/stores/memory.d.ts.map +1 -1
- package/dist/stores/sqlite.d.ts +140 -8
- package/dist/stores/sqlite.d.ts.map +1 -1
- package/dist/stores/sqlite.js +49 -7
- package/dist/stores/sqlite.js.map +3 -3
- package/dist/types.d.ts +411 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/vault.d.ts +561 -20
- package/dist/vault.d.ts.map +1 -1
- package/docs/README.md +10 -0
- package/docs/index/README.md +48 -0
- package/docs/index/classes/FileStore.md +341 -0
- package/docs/index/classes/MemoryStore.md +240 -0
- package/docs/index/classes/Vault.md +805 -0
- package/docs/index/classes/VaultError.md +371 -0
- package/docs/index/classes/VaultKeyError.md +370 -0
- package/docs/index/functions/envKey.md +43 -0
- package/docs/index/functions/fileKey.md +46 -0
- package/docs/index/functions/generateKey.md +39 -0
- package/docs/index/functions/importKey.md +49 -0
- package/docs/index/functions/isKeyProvider.md +43 -0
- package/docs/index/functions/open.md +67 -0
- package/docs/index/functions/randomValue.md +53 -0
- package/docs/index/functions/seal.md +56 -0
- package/docs/index/functions/staticKey.md +39 -0
- package/docs/index/type-aliases/Generator.md +58 -0
- package/docs/index/type-aliases/HistoryEntry.md +65 -0
- package/docs/index/type-aliases/KeyProvider.md +74 -0
- package/docs/index/type-aliases/PutOptions.md +141 -0
- package/docs/index/type-aliases/RekeyReport.md +37 -0
- package/docs/index/type-aliases/RotationContext.md +49 -0
- package/docs/index/type-aliases/RotationPolicy.md +142 -0
- package/docs/index/type-aliases/SecretRecord.md +214 -0
- package/docs/index/type-aliases/SecretSummary.md +56 -0
- package/docs/index/type-aliases/VaultEvent.md +95 -0
- package/docs/index/type-aliases/VaultOptions.md +142 -0
- package/docs/index/type-aliases/VaultStore.md +156 -0
- package/docs/index/variables/DEFAULT_ALPHABET.md +29 -0
- package/docs/index/variables/DEFAULT_HISTORY_LIMIT.md +28 -0
- package/docs/index/variables/DEFAULT_PREFIX.md +23 -0
- package/docs/stores/sqlite/README.md +11 -0
- package/docs/stores/sqlite/classes/SqliteStore.md +307 -0
- package/package.json +15 -5
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / envKey
|
|
6
|
+
|
|
7
|
+
# Function: envKey()
|
|
8
|
+
|
|
9
|
+
> **envKey**(`name`): [`KeyProvider`](../type-aliases/KeyProvider.md)
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/providers.ts:92
|
|
12
|
+
|
|
13
|
+
A key from an environment variable.
|
|
14
|
+
|
|
15
|
+
## Parameters
|
|
16
|
+
|
|
17
|
+
### name
|
|
18
|
+
|
|
19
|
+
`string`
|
|
20
|
+
|
|
21
|
+
The variable to read, at the moment the key is first needed —
|
|
22
|
+
so a process that loads its environment after building the vault still
|
|
23
|
+
works.
|
|
24
|
+
|
|
25
|
+
## Returns
|
|
26
|
+
|
|
27
|
+
[`KeyProvider`](../type-aliases/KeyProvider.md)
|
|
28
|
+
|
|
29
|
+
A provider that reads `process.env[name]`.
|
|
30
|
+
|
|
31
|
+
## Throws
|
|
32
|
+
|
|
33
|
+
[VaultKeyError](../classes/VaultKeyError.md) when the variable is unset or empty, at the first
|
|
34
|
+
operation that needs a key rather than at construction.
|
|
35
|
+
|
|
36
|
+
## Example
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { Vault, MemoryStore, envKey } from "@mstone6969/vault"
|
|
40
|
+
|
|
41
|
+
const vault = new Vault({ key: envKey("VAULT_KEY"), store: new MemoryStore() })
|
|
42
|
+
await vault.put("alice", "db", "hunter2") // throws here if VAULT_KEY is unset
|
|
43
|
+
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / fileKey
|
|
6
|
+
|
|
7
|
+
# Function: fileKey()
|
|
8
|
+
|
|
9
|
+
> **fileKey**(`path`): [`KeyProvider`](../type-aliases/KeyProvider.md)
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/providers.ts:125
|
|
12
|
+
|
|
13
|
+
A key from a file — the usual way to keep one off the process list and out
|
|
14
|
+
of shell history. Whitespace around it is ignored, so a trailing newline
|
|
15
|
+
from `openssl rand -base64 32 > key` does no harm.
|
|
16
|
+
|
|
17
|
+
## Parameters
|
|
18
|
+
|
|
19
|
+
### path
|
|
20
|
+
|
|
21
|
+
`string`
|
|
22
|
+
|
|
23
|
+
The key file, read at the moment the key is first needed. It is
|
|
24
|
+
read once and kept, so replacing the file later does not change the key a
|
|
25
|
+
running vault uses.
|
|
26
|
+
|
|
27
|
+
## Returns
|
|
28
|
+
|
|
29
|
+
[`KeyProvider`](../type-aliases/KeyProvider.md)
|
|
30
|
+
|
|
31
|
+
A provider that reads and trims the file.
|
|
32
|
+
|
|
33
|
+
## Throws
|
|
34
|
+
|
|
35
|
+
[VaultKeyError](../classes/VaultKeyError.md) when the file is missing, or holds nothing but
|
|
36
|
+
whitespace.
|
|
37
|
+
|
|
38
|
+
## Example
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { Vault, FileStore, fileKey } from "@mstone6969/vault"
|
|
42
|
+
|
|
43
|
+
// The store's own key opens the file; the vault's key seals the values.
|
|
44
|
+
const store = new FileStore("./secrets.vault", fileKey("/etc/vault.key"))
|
|
45
|
+
const vault = new Vault({ key: fileKey("/etc/vault.key"), store })
|
|
46
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / generateKey
|
|
6
|
+
|
|
7
|
+
# Function: generateKey()
|
|
8
|
+
|
|
9
|
+
> **generateKey**(): `string`
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/crypto.ts:47
|
|
12
|
+
|
|
13
|
+
A new random key, base64 encoded — store it somewhere safe.
|
|
14
|
+
|
|
15
|
+
## Returns
|
|
16
|
+
|
|
17
|
+
`string`
|
|
18
|
+
|
|
19
|
+
32 random bytes, base64. Nothing keeps a copy, so a key that is lost
|
|
20
|
+
takes every value sealed under it with it.
|
|
21
|
+
|
|
22
|
+
## Remarks
|
|
23
|
+
|
|
24
|
+
Used for master keys you generate once and keep, and — inside the vault — for
|
|
25
|
+
the throwaway data key minted per written value.
|
|
26
|
+
|
|
27
|
+
## Example
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { generateKey, importKey, seal } from "@mstone6969/vault"
|
|
31
|
+
|
|
32
|
+
const material = generateKey()
|
|
33
|
+
const key = await importKey(material)
|
|
34
|
+
const sealed = await seal(key, "hunter2")
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## See
|
|
38
|
+
|
|
39
|
+
[importKey](importKey.md) to turn the string back into a usable key.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / importKey
|
|
6
|
+
|
|
7
|
+
# Function: importKey()
|
|
8
|
+
|
|
9
|
+
> **importKey**(`base64Key`): `Promise`\<`CryptoKey`\>
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/crypto.ts:72
|
|
12
|
+
|
|
13
|
+
Imports a base64 key produced by [generateKey](generateKey.md).
|
|
14
|
+
|
|
15
|
+
## Parameters
|
|
16
|
+
|
|
17
|
+
### base64Key
|
|
18
|
+
|
|
19
|
+
`string`
|
|
20
|
+
|
|
21
|
+
The key material, base64 encoded, decoding to exactly 32
|
|
22
|
+
bytes.
|
|
23
|
+
|
|
24
|
+
## Returns
|
|
25
|
+
|
|
26
|
+
`Promise`\<`CryptoKey`\>
|
|
27
|
+
|
|
28
|
+
A key usable with [seal](seal.md) and [open](open.md).
|
|
29
|
+
|
|
30
|
+
## Throws
|
|
31
|
+
|
|
32
|
+
[VaultKeyError](../classes/VaultKeyError.md) When the decoded material is not 32 bytes. Note
|
|
33
|
+
that base64 decoding is lenient: rubbish that is not base64 at all decodes
|
|
34
|
+
to too few bytes and surfaces here as a length complaint rather than a
|
|
35
|
+
parse error.
|
|
36
|
+
|
|
37
|
+
## Remarks
|
|
38
|
+
|
|
39
|
+
The imported key is not extractable, so the raw bytes cannot be read back out
|
|
40
|
+
of it — a value only ever leaves via [open](open.md).
|
|
41
|
+
|
|
42
|
+
## Example
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { importKey, MemoryStore, Vault } from "@mstone6969/vault"
|
|
46
|
+
|
|
47
|
+
const key = await importKey(process.env.VAULT_KEY!)
|
|
48
|
+
const vault = new Vault({ key, store: new MemoryStore() })
|
|
49
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / isKeyProvider
|
|
6
|
+
|
|
7
|
+
# Function: isKeyProvider()
|
|
8
|
+
|
|
9
|
+
> **isKeyProvider**(`value`): `value is KeyProvider`
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/providers.ts:160
|
|
12
|
+
|
|
13
|
+
True when something is a provider rather than a key.
|
|
14
|
+
|
|
15
|
+
[Vault](../classes/Vault.md) and [FileStore](../classes/FileStore.md) accept either, and use this to tell them
|
|
16
|
+
apart: anything with a callable `key` is a provider, everything else is key
|
|
17
|
+
material to be wrapped in [staticKey](staticKey.md). A `CryptoKey` has no `key`
|
|
18
|
+
method, so it never matches.
|
|
19
|
+
|
|
20
|
+
## Parameters
|
|
21
|
+
|
|
22
|
+
### value
|
|
23
|
+
|
|
24
|
+
`unknown`
|
|
25
|
+
|
|
26
|
+
Anything — key material, a provider, or neither.
|
|
27
|
+
|
|
28
|
+
## Returns
|
|
29
|
+
|
|
30
|
+
`value is KeyProvider`
|
|
31
|
+
|
|
32
|
+
Whether `value` has a callable `key`, narrowing it to
|
|
33
|
+
[KeyProvider](../type-aliases/KeyProvider.md).
|
|
34
|
+
|
|
35
|
+
## Example
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { envKey, isKeyProvider, staticKey } from "@mstone6969/vault"
|
|
39
|
+
|
|
40
|
+
isKeyProvider(envKey("VAULT_KEY")) // true
|
|
41
|
+
isKeyProvider(staticKey("...")) // true
|
|
42
|
+
isKeyProvider("base64-key-material") // false
|
|
43
|
+
```
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / open
|
|
6
|
+
|
|
7
|
+
# Function: open()
|
|
8
|
+
|
|
9
|
+
> **open**(`key`, `sealed`): `Promise`\<`string`\>
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/crypto.ts:152
|
|
12
|
+
|
|
13
|
+
Opens a value sealed by [seal](seal.md).
|
|
14
|
+
|
|
15
|
+
## Parameters
|
|
16
|
+
|
|
17
|
+
### key
|
|
18
|
+
|
|
19
|
+
`CryptoKey`
|
|
20
|
+
|
|
21
|
+
The key it was sealed under.
|
|
22
|
+
|
|
23
|
+
### sealed
|
|
24
|
+
|
|
25
|
+
`string`
|
|
26
|
+
|
|
27
|
+
The `iv:payload` string to open.
|
|
28
|
+
|
|
29
|
+
## Returns
|
|
30
|
+
|
|
31
|
+
`Promise`\<`string`\>
|
|
32
|
+
|
|
33
|
+
The plaintext.
|
|
34
|
+
|
|
35
|
+
## Throws
|
|
36
|
+
|
|
37
|
+
[VaultKeyError](../classes/VaultKeyError.md) When the key is wrong, the value has been
|
|
38
|
+
altered, or it is not in `iv:payload` form. A wrong key fails rather than
|
|
39
|
+
returning nonsense, because GCM authenticates what it decrypts.
|
|
40
|
+
|
|
41
|
+
## Remarks
|
|
42
|
+
|
|
43
|
+
That failure mode is worth relying on. A caller does not need to check
|
|
44
|
+
whether what came back looks plausible: if this returns at all, the value is
|
|
45
|
+
byte for byte what was sealed, under the key that sealed it. It is also why
|
|
46
|
+
[Vault.rekey](../classes/Vault.md#rekey) can try each key in turn and know which one was right,
|
|
47
|
+
and why a store that silently corrupts a record produces an error rather
|
|
48
|
+
than a credential that fails somewhere far away.
|
|
49
|
+
|
|
50
|
+
The error deliberately does not say which of the three went wrong: telling
|
|
51
|
+
an attacker apart from a typo is not worth telling an attacker anything.
|
|
52
|
+
|
|
53
|
+
## Example
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { generateKey, importKey, open, seal, VaultKeyError } from "@mstone6969/vault"
|
|
57
|
+
|
|
58
|
+
const key = await importKey(generateKey())
|
|
59
|
+
const other = await importKey(generateKey())
|
|
60
|
+
const sealed = await seal(key, "s3cret")
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
await open(other, sealed)
|
|
64
|
+
} catch (error) {
|
|
65
|
+
error instanceof VaultKeyError // true — never a wrong plaintext
|
|
66
|
+
}
|
|
67
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / randomValue
|
|
6
|
+
|
|
7
|
+
# Function: randomValue()
|
|
8
|
+
|
|
9
|
+
> **randomValue**(`length?`, `alphabet?`): `string`
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/vault.ts:125
|
|
12
|
+
|
|
13
|
+
A random string of `length` characters drawn from `alphabet`.
|
|
14
|
+
|
|
15
|
+
Sampling is rejected rather than folded with `%`, so every character is
|
|
16
|
+
equally likely however odd the alphabet's length.
|
|
17
|
+
|
|
18
|
+
## Parameters
|
|
19
|
+
|
|
20
|
+
### length?
|
|
21
|
+
|
|
22
|
+
`number` = `32`
|
|
23
|
+
|
|
24
|
+
How many characters to produce. Defaults to 32.
|
|
25
|
+
|
|
26
|
+
### alphabet?
|
|
27
|
+
|
|
28
|
+
`string` = `DEFAULT_ALPHABET`
|
|
29
|
+
|
|
30
|
+
The characters to draw from. Defaults to
|
|
31
|
+
[DEFAULT\_ALPHABET](../variables/DEFAULT_ALPHABET.md).
|
|
32
|
+
|
|
33
|
+
## Returns
|
|
34
|
+
|
|
35
|
+
`string`
|
|
36
|
+
|
|
37
|
+
A fresh string of exactly `length` characters.
|
|
38
|
+
|
|
39
|
+
## Throws
|
|
40
|
+
|
|
41
|
+
[VaultError](../classes/VaultError.md) 422 when `length` is below one, or `alphabet` has
|
|
42
|
+
fewer than two characters — neither can produce anything unguessable.
|
|
43
|
+
|
|
44
|
+
## Example
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
randomValue() // 32 characters of A-Z, a-z, 0-9
|
|
48
|
+
randomValue(16, "0123456789abcdef") // 16 hex characters
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## See
|
|
52
|
+
|
|
53
|
+
[RotationPolicy](../type-aliases/RotationPolicy.md) to have the vault call this during a rotation.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / seal
|
|
6
|
+
|
|
7
|
+
# Function: seal()
|
|
8
|
+
|
|
9
|
+
> **seal**(`key`, `plaintext`): `Promise`\<`string`\>
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/crypto.ts:108
|
|
12
|
+
|
|
13
|
+
Seals a value under a key.
|
|
14
|
+
|
|
15
|
+
## Parameters
|
|
16
|
+
|
|
17
|
+
### key
|
|
18
|
+
|
|
19
|
+
`CryptoKey`
|
|
20
|
+
|
|
21
|
+
The key to seal under.
|
|
22
|
+
|
|
23
|
+
### plaintext
|
|
24
|
+
|
|
25
|
+
`string`
|
|
26
|
+
|
|
27
|
+
What to seal.
|
|
28
|
+
|
|
29
|
+
## Returns
|
|
30
|
+
|
|
31
|
+
`Promise`\<`string`\>
|
|
32
|
+
|
|
33
|
+
`iv:payload`, both base64. A fresh IV every time, so the same value
|
|
34
|
+
sealed twice gives two different results.
|
|
35
|
+
|
|
36
|
+
## Remarks
|
|
37
|
+
|
|
38
|
+
That the output differs every time is the point: an observer with the store
|
|
39
|
+
in front of them cannot tell that two entries hold the same password, nor
|
|
40
|
+
that a value was replaced with itself. It also means a sealed string is no
|
|
41
|
+
good as a cache key or an equality check.
|
|
42
|
+
|
|
43
|
+
Nothing about the key is written into the output, so the caller must
|
|
44
|
+
remember which key sealed what — the vault does that by keeping each value's
|
|
45
|
+
data key beside it in [SecretRecord.sealedKey](../type-aliases/SecretRecord.md#sealedkey).
|
|
46
|
+
|
|
47
|
+
## Example
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { generateKey, importKey, open, seal } from "@mstone6969/vault"
|
|
51
|
+
|
|
52
|
+
const key = await importKey(generateKey())
|
|
53
|
+
const sealed = await seal(key, "s3cret")
|
|
54
|
+
sealed.split(":").length // 2
|
|
55
|
+
await open(key, sealed) // "s3cret"
|
|
56
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / staticKey
|
|
6
|
+
|
|
7
|
+
# Function: staticKey()
|
|
8
|
+
|
|
9
|
+
> **staticKey**(`key`): [`KeyProvider`](../type-aliases/KeyProvider.md)
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/providers.ts:70
|
|
12
|
+
|
|
13
|
+
A key you already have.
|
|
14
|
+
|
|
15
|
+
Mostly for handing a key to something that wants a provider —
|
|
16
|
+
[Vault.rekey](../classes/Vault.md#rekey), or a `previousKeys` entry — without wrapping it
|
|
17
|
+
yourself. Passing raw key material as `key` does this for you.
|
|
18
|
+
|
|
19
|
+
## Parameters
|
|
20
|
+
|
|
21
|
+
### key
|
|
22
|
+
|
|
23
|
+
`string` \| `CryptoKey`
|
|
24
|
+
|
|
25
|
+
The master key: base64, or already imported.
|
|
26
|
+
|
|
27
|
+
## Returns
|
|
28
|
+
|
|
29
|
+
[`KeyProvider`](../type-aliases/KeyProvider.md)
|
|
30
|
+
|
|
31
|
+
A provider that hands back `key` every time.
|
|
32
|
+
|
|
33
|
+
## Example
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { Vault, MemoryStore, generateKey, staticKey } from "@mstone6969/vault"
|
|
37
|
+
|
|
38
|
+
const vault = new Vault({ key: staticKey(generateKey()), store: new MemoryStore() })
|
|
39
|
+
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / Generator
|
|
6
|
+
|
|
7
|
+
# Type Alias: Generator
|
|
8
|
+
|
|
9
|
+
> **Generator** = (`context`) => `Promise`\<`string`\> \| `string`
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/vault.ts:102
|
|
12
|
+
|
|
13
|
+
Produces the next value for an entry whose policy names it.
|
|
14
|
+
|
|
15
|
+
## Parameters
|
|
16
|
+
|
|
17
|
+
### context
|
|
18
|
+
|
|
19
|
+
[`RotationContext`](RotationContext.md)
|
|
20
|
+
|
|
21
|
+
Which entry is being rotated and its policy's arguments. Not
|
|
22
|
+
the value being replaced.
|
|
23
|
+
|
|
24
|
+
## Returns
|
|
25
|
+
|
|
26
|
+
`Promise`\<`string`\> \| `string`
|
|
27
|
+
|
|
28
|
+
The next value, or a promise of it.
|
|
29
|
+
|
|
30
|
+
## Remarks
|
|
31
|
+
|
|
32
|
+
Registered under a name in [VaultOptions.generators](VaultOptions.md#generators) and asked for by
|
|
33
|
+
[RotationPolicy.generator](RotationPolicy.md#generator). Use one where the vault cannot invent the
|
|
34
|
+
value itself — a key only the far end can mint, or a password that has to be
|
|
35
|
+
set on a database before it means anything.
|
|
36
|
+
|
|
37
|
+
## Example
|
|
38
|
+
|
|
39
|
+
**Minting a key at the provider that issues it**
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
const vault = new Vault({
|
|
43
|
+
key: generateKey(),
|
|
44
|
+
store: new MemoryStore(),
|
|
45
|
+
generators: {
|
|
46
|
+
provider: async ({ arguments: args }) => mintKeyFor(args.account),
|
|
47
|
+
},
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
await vault.put("alice", "api", "old-key", {
|
|
51
|
+
rotation: {
|
|
52
|
+
kind: "generator",
|
|
53
|
+
generator: "provider",
|
|
54
|
+
arguments: { account: "acct_123" },
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
await vault.rotate("alice", "api")
|
|
58
|
+
```
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / HistoryEntry
|
|
6
|
+
|
|
7
|
+
# Type Alias: HistoryEntry
|
|
8
|
+
|
|
9
|
+
> **HistoryEntry** = `object`
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/types.ts:18
|
|
12
|
+
|
|
13
|
+
A value a rotatable entry used to hold.
|
|
14
|
+
|
|
15
|
+
## Remarks
|
|
16
|
+
|
|
17
|
+
Kept sealed, exactly as the live value is, so history costs no more trust
|
|
18
|
+
than the entry itself. A job that read the credential moments before a
|
|
19
|
+
rotation can still finish on what it was given.
|
|
20
|
+
|
|
21
|
+
## Example
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
await vault.rotate("alice", "db")
|
|
25
|
+
// The value that was live until the rotation, opened:
|
|
26
|
+
const [previous] = await vault.versions("alice", "db")
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## See
|
|
30
|
+
|
|
31
|
+
[SecretRecord.history](SecretRecord.md#history)
|
|
32
|
+
|
|
33
|
+
## Properties
|
|
34
|
+
|
|
35
|
+
### sealed
|
|
36
|
+
|
|
37
|
+
> **sealed**: `string`
|
|
38
|
+
|
|
39
|
+
Defined in: cron/vault/src/types.ts:20
|
|
40
|
+
|
|
41
|
+
The value, sealed exactly as the live one is.
|
|
42
|
+
|
|
43
|
+
***
|
|
44
|
+
|
|
45
|
+
### sealedKey
|
|
46
|
+
|
|
47
|
+
> **sealedKey**: `string` \| `null`
|
|
48
|
+
|
|
49
|
+
Defined in: cron/vault/src/types.ts:28
|
|
50
|
+
|
|
51
|
+
The data key that opens it, itself sealed under the master key.
|
|
52
|
+
|
|
53
|
+
Null on values kept before envelope encryption, which are sealed under
|
|
54
|
+
the master key directly. A `rekey` moves the non-null ones onto the new
|
|
55
|
+
master key and leaves the rest alone.
|
|
56
|
+
|
|
57
|
+
***
|
|
58
|
+
|
|
59
|
+
### createdAt
|
|
60
|
+
|
|
61
|
+
> **createdAt**: `Date`
|
|
62
|
+
|
|
63
|
+
Defined in: cron/vault/src/types.ts:30
|
|
64
|
+
|
|
65
|
+
When this value was replaced.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
[**@mstone6969/vault**](../../README.md)
|
|
2
|
+
|
|
3
|
+
***
|
|
4
|
+
|
|
5
|
+
[@mstone6969/vault](../../README.md) / [index](../README.md) / KeyProvider
|
|
6
|
+
|
|
7
|
+
# Type Alias: KeyProvider
|
|
8
|
+
|
|
9
|
+
> **KeyProvider** = `object`
|
|
10
|
+
|
|
11
|
+
Defined in: cron/vault/src/providers.ts:41
|
|
12
|
+
|
|
13
|
+
Where the master key comes from.
|
|
14
|
+
|
|
15
|
+
A vault takes a provider rather than a string so the key can live wherever
|
|
16
|
+
you keep such things — the environment, a file with tight permissions, or a
|
|
17
|
+
service that hands one over. Write your own for anything else; it is one
|
|
18
|
+
method.
|
|
19
|
+
|
|
20
|
+
## Remarks
|
|
21
|
+
|
|
22
|
+
Whoever holds the provider — [Vault](../classes/Vault.md) or [FileStore](../classes/FileStore.md) — calls
|
|
23
|
+
`key` the first time a key is actually needed and keeps the promise, so a
|
|
24
|
+
provider that reaches over the network is asked once and a vault nobody uses
|
|
25
|
+
never asks at all. Anything thrown surfaces from that first operation, not
|
|
26
|
+
from the constructor.
|
|
27
|
+
|
|
28
|
+
## Example
|
|
29
|
+
|
|
30
|
+
A provider for something this package does not ship — here a KMS, but the
|
|
31
|
+
shape is the same for 1Password, age, or a file on a smartcard.
|
|
32
|
+
```ts
|
|
33
|
+
import { Vault, MemoryStore, type KeyProvider } from "@mstone6969/vault"
|
|
34
|
+
|
|
35
|
+
function kmsKey(id: string): KeyProvider {
|
|
36
|
+
return {
|
|
37
|
+
async key() {
|
|
38
|
+
const response = await fetch(`https://kms.internal/keys/${id}`)
|
|
39
|
+
if (!response.ok) throw new Error(`KMS refused key ${id}.`)
|
|
40
|
+
return (await response.text()).trim() // base64
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const vault = new Vault({ key: kmsKey("vault-master"), store: new MemoryStore() })
|
|
46
|
+
await vault.put("alice", "db", "hunter2") // the KMS is called here, once
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## See
|
|
50
|
+
|
|
51
|
+
[staticKey](../functions/staticKey.md), [envKey](../functions/envKey.md) and [fileKey](../functions/fileKey.md) for the ones that
|
|
52
|
+
ship.
|
|
53
|
+
|
|
54
|
+
## Methods
|
|
55
|
+
|
|
56
|
+
### key()
|
|
57
|
+
|
|
58
|
+
> **key**(): `string` \| `CryptoKey` \| `Promise`\<`string` \| `CryptoKey`\>
|
|
59
|
+
|
|
60
|
+
Defined in: cron/vault/src/providers.ts:50
|
|
61
|
+
|
|
62
|
+
The key, base64 or already imported. Called once, when first needed.
|
|
63
|
+
|
|
64
|
+
#### Returns
|
|
65
|
+
|
|
66
|
+
`string` \| `CryptoKey` \| `Promise`\<`string` \| `CryptoKey`\>
|
|
67
|
+
|
|
68
|
+
The master key: a base64 string of 32 bytes, or a `CryptoKey`
|
|
69
|
+
already imported for AES-GCM. May be a promise.
|
|
70
|
+
|
|
71
|
+
#### Throws
|
|
72
|
+
|
|
73
|
+
Whatever the source of the key throws when it cannot produce
|
|
74
|
+
one. The ones here throw [VaultKeyError](../classes/VaultKeyError.md).
|