@secrefs/node 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Armistice Group
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # @secrefs/node
2
+
3
+ Put a reference in your config instead of a secret.
4
+
5
+ ```diff
6
+ - DB_PASSWORD=correcthorsebatterystaple
7
+ + DB_PASSWORD=sec://aws/prod/db#password
8
+ ```
9
+
10
+ The second line is safe to commit. SecRefs resolves it from your own vault, in
11
+ memory, at the moment it is used — the value never lands on disk, in shell
12
+ history, or in a CI log.
13
+
14
+ **Bring your own vault.** SecRefs is not a place to store secrets and never
15
+ holds a copy of one. Your AWS Secrets Manager, HashiCorp Vault, or Bitwarden
16
+ instance stays the single source of truth; this library just knows how to read
17
+ from it.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ npm install @secrefs/node # or: pnpm add @secrefs/node
23
+ ```
24
+
25
+ ## Use it
26
+
27
+ ### Wrap your process
28
+
29
+ The CLI expands every `sec://` value in the environment and hands the real
30
+ values to your program:
31
+
32
+ ```bash
33
+ npx secrefs run -- node server.js
34
+ # secrefs: resolved 2 secret reference(s): DB_PASSWORD, STRIPE_KEY
35
+ ```
36
+
37
+ Your app reads `process.env.DB_PASSWORD` as it always did. Nothing else changes.
38
+
39
+ ### Or call it directly
40
+
41
+ ```ts
42
+ import { secRefs } from "@secrefs/node";
43
+
44
+ // Expand everything in process.env, once, at boot.
45
+ await secRefs.init();
46
+
47
+ // Or resolve a single reference at the point of use.
48
+ const key = await secRefs.expandString("sec://vault/secret/data/stripe#key");
49
+ ```
50
+
51
+ ### Check without resolving
52
+
53
+ `check()` validates every reference it can see and **never returns a plaintext
54
+ value** — safe to run in CI to catch a typo'd path before it pages someone.
55
+
56
+ ```ts
57
+ const report = await secRefs.check();
58
+ ```
59
+
60
+ ## A stable name for a value that changes
61
+
62
+ `expandString()` re-fetches by default (`cacheTtlMs` is `0`), which means a
63
+ rotated secret reaches a long-running process without a restart or a redeploy:
64
+
65
+ ```ts
66
+ const secRefs = new SecRefs();
67
+ const REF = "sec://aws/prod/db#password";
68
+
69
+ await secRefs.expandString(REF); // "live-verify-8c41f9d2"
70
+ // ... the secret is rotated in AWS, out of band ...
71
+ await secRefs.expandString(REF); // "ROTATED-3b7e01aa" - same process, same reference
72
+ ```
73
+
74
+ The reference is the stable thing; the value underneath it is free to move.
75
+ Set `cacheTtlMs` above zero to trade a bounded window of staleness for fewer
76
+ round trips — concurrent resolutions of the same reference are coalesced into
77
+ one fetch either way.
78
+
79
+ Note the difference between the two entry points: `init()` hydrates
80
+ `process.env` once at boot, so a rotation reaches it on the next restart.
81
+ `expandString()` is the use-time path, and it is the one that picks up a
82
+ rotation live.
83
+
84
+ ## The reference format
85
+
86
+ ```
87
+ sec://<provider>/<path>[#field]
88
+ ```
89
+
90
+ | Part | Meaning |
91
+ |---|---|
92
+ | `provider` | Which vault to ask — `aws`, `vault`, `bitwarden`, `local` |
93
+ | `path` | The secret's identifier within that vault |
94
+ | `field` | Optional. Extracts one key from a JSON secret |
95
+
96
+ `sec://aws/prod/db#password` reads the `password` field out of the JSON stored
97
+ at `prod/db`, and returns only that field.
98
+
99
+ ## Providers
100
+
101
+ | Provider | Reference | Authentication |
102
+ |---|---|---|
103
+ | AWS Secrets Manager | `sec://aws/...` | The standard AWS credential chain — env vars, shared config, or an instance/IRSA role |
104
+ | HashiCorp Vault | `sec://vault/...` | `VAULT_ADDR` / `VAULT_TOKEN` from the environment. KV v1 and v2 |
105
+ | Bitwarden | `sec://bitwarden/...` | A machine account access token |
106
+ | Local (dev only) | `sec://local/...` | A gitignored `.secrefs.local.json`, for teammates without vault access yet |
107
+
108
+ No provider ever needs a static credential in SecRefs' own configuration.
109
+
110
+ ## Missing references fail loudly
111
+
112
+ Strict mode is the default: a reference that cannot be resolved throws rather
113
+ than silently yielding `undefined` and letting your app boot half-configured.
114
+ Pass `{ strict: false }` if you'd rather leave unresolvable references in place.
115
+
116
+ Every reference resolves concurrently, and one failure never blocks the others.
117
+
118
+ ## License
119
+
120
+ MIT. See [LICENSE](./LICENSE).
121
+
122
+ The client libraries are MIT permanently and unconditionally — the SecRefs
123
+ control plane is licensed separately. See
124
+ [LICENSING.md](https://github.com/Armistice-Group/secrefs/blob/main/LICENSING.md).