@sirrlock/node 0.1.0 → 1.0.1
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 +1 -1
- package/README.md +100 -24
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +48 -30
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +327 -45
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +271 -47
- package/dist/index.js.map +1 -1
- package/package.json +8 -3
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# @sirrlock/node
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@sirrlock/node)
|
|
3
|
+
[](https://www.npmjs.com/package/@sirrlock/node)
|
|
5
4
|
[](https://www.npmjs.com/package/@sirrlock/node)
|
|
5
|
+
[](https://github.com/sirrlock/node/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.typescriptlang.org/)
|
|
7
7
|
[](https://nodejs.org)
|
|
8
|
+
[](https://github.com/sirrlock/node)
|
|
9
|
+
[](https://github.com/sirrlock/node)
|
|
8
10
|
[](LICENSE)
|
|
9
11
|
|
|
10
12
|
**Node.js client and npx CLI for [Sirr](https://github.com/sirrlock/sirr) — ephemeral secret management.**
|
|
@@ -20,20 +22,22 @@ npm install @sirrlock/node
|
|
|
20
22
|
Or use without installing:
|
|
21
23
|
|
|
22
24
|
```bash
|
|
23
|
-
npx @sirrlock/node push
|
|
25
|
+
npx @sirrlock/node push "postgres://..." --reads 1 --ttl 1h
|
|
24
26
|
```
|
|
25
27
|
|
|
26
28
|
## CLI
|
|
27
29
|
|
|
28
30
|
```bash
|
|
29
|
-
# Push a
|
|
30
|
-
sirr push
|
|
31
|
+
# Push a public dead drop — returns a one-time URL
|
|
32
|
+
sirr push "postgres://..." --reads 1 --ttl 1h
|
|
33
|
+
# → https://sirrlock.com/s/abc123
|
|
31
34
|
|
|
32
|
-
#
|
|
33
|
-
sirr
|
|
35
|
+
# Set an org-scoped named secret
|
|
36
|
+
sirr set DB_URL "postgres://..." --org acme --reads 3 --ttl 24h
|
|
34
37
|
|
|
35
|
-
#
|
|
36
|
-
sirr
|
|
38
|
+
# Retrieve by ID (dead drop) or key (org-scoped)
|
|
39
|
+
sirr get abc123
|
|
40
|
+
sirr get DB_URL --org acme
|
|
37
41
|
|
|
38
42
|
# Manage
|
|
39
43
|
sirr list
|
|
@@ -44,51 +48,124 @@ sirr health
|
|
|
44
48
|
|
|
45
49
|
Config via env vars:
|
|
46
50
|
```bash
|
|
47
|
-
export SIRR_SERVER=
|
|
51
|
+
export SIRR_SERVER=https://sirrlock.com
|
|
48
52
|
export SIRR_TOKEN=your-master-key
|
|
49
53
|
```
|
|
50
54
|
|
|
51
55
|
## Programmatic API
|
|
52
56
|
|
|
53
57
|
```typescript
|
|
54
|
-
import { SirrClient, SirrError } from '@sirrlock/node'
|
|
58
|
+
import { SirrClient, SirrError, SecretExistsError } from '@sirrlock/node'
|
|
55
59
|
|
|
56
60
|
const sirr = new SirrClient({
|
|
57
|
-
server: process.env.SIRR_SERVER ?? '
|
|
61
|
+
server: process.env.SIRR_SERVER ?? 'https://sirrlock.com',
|
|
58
62
|
token: process.env.SIRR_TOKEN!,
|
|
59
63
|
})
|
|
60
64
|
|
|
61
|
-
// Push a
|
|
62
|
-
await sirr.push('
|
|
65
|
+
// Push a public dead drop — returns { id, url }
|
|
66
|
+
const { id, url } = await sirr.push('sk-...', { ttl: 3600, reads: 1 })
|
|
67
|
+
console.log(url) // → https://sirrlock.com/s/abc123
|
|
68
|
+
|
|
69
|
+
// Set an org-scoped named secret — throws SecretExistsError on conflict
|
|
70
|
+
await sirr.set('DB_URL', 'postgres://...', { org: 'acme', ttl: 86400, reads: 3 })
|
|
63
71
|
|
|
64
|
-
// Retrieve —
|
|
65
|
-
const value = await sirr.get(
|
|
72
|
+
// Retrieve — routes by org presence
|
|
73
|
+
const value = await sirr.get(id) // dead drop by ID
|
|
74
|
+
const dbUrl = await sirr.get('DB_URL', { org: 'acme' }) // org-scoped by key
|
|
66
75
|
|
|
67
76
|
// Pull all secrets into a plain object
|
|
68
77
|
const secrets = await sirr.pullAll()
|
|
69
78
|
|
|
70
79
|
// Inject all secrets as env vars for the duration of a callback
|
|
71
80
|
await sirr.withSecrets(async () => {
|
|
72
|
-
// process.env.
|
|
81
|
+
// process.env.DB_URL is set here
|
|
73
82
|
await runAgentTask()
|
|
74
83
|
})
|
|
75
84
|
|
|
85
|
+
// Inspect metadata without consuming a read (HEAD request)
|
|
86
|
+
const status = await sirr.check('DB_URL')
|
|
87
|
+
// { status: 'active', readCount: 0, readsRemaining: 3, ... }
|
|
88
|
+
|
|
76
89
|
// Delete immediately
|
|
77
|
-
await sirr.delete('
|
|
90
|
+
await sirr.delete('DB_URL')
|
|
78
91
|
|
|
79
92
|
// List active secrets (metadata only — no values)
|
|
80
93
|
const list = await sirr.list()
|
|
81
94
|
```
|
|
82
95
|
|
|
96
|
+
### Multi-Tenant / Org Mode
|
|
97
|
+
|
|
98
|
+
Org scoping is now per-call via the `org` option on `set()` and `get()`:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// Set an org-scoped secret
|
|
102
|
+
await sirr.set('DB_URL', 'postgres://...', { org: 'acme', reads: 1 })
|
|
103
|
+
|
|
104
|
+
// Retrieve an org-scoped secret
|
|
105
|
+
const value = await sirr.get('DB_URL', { org: 'acme' })
|
|
106
|
+
|
|
107
|
+
// Audit, list, and webhook calls still support org at the client level
|
|
108
|
+
const sirr = new SirrClient({
|
|
109
|
+
server: 'https://sirrlock.com',
|
|
110
|
+
token: process.env.SIRR_TOKEN!,
|
|
111
|
+
org: 'acme',
|
|
112
|
+
})
|
|
113
|
+
const events = await sirr.audit()
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### /me endpoints
|
|
117
|
+
|
|
118
|
+
Manage the current principal's profile and API keys:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
const profile = await sirr.me() // GET /me
|
|
122
|
+
await sirr.updateMe({ metadata: { team: 'platform' } }) // PATCH /me
|
|
123
|
+
const key = await sirr.createKey({ name: 'ci' }) // POST /me/keys
|
|
124
|
+
const revoked = await sirr.deleteKey(key.id) // DELETE /me/keys/{id} → boolean
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### Admin endpoints (master key only)
|
|
128
|
+
|
|
129
|
+
Manage orgs, principals, and roles. Available both as flat methods and through
|
|
130
|
+
namespaced sub-clients (`sirr.orgs.*`, `sirr.principals.*`, `sirr.webhooks.*`):
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
// Orgs
|
|
134
|
+
const org = await sirr.orgs.create({ name: 'acme' }) // or sirr.createOrg(...)
|
|
135
|
+
const orgs = await sirr.orgs.list() // returns Org[]
|
|
136
|
+
await sirr.orgs.delete(org.id)
|
|
137
|
+
|
|
138
|
+
// Principals
|
|
139
|
+
const p = await sirr.principals.create(org.id, { name: 'alice', role: 'writer' })
|
|
140
|
+
const principals = await sirr.principals.list(org.id) // returns Principal[]
|
|
141
|
+
await sirr.principals.delete(org.id, p.id)
|
|
142
|
+
|
|
143
|
+
// Roles — permissions is a letter string, not an array
|
|
144
|
+
await sirr.createRole(org.id, { name: 'reader', permissions: 'rRlL' })
|
|
145
|
+
await sirr.listRoles(org.id)
|
|
146
|
+
await sirr.deleteRole(org.id, 'reader')
|
|
147
|
+
|
|
148
|
+
// Webhooks
|
|
149
|
+
const wh = await sirr.webhooks.create('https://example.com/hook')
|
|
150
|
+
const webhooks = await sirr.webhooks.list()
|
|
151
|
+
await sirr.webhooks.delete(wh.id)
|
|
152
|
+
|
|
153
|
+
// Audit log
|
|
154
|
+
const events = await sirr.audit({ action: 'secret.read', limit: 50 })
|
|
155
|
+
```
|
|
156
|
+
|
|
83
157
|
### Error Handling
|
|
84
158
|
|
|
85
159
|
```typescript
|
|
86
|
-
import { SirrError } from '@sirrlock/node'
|
|
160
|
+
import { SirrError, SecretExistsError } from '@sirrlock/node'
|
|
87
161
|
|
|
88
162
|
try {
|
|
89
|
-
await sirr.
|
|
163
|
+
await sirr.set('DB_URL', 'postgres://...', { org: 'acme' })
|
|
90
164
|
} catch (e) {
|
|
91
|
-
if (e instanceof
|
|
165
|
+
if (e instanceof SecretExistsError) {
|
|
166
|
+
// 409 — secret with this key already exists in the org
|
|
167
|
+
console.error('Secret already exists, use a different key or delete first')
|
|
168
|
+
} else if (e instanceof SirrError) {
|
|
92
169
|
console.error(`API error ${e.status}: ${e.message}`)
|
|
93
170
|
}
|
|
94
171
|
}
|
|
@@ -123,9 +200,8 @@ await sirr.withSecrets(async () => {
|
|
|
123
200
|
### CI/CD: one-time deploy credential
|
|
124
201
|
|
|
125
202
|
```typescript
|
|
126
|
-
await sirr.push(
|
|
127
|
-
|
|
128
|
-
// DEPLOY_TOKEN was read once and is now deleted
|
|
203
|
+
const { url } = await sirr.push(process.env.PERMANENT_TOKEN!, { reads: 1 })
|
|
204
|
+
// Share the URL with the deploy script — burned after one read
|
|
129
205
|
```
|
|
130
206
|
|
|
131
207
|
### pytest-style fixture for Node.js tests
|
package/dist/cli.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Sirr CLI — thin Node.js wrapper for use via `npx sirr` or `npm i -g sirr`.
|
|
4
4
|
*
|
|
5
|
-
* Reads SIRR_SERVER (default: http://localhost:
|
|
5
|
+
* Reads SIRR_SERVER (default: http://localhost:39999), SIRR_TOKEN, and SIRR_ORG.
|
|
6
6
|
*/
|
|
7
7
|
export declare function parseArgs(argv: string[]): Record<string, string | number | boolean>;
|
|
8
8
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAoCH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAqBnF"}
|
package/dist/cli.js
CHANGED
|
@@ -3,35 +3,38 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Sirr CLI — thin Node.js wrapper for use via `npx sirr` or `npm i -g sirr`.
|
|
5
5
|
*
|
|
6
|
-
* Reads SIRR_SERVER (default: http://localhost:
|
|
6
|
+
* Reads SIRR_SERVER (default: http://localhost:39999), SIRR_TOKEN, and SIRR_ORG.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.parseArgs = parseArgs;
|
|
10
10
|
const index_1 = require("./index");
|
|
11
|
-
const server = process.env.SIRR_SERVER ?? "http://localhost:
|
|
11
|
+
const server = process.env.SIRR_SERVER ?? "http://localhost:39999";
|
|
12
12
|
const token = process.env.SIRR_TOKEN ?? "";
|
|
13
|
+
const envOrg = process.env.SIRR_ORG;
|
|
13
14
|
function usage() {
|
|
14
15
|
console.error(`
|
|
15
16
|
Usage: sirr <command> [options]
|
|
16
17
|
|
|
17
18
|
Commands:
|
|
18
|
-
push
|
|
19
|
-
|
|
19
|
+
push <value> [--ttl <secs>] [--reads <n>]
|
|
20
|
+
set KEY=value [--org <org>] [--ttl <secs>] [--reads <n>]
|
|
21
|
+
get <id|KEY> [--org <org>]
|
|
20
22
|
list
|
|
21
23
|
delete KEY
|
|
22
24
|
prune
|
|
23
25
|
health
|
|
24
|
-
audit [--since <ts>] [--action <action>] [--limit <n>]
|
|
26
|
+
audit [--since <ts>] [--action <action>] [--key <key>] [--limit <n>]
|
|
25
27
|
webhooks list
|
|
26
28
|
webhooks add <url> [--events <csv>]
|
|
27
29
|
webhooks remove <id>
|
|
28
30
|
keys list
|
|
29
|
-
keys create <label> [--
|
|
31
|
+
keys create <label> [--valid-for <secs>]
|
|
30
32
|
keys remove <id>
|
|
31
33
|
|
|
32
34
|
Environment:
|
|
33
|
-
SIRR_SERVER Server URL (default: http://localhost:
|
|
35
|
+
SIRR_SERVER Server URL (default: http://localhost:39999)
|
|
34
36
|
SIRR_TOKEN Bearer token
|
|
37
|
+
SIRR_ORG Default org (used by set/get when --org is not passed)
|
|
35
38
|
`);
|
|
36
39
|
process.exit(1);
|
|
37
40
|
}
|
|
@@ -64,7 +67,7 @@ async function main() {
|
|
|
64
67
|
if (!subcmd)
|
|
65
68
|
usage();
|
|
66
69
|
const args = parseArgs(rest);
|
|
67
|
-
const client = new index_1.SirrClient({ server, token });
|
|
70
|
+
const client = new index_1.SirrClient({ server, token, org: envOrg });
|
|
68
71
|
try {
|
|
69
72
|
switch (subcmd) {
|
|
70
73
|
case "health": {
|
|
@@ -73,30 +76,46 @@ async function main() {
|
|
|
73
76
|
break;
|
|
74
77
|
}
|
|
75
78
|
case "push": {
|
|
79
|
+
const value = args._0;
|
|
80
|
+
if (!value)
|
|
81
|
+
usage();
|
|
82
|
+
const ttlArg = args.ttl;
|
|
83
|
+
const readsArg = args.reads;
|
|
84
|
+
const result = await client.push(value, {
|
|
85
|
+
ttl: ttlArg ? Number.parseInt(ttlArg, 10) : undefined,
|
|
86
|
+
reads: readsArg ? Number.parseInt(readsArg, 10) : undefined,
|
|
87
|
+
});
|
|
88
|
+
console.log(`✓ pushed — id: ${result.id}`);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case "set": {
|
|
76
92
|
const target = args._0;
|
|
77
93
|
if (!target)
|
|
78
94
|
usage();
|
|
79
95
|
const ttlArg = args.ttl;
|
|
80
96
|
const readsArg = args.reads;
|
|
97
|
+
const orgArg = args.org;
|
|
81
98
|
if (!target.includes("=")) {
|
|
82
|
-
console.error("
|
|
99
|
+
console.error("set: expected KEY=value");
|
|
83
100
|
process.exit(1);
|
|
84
101
|
}
|
|
85
102
|
const eqIdx = target.indexOf("=");
|
|
86
103
|
const key = target.slice(0, eqIdx);
|
|
87
104
|
const value = target.slice(eqIdx + 1);
|
|
88
|
-
await client.
|
|
105
|
+
const result = await client.set(key, value, {
|
|
106
|
+
org: orgArg,
|
|
89
107
|
ttl: ttlArg ? Number.parseInt(ttlArg, 10) : undefined,
|
|
90
108
|
reads: readsArg ? Number.parseInt(readsArg, 10) : undefined,
|
|
91
109
|
});
|
|
92
|
-
console.log(`✓
|
|
110
|
+
console.log(`✓ set ${result.key}`);
|
|
93
111
|
break;
|
|
94
112
|
}
|
|
95
113
|
case "get": {
|
|
96
|
-
const
|
|
97
|
-
if (!
|
|
114
|
+
const idOrKey = args._0;
|
|
115
|
+
if (!idOrKey)
|
|
98
116
|
usage();
|
|
99
|
-
const
|
|
117
|
+
const orgArg = args.org;
|
|
118
|
+
const value = await client.get(idOrKey, { org: orgArg });
|
|
100
119
|
if (value === null) {
|
|
101
120
|
console.error("not found or expired");
|
|
102
121
|
process.exit(1);
|
|
@@ -133,6 +152,7 @@ async function main() {
|
|
|
133
152
|
const events = await client.getAuditLog({
|
|
134
153
|
since: args.since ? Number(args.since) : undefined,
|
|
135
154
|
action: args.action,
|
|
155
|
+
key: args.key,
|
|
136
156
|
limit: args.limit ? Number(args.limit) : undefined,
|
|
137
157
|
});
|
|
138
158
|
if (events.length === 0) {
|
|
@@ -193,25 +213,19 @@ async function main() {
|
|
|
193
213
|
usage();
|
|
194
214
|
switch (sub) {
|
|
195
215
|
case "list": {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
console.log("(no API keys)");
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
for (const k of keys) {
|
|
202
|
-
console.log(` ${k.id} ${k.label} [${k.permissions.join(",")}] prefix=${k.prefix ?? "*"}`);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
216
|
+
// No list-keys endpoint on the server API.
|
|
217
|
+
console.log("Key listing is not supported by the server API.");
|
|
205
218
|
break;
|
|
206
219
|
}
|
|
207
220
|
case "create": {
|
|
208
|
-
const
|
|
209
|
-
if (!
|
|
221
|
+
const name = args._1;
|
|
222
|
+
if (!name)
|
|
210
223
|
usage();
|
|
211
|
-
const
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
224
|
+
const validFor = args["valid-for"];
|
|
225
|
+
const result = await client.createKey({
|
|
226
|
+
name,
|
|
227
|
+
valid_for_seconds: validFor ? Number(validFor) : undefined,
|
|
228
|
+
});
|
|
215
229
|
console.log("API key created");
|
|
216
230
|
console.log(` id: ${result.id}`);
|
|
217
231
|
console.log(` key: ${result.key}`);
|
|
@@ -222,7 +236,7 @@ async function main() {
|
|
|
222
236
|
const id = args._1;
|
|
223
237
|
if (!id)
|
|
224
238
|
usage();
|
|
225
|
-
await client.
|
|
239
|
+
await client.deleteKey(id);
|
|
226
240
|
console.log(`API key ${id} removed`);
|
|
227
241
|
break;
|
|
228
242
|
}
|
|
@@ -236,6 +250,10 @@ async function main() {
|
|
|
236
250
|
}
|
|
237
251
|
}
|
|
238
252
|
catch (e) {
|
|
253
|
+
if (e instanceof index_1.SecretExistsError) {
|
|
254
|
+
console.error(`conflict: ${e.message}`);
|
|
255
|
+
process.exit(2);
|
|
256
|
+
}
|
|
239
257
|
console.error(e.message ?? String(e));
|
|
240
258
|
process.exit(1);
|
|
241
259
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AACA;;;;GAIG;;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|