vestauth 0.8.2 → 0.8.4

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/CHANGELOG.md CHANGED
@@ -2,7 +2,19 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- [Unreleased](https://github.com/vestauth/vestauth/compare/v0.8.2...main)
5
+ [Unreleased](https://github.com/vestauth/vestauth/compare/v0.8.4...main)
6
+
7
+ ## [0.8.4](https://github.com/vestauth/vestauth/compare/v0.8.3...v0.8.4) (2026-02-06)
8
+
9
+ ### Changed
10
+
11
+ * Patch bug with missing `web-bot-auth` lib
12
+
13
+ ## [0.8.3](https://github.com/vestauth/vestauth/compare/v0.8.2...v0.8.3) (2026-02-06)
14
+
15
+ ### Changed
16
+
17
+ * Various clean up.
6
18
 
7
19
  ## [0.8.2](https://github.com/vestauth/vestauth/compare/v0.8.1...v0.8.2) (2026-02-05)
8
20
 
package/README.md CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  *auth for agents*–from the creator of [`dotenv`](https://github.com/motdotla/dotenv) and [`dotenvx`](https://github.com/dotenvx/dotenvx).
4
4
 
5
- * identity (cryptographic)
6
- * authentication
7
- * verification
8
-
9
- [Watch demo video 📺](https://www.youtube.com/watch?v=cHARyULr_qk)
5
+ > [1 minute demo 📺](https://www.youtube.com/watch?v=cHARyULr_qk)
6
+ >
7
+ > Vestauth gives agents a cryptographic identity and a simple way to authenticate HTTP requests. Most agent systems rely on API keys, bearer tokens, or username/passwords. These approaches are difficult to rotate, easy to leak, and hard to attribute to a specific agent. Vestauth replaces shared secrets with public/private key cryptography. Agents sign requests using a private key, and providers verify those requests using the agent's public key. [[1](#compare)]
8
+ >
9
+ > *Scott Motte–creator of `dotenv` and `dotenvx`*
10
10
 
11
11
   
12
12
 
@@ -18,7 +18,7 @@ npm i -g vestauth
18
18
 
19
19
  ```sh
20
20
  vestauth agent init
21
- vestauth agent curl https://PROVIDER.com/TOOL
21
+ vestauth agent curl -X POST https://ping.vestauth.com
22
22
  ```
23
23
 
24
24
  <details><summary>with curl 🌐 </summary><br>
@@ -187,19 +187,6 @@ Vestauth intentionally separates identity discovery from verification to support
187
187
 
188
188
  &nbsp;
189
189
 
190
- ## Standards
191
-
192
- Vestauth builds on open internet standards for agent authentication.
193
-
194
- | Specification | Purpose |
195
- |------------|------------|
196
- | **[RFC 9421 – HTTP Message Signatures](https://datatracker.ietf.org/doc/rfc9421/)** | Defines how requests are cryptographically signed and verified |
197
- | **[Web-Bot-Auth Draft](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture)** | Defines headers and authentication architecture for autonomous agents |
198
-
199
- Vestauth follows these specifications to ensure interoperability between agents and providers while avoiding vendor lock-in. Vestauth focuses on developer ergonomics while staying compliant with these emerging standards.
200
-
201
- &nbsp;
202
-
203
190
  ## Advanced
204
191
 
205
192
  > Become a `vestauth` power user.
@@ -209,6 +196,101 @@ Vestauth follows these specifications to ensure interoperability between agents
209
196
 
210
197
  Advanced CLI commands.
211
198
 
199
+ <details><summary>`agent init`</summary><br>
200
+
201
+ Create agent.
202
+
203
+ ```sh
204
+ $ vestauth agent init
205
+ ✔ agent created (.env/AGENT_ID=agent-609a4fd2ebf4e6347108c517)
206
+ ⮕ next run: [vestauth agent curl https://api.vestauth.com/whoami]
207
+ ```
208
+
209
+ </details>
210
+ <details><summary>`agent curl`</summary><br>
211
+
212
+ Run curl as agent.
213
+
214
+ ```sh
215
+ $ vestauth agent curl https://api.vestauth.com/whoami
216
+ {"uid":"agent-609a4fd2ebf4e6347108c517", ...}
217
+ ```
218
+
219
+ </details>
220
+ <details><summary>`agent curl --pretty-print`</summary><br>
221
+
222
+ Pretty print curl json output.
223
+
224
+ ```sh
225
+ $ vestauth agent curl https://api.vestauth.com/whoami --pp
226
+ {
227
+ "uid": "agent-609a4fd2ebf4e6347108c517",
228
+ "kid": "FGzgs758DBGnI1S0BejChDsK0IKZm3qPpOOXdRnnBkM",
229
+ "public_jwk": {
230
+ ...
231
+ },
232
+ "well_known_url": "https://agent-609a4fd2ebf4e6347108c517.agents.vestauth.com/.well-known/http-message-signatures-directory"
233
+ }
234
+ ```
235
+
236
+ </details>
237
+
238
+ <details><summary>`agent headers`</summary><br>
239
+
240
+ Generate signed headers as agent.
241
+
242
+ ```sh
243
+ $ vestauth agent headers GET https://api.vestauth.com/whoami --pp
244
+ {
245
+ "Signature": "sig1=:UW6A7j8jo+gQxd+EeVgDddY51ZOc9plrSaupW/N53hQnQFvP9BuwQHgL7SVPLQIu4cnRzLgvwm7Yu9YMO+HUDQ==:",
246
+ "Signature-Input": "sig1=(\"@authority\");created=1770396357;keyid=\"FGzgs758DBGnI1S0BejChDsK0IKZm3qPpOOXdRnnBkM\";alg=\"ed25519\";expires=1770396657;nonce=\"PrE7A6I_5fWnxBsBigNvxjp3-YangXl71V1uM3hPZavh918JqzjMSRcjHv_n5XIb3N8WivZEeigCBH6QGDSqgA\";tag=\"web-bot-auth\"",
247
+ "Signature-Agent": "sig1=agent-609a4fd2ebf4e6347108c517.agents.vestauth.com"
248
+ }
249
+ ```
250
+
251
+ </details>
252
+
253
+ <details><summary>`agent headers --id`</summary><br>
254
+
255
+ Change the `AGENT_ID`.
256
+
257
+ ```sh
258
+ $ vestauth agent headers GET https://api.vestauth.com/whoami --id agent-1234 --pp
259
+ {
260
+ "Signature": "sig1=:UW6A7j8jo+gQxd+EeVgDddY51ZOc9plrSaupW/N53hQnQFvP9BuwQHgL7SVPLQIu4cnRzLgvwm7Yu9YMO+HUDQ==:",
261
+ "Signature-Input": "sig1=(\"@authority\");created=1770396357;keyid=\"FGzgs758DBGnI1S0BejChDsK0IKZm3qPpOOXdRnnBkM\";alg=\"ed25519\";expires=1770396657;nonce=\"PrE7A6I_5fWnxBsBigNvxjp3-YangXl71V1uM3hPZavh918JqzjMSRcjHv_n5XIb3N8WivZEeigCBH6QGDSqgA\";tag=\"web-bot-auth\"",
262
+ "Signature-Agent": "sig1=agent-1234.agents.vestauth.com"
263
+ }
264
+ ```
265
+
266
+ </details>
267
+
268
+ <details><summary>`agent headers --private-jwk`</summary><br>
269
+
270
+ Change the `AGENT_PRIVATE_JWK` used to sign the headers.
271
+
272
+ ```sh
273
+ $ vestauth agent headers GET https://api.vestauth.com/whoami --private-jwk '{"crv":"Ed25519","d":"RyFk7QTOk_bMjFQKjyAR-vJDp7BITn9U0YBFNdpR9wE","x":"hyAxNMbuTcFQq420Dr46ucF0dRZ_FIyxgsujruEoklM","kty":"OKP","kid":"UfHTArlyLsqM8cB8sNfH2z6XOwc0RmJIq2CAPGfvMjk"}' --pp
274
+ {
275
+ "Signature": "sig1=:PZUVVjqiECYuk8Hg1GZKKeJmwhLrcRdRA7nm1R595UFK9cx0q9atNFBzKP5wBEmszMIgvpYdMrIQbPEeKz4tCQ==:",
276
+ "Signature-Input": "sig1=(\"@authority\");created=1770396546;keyid=\"UfHTArlyLsqM8cB8sNfH2z6XOwc0RmJIq2CAPGfvMjk\";alg=\"ed25519\";expires=1770396846;nonce=\"BSIugautfZvN3u5QUgl1mMuyxgmeRsRy9XxX7GXxjJxq1mI0kJl4F-C1nITtOfSeEt6xR1YBfyxsffNKy_wKSA\";tag=\"web-bot-auth\"",
277
+ "Signature-Agent": "sig1=agent-609a4fd2ebf4e6347108c517.agents.vestauth.com"
278
+ }
279
+ ```
280
+
281
+ </details>
282
+
283
+ <details><summary>`provider verify`</summary><br>
284
+
285
+ Verify agent.
286
+
287
+ ```sh
288
+ $ vestauth provider verify GET https://api.vestauth.com/whoami --signature "sig1=:H1kxwSRWFbIzKbHaUy4hQFp/JrmVTX//72JPHcW4W7cPt9q6LytRJgx5pUgWrrr7DCcMWgx/jpTPc8Ht8SZ3CQ==:" --signature-input "sig1=(\"@authority\");created=1770396709;keyid=\"FGzgs758DBGnI1S0BejChDsK0IKZm3qPpOOXdRnnBkM\";alg=\"ed25519\";expires=1770397009;nonce=\"BZSDVktdkjO6XH5jafAdPDttsB6eytXO7u8KXJN1tMtd5bprE3rp08HiaTRo7H6gZGtYb4_qtL7RiGi8P2Gq7w\";tag=\"web-bot-auth\"" --signature-agent "sig1=agent-609a4fd2ebf4e6347108c517.agents.vestauth.com"
289
+ {"uid":"agent-609a4fd2ebf4e6347108c517",...}
290
+ ```
291
+
292
+ </details>
293
+
212
294
  <details><summary>`primitives keypair`</summary><br>
213
295
 
214
296
  Generate public/private keypair.
@@ -252,112 +334,125 @@ $ vestauth primitives headers GET http://example.com --pp
252
334
  Verify signed headers.
253
335
 
254
336
  ```sh
255
- $ vestauth primitives verify GET https://example.com --signature "sig1=:K7z3Nozcq1z5zfJhrd540DWYbjyQ1kR/S7ZDcMXE5gVhxezvG6Rn9BxEvfteiAnBuQhOkvbpGtF83WpQQerGBw==:" --signature-input "sig1=(\"@authority\");created=1770263541;keyid=\"_4GFBGmXKinLBoh3-GJZCiLBt-84GP9Fb0iBzmYncUg\";alg=\"ed25519\";expires=1770263841;nonce=\"0eu7hVMVFm61lQvIryKNmZXIbzkkgpVocoKvN0de5QO8Eu5slTxklJAcVLQs0L_UTVtx4f8qJcqYZ21JTeOQww\";tag=\"web-bot-auth\""
256
- {"success":true}
337
+ $ vestauth primitives verify GET https://api.vestauth.com/whoami --signature "sig1=:UHqXQbWZmyYW40JRcdCl+NLccLgPmcoirUKwLtdcpEcIgxG2+i+Q2U3yIYeMquseON3fKm29WSL2ntHeRefHBQ==:" --signature-input "sig1=(\"@authority\");created=1770395703;keyid=\"FGzgs758DBGnI1S0BejChDsK0IKZm3qPpOOXdRnnBkM\";alg=\"ed25519\";expires=1770396003;nonce=\"O8JOC1reBofwbpPcdD-MRRCdrtAf4khvJTuhpRI_RiaH_hpU93okLkmPZVFFcUEdYtYfcduaB8Sca54GTd2GXA\";tag=\"web-bot-auth\"" --signature-agent "sig1=agent-609a4fd2ebf4e6347108c517.agents.vestauth.com"
338
+ {"uid":"agent-609a4fd2ebf4e6347108c517", ...}
257
339
  ```
258
340
 
259
341
  </details>
260
342
 
261
343
  &nbsp;
262
344
 
263
- ## FAQ
345
+ ## Compare
264
346
 
265
- <details><summary>What problem does Vestauth solve?</summary><br>
347
+ **Agent + Provider Matrix** – Compare Vestauth vs existing auth.
266
348
 
267
- > Vestauth gives agents a cryptographic identity and a simple way to authenticate HTTP requests.
268
- >
269
- > Most agent systems rely on API keys, bearer tokens, or username/passwords. These approaches are difficult to rotate, easy to leak, and hard to attribute to a specific agent.
270
- >
271
- > Vestauth replaces shared secrets with public/private key cryptography. Agents sign requests using a private key, and providers verify those requests using the agent's public key.
349
+ | Capability | Vestauth | API Keys | OAuth | Cookies |
350
+ |---|---|---|---|---|
351
+ | **Agent: no browser required** | | | ⚠️ (depends on flow) | |
352
+ | **Agent: easy to automate** | ✅ | ✅ | ⚠️ | ❌ |
353
+ | **Agent: no shared secret** | | | ⚠️ (bearer tokens) | |
354
+ | **Agent: per‑request identity proof** | ✅ | ❌ | ⚠️ (token‑based) | ❌ |
355
+ | **Agent: easy key/token rotation** | ✅ | ⚠️ | ⚠️ | ⚠️ |
356
+ | **Provider: no secret storage** | ✅ (public keys only) | ❌ | ❌ | ❌ |
357
+ | **Provider: strong attribution to agent** | ✅ | ⚠️ | ⚠️ | ❌ |
358
+ | **Provider: stateless verification** | ✅ | ✅ | ✅ | ❌ |
359
+ | **Provider: simple to implement** | ⚠️ (sig verification) | ✅ | ❌ | ✅ |
360
+ | **Provider: revocation control** | ✅ | ⚠️ | ✅ | ⚠️ |
361
+
362
+ Legend: ✅ strong fit, ⚠️ partial/conditional, ❌ poor fit
363
+
364
+ #### How It Works
365
+
366
+ 1. An agent generates a public/private keypair.
367
+ 2. The agent signs each HTTP request with its private key.
368
+ 3. The provider verifies the signature using the agent’s public key.
369
+ 4. Requests are attributable, auditable, and do not require shared secrets or browser sessions.
272
370
 
273
371
  &nbsp;
274
372
 
275
- </details>
373
+ ## Standards
276
374
 
277
- <details><summary>How does Vestauth authentication work?</summary><br>
375
+ Vestauth builds on open internet standards for agent authentication.
278
376
 
279
- > Vestauth uses HTTP Message Signatures ([RFC 9421](https://datatracker.ietf.org/doc/rfc9421/)). Each request is signed using the agent's private key. The request includes signed headers such as:
280
- >
281
- > * Signature
282
- > * Signature-Input
283
- > * Signature-Agent
284
- >
285
- > Providers verify the request by retrieving the agent's public key from a discovery endpoint and verifying the signature cryptographically.
286
- >
287
- > If the signature is valid, the provider knows the request was created by the agent that owns that private key.
377
+ | Specification | Purpose |
378
+ |------------|------------|
379
+ | **[RFC 9421 – HTTP Message Signatures](https://datatracker.ietf.org/doc/rfc9421/)** | Defines how requests are cryptographically signed and verified |
380
+ | **[Web-Bot-Auth Draft](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture)** | Defines headers and authentication architecture for autonomous agents |
381
+
382
+ Vestauth follows these specifications to ensure interoperability between agents and providers while avoiding vendor lock-in. Vestauth focuses on developer ergonomics while staying compliant with these emerging standards.
288
383
 
289
384
  &nbsp;
290
385
 
291
- </details>
292
386
 
293
- <details><summary>Do I need to run a Vestauth server?</summary><br>
294
387
 
295
- > No.
388
+ ## FAQ
389
+
390
+ <details><summary>What problem does Vestauth solve?</summary><br>
391
+
392
+ > Vestauth gives agents a cryptographic identity and a simple way to authenticate HTTP requests.
296
393
  >
297
- > Vestauth is primarily a client-side and verification library. Agents generate keys locally and sign requests directly. Providers verify requests using public keys exposed via .well-known discovery endpoints.
394
+ > Most agent systems rely on API keys, bearer tokens, or username/passwords. These approaches are difficult to rotate, easy to leak, and hard to attribute to a specific agent.
298
395
  >
299
- > There is no central authentication server required.
396
+ > Vestauth replaces shared secrets with public/private key cryptography. Agents sign requests using a private key, and providers verify those requests using the agent's public key.
300
397
 
301
398
  &nbsp;
302
399
 
303
400
  </details>
304
401
 
305
- <details><summary>Where are agent keys stored?</summary><br>
402
+ <details><summary>Why not just use API keys?</summary><br>
306
403
 
307
- > Agent keys are generated locally and stored in the agent's environment configuration.
308
- >
309
- > * `AGENT_PRIVATE_JWK` is used to sign requests and must never be shared.
310
- > * `AGENT_PUBLIC_JWK` is safe to publish and is used by providers for verification.
404
+ > API keys are shared secrets. Anyone who obtains the key can impersonate the client, and keys are difficult to rotate safely.
311
405
  >
312
- > Vestauth automatically exposes public keys through a discovery endpoint.
406
+ > Vestauth uses cryptographic signing instead of shared secrets. This allows providers to verify identity without storing or distributing sensitive credentials.
313
407
 
314
408
  &nbsp;
315
409
 
316
410
  </details>
317
411
 
318
- <details><summary>Can someone impersonate my agent?</summary><br>
412
+ <details><summary>Where are agent keys stored?</summary><br>
319
413
 
320
- > No, unless they obtain your private key.
321
- >
322
- > Vestauth relies on asymmetric cryptography. Only the holder of the private key can generate valid signatures. Providers verify those signatures using the corresponding public key.
414
+ > Agent keys are generated locally and stored in the agent's environment configuration (`.env`).
323
415
  >
324
- > As long as your private key remains secure, your agent identity cannot be forged.
416
+ > * `AGENT_PRIVATE_JWK` is used to sign requests and must never be shared.
417
+ > * `AGENT_PUBLIC_JWK` is safe to publish and is used by providers for verification.
325
418
 
326
419
  &nbsp;
327
420
 
328
421
  </details>
329
422
 
330
- <details><summary>Why does Vestauth use public key discovery?</summary><br>
423
+ <details><summary>Is Vestauth only for AI agents?</summary><br>
331
424
 
332
- > Public key discovery allows providers to verify agent signatures without manual key exchange. Each agent hosts its public keys in a standardized .well-known directory.
425
+ > No.
333
426
  >
334
- > This enables dynamic agent onboarding while preserving cryptographic verification.
427
+ > Vestauth can authenticate any automated system including:
428
+ >
429
+ > * developer tools
430
+ > * CLIs
431
+ > * automation services
432
+ > * bots
433
+ > * infrastructure tools
335
434
 
336
435
  &nbsp;
337
436
 
338
437
  </details>
339
438
 
340
- <details><summary>Does Vestauth send secrets over the network?</summary><br>
439
+ <details><summary>Can Vestauth work without curl?</summary><br>
341
440
 
342
- > No.
441
+ > Yes.
343
442
  >
344
- > Vestauth signs requests using private keys locally. Only public keys are shared for verification.
443
+ > Vestauth provides libraries and primitives that can be integrated into any HTTP client or framework. The CLI simply makes it easy to adopt and demonstrate.
345
444
 
346
445
  &nbsp;
347
446
 
348
447
  </details>
349
448
 
350
- <details><summary>Is Vestauth production ready?</summary><br>
449
+ <details><summary>Do I need to run a Vestauth server?</summary><br>
351
450
 
352
- > Yes.
353
- >
354
- > Vestauth is built on established cryptographic and HTTP standards:
451
+ > No.
355
452
  >
356
- > * RFC 9421 HTTP Message Signatures
357
- > * JOSE / JWK key formats
358
- > * Web-Bot-Auth draft architecture
453
+ > Vestauth is primarily a client-side and verification library. Agents generate keys locally and sign requests directly. Providers verify requests using public keys exposed via .well-known discovery endpoints.
359
454
  >
360
- > These standards are designed for secure, verifiable HTTP communication.
455
+ > There is no central authentication server required.
361
456
 
362
457
  &nbsp;
363
458
 
@@ -376,37 +471,17 @@ $ vestauth primitives verify GET https://example.com --signature "sig1=:K7z3Nozc
376
471
 
377
472
  </details>
378
473
 
379
- <details><summary>Can Vestauth work without curl?</summary><br>
380
-
381
- > Yes.
382
- >
383
- > Vestauth provides libraries and primitives that can be integrated into any HTTP client or framework. The CLI simply makes it easy to adopt and demonstrate.
384
-
385
- &nbsp;
386
-
387
- </details>
388
-
389
- <details><summary>Is Vestauth only for AI agents?</summary><br>
474
+ <details><summary>How does Vestauth authentication work?</summary><br>
390
475
 
391
- > No.
476
+ > Vestauth uses HTTP Message Signatures ([RFC 9421](https://datatracker.ietf.org/doc/rfc9421/)). Each request is signed using the agent's private key. The request includes signed headers such as:
392
477
  >
393
- > Vestauth can authenticate any automated system including:
478
+ > * Signature
479
+ > * Signature-Input
480
+ > * Signature-Agent
394
481
  >
395
- > * developer tools
396
- > * CLIs
397
- > * automation services
398
- > * bots
399
- > * infrastructure tools
400
-
401
- &nbsp;
402
-
403
- </details>
404
-
405
- <details><summary>Why not just use API keys?</summary><br>
406
-
407
- > API keys are shared secrets. Anyone who obtains the key can impersonate the client, and keys are difficult to rotate safely.
482
+ > Providers verify the request by retrieving the agent's public key from a discovery endpoint and verifying the signature cryptographically.
408
483
  >
409
- > Vestauth uses cryptographic signing instead of shared secrets. This allows providers to verify identity without storing or distributing sensitive credentials.
484
+ > If the signature is valid, the provider knows the request was created by the agent that owns that private key.
410
485
 
411
486
  &nbsp;
412
487
 
@@ -436,6 +511,26 @@ $ vestauth primitives verify GET https://example.com --signature "sig1=:K7z3Nozc
436
511
 
437
512
  </details>
438
513
 
514
+ <details><summary>Why does Vestauth use public key discovery?</summary><br>
515
+
516
+ > Public key discovery allows providers to verify agent signatures without manual key exchange. Each agent hosts its public keys in a standardized .well-known directory.
517
+ >
518
+ > This enables dynamic agent onboarding while preserving cryptographic verification.
519
+
520
+ &nbsp;
521
+
522
+ </details>
523
+
524
+ <details><summary>Does Vestauth send secrets over the network?</summary><br>
525
+
526
+ > No.
527
+ >
528
+ > Vestauth signs requests using private keys locally. Only public keys are shared for verification.
529
+
530
+ &nbsp;
531
+
532
+ </details>
533
+
439
534
  <details><summary>How does Vestauth avoid SSRF during public key discovery?</summary><br>
440
535
 
441
536
  > Vestauth prevents Server-Side Request Forgery (SSRF) by restricting public key discovery to trusted domains.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vestauth",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "description": "auth for agents–from the creator of dotenvx",
5
5
  "keywords": [
6
6
  "vestauth"
@@ -38,14 +38,10 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@dotenvx/dotenvx": "^1.52.0",
41
- "@noble/hashes": "^1.8.0",
42
- "@noble/secp256k1": "^1.7.2",
43
41
  "commander": "^11.1.0",
44
- "eciesjs": "^0.4.16",
45
42
  "execa": "^5.1.1",
46
43
  "structured-headers": "^2.0.2",
47
- "undici": "7.11.0",
48
- "web-bot-auth": "^0.1.2"
44
+ "undici": "7.11.0"
49
45
  },
50
46
  "devDependencies": {
51
47
  "@yao-pkg/pkg": "^5.14.2",
@@ -55,6 +51,7 @@
55
51
  "sinon": "^14.0.1",
56
52
  "standard": "^17.1.0",
57
53
  "standard-version": "^9.5.0",
58
- "tap": "^21.0.1"
54
+ "tap": "^21.0.1",
55
+ "web-bot-auth": "^0.1.2"
59
56
  }
60
57
  }
@@ -1,6 +1,7 @@
1
1
  const { logger } = require('./../../../shared/logger')
2
2
  const agent = require('./../../../lib/agent')
3
3
  const execute = require('./../../../lib/helpers/execute')
4
+ const Errors = require('./../../../lib/helpers/errors')
4
5
  const findUrl = require('./../../../lib/helpers/findUrl')
5
6
  const catchAndLog = require('./../../../lib/helpers/catchAndLog')
6
7
 
@@ -27,7 +28,7 @@ async function curl () {
27
28
 
28
29
  if (exitCode !== 0) {
29
30
  logger.debug(`received exitCode ${exitCode}`)
30
- throw new Error(`Command exited with exit code ${exitCode}`)
31
+ throw new Errors({ exitCode }).commandFailed()
31
32
  }
32
33
 
33
34
  let space = 0
@@ -28,7 +28,6 @@ async function verify (httpMethod, uri) {
28
28
  const publicJwk = options.publicJwk ? JSON.parse(options.publicJwk) : undefined
29
29
 
30
30
  const output = await primitives.verify(httpMethod, uri, headers, publicJwk)
31
- // const output = await primitive.verifyWebBotAuth(httpMethod, uri, signature, signatureInput, JSON.parse(publicJwk))
32
31
 
33
32
  let space = 0
34
33
  if (options.prettyPrint) {
@@ -12,7 +12,6 @@ agent
12
12
  const initAction = require('./../actions/agent/init')
13
13
  agent.command('init')
14
14
  .description('create agent')
15
- .option('--pp, --pretty-print', 'pretty print output')
16
15
  .action(initAction)
17
16
 
18
17
  // vestauth agent curl
@@ -1,6 +1,7 @@
1
1
  class Errors {
2
2
  constructor (options = {}) {
3
3
  this.message = options.message
4
+ this.exitCode = options.exitCode
4
5
  }
5
6
 
6
7
  missingId () {
@@ -107,6 +108,15 @@ class Errors {
107
108
  return e
108
109
  }
109
110
 
111
+ commandFailed () {
112
+ const code = 'COMMAND_FAILED'
113
+ const message = `[${code}] command failed with exit code ${this.exitCode}`
114
+
115
+ const e = new Error(message)
116
+ e.code = code
117
+ return e
118
+ }
119
+
110
120
  econnrefused () {
111
121
  const code = 'ECONNREFUSED'
112
122
  const message = `[${code}] connection refused`
@@ -19,18 +19,6 @@ async function headers (httpMethod, uri, id, privateJwk, tag = 'web-bot-auth', n
19
19
  const kid = thumbprint(privateJwk)
20
20
  privateJwk.kid = kid
21
21
 
22
- // // theirs
23
- // const request = new Request(uri)
24
- // const now = new Date()
25
- // return await signatureHeaders(
26
- // request,
27
- // await signerFromJWK(JSON.parse(privateJwk)),
28
- // {
29
- // created: now,
30
- // expires: new Date(now.getTime() + 300_000), // now + 5 min
31
- // }
32
- // )
33
-
34
22
  const signatureInput = signatureParams(privateJwk.kid, tag, nonce)
35
23
  const signature = webBotAuthSignature(httpMethod, uri, signatureInput, privateJwk)
36
24
  const signatureAgent = `${id}.agents.vestauth.com` // agent-1234.agents.vestauth.com (no scheme) /.well-known/http-message-signatures-directory
@@ -1,11 +1,9 @@
1
1
  const keypair = require('./helpers/keypair')
2
2
  const headers = require('./helpers/headers')
3
3
  const verify = require('./helpers/verify')
4
- const verifyWebBotAuth = require('./helpers/verifyWebBotAuth')
5
4
 
6
5
  module.exports = {
7
6
  keypair,
8
7
  headers,
9
- verify,
10
- verifyWebBotAuth
8
+ verify
11
9
  }
@@ -1,115 +0,0 @@
1
- const path = require('path')
2
- const which = require('which')
3
- const execute = require('./../../lib/helpers/execute')
4
- const { logger } = require('./../../shared/logger')
5
-
6
- async function executeCommand (commandArgs) {
7
- const signals = [
8
- 'SIGHUP', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
9
- 'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2'
10
- ]
11
-
12
- logger.debug(`executing process command [${commandArgs.join(' ')}]`)
13
-
14
- let child
15
- let signalSent
16
-
17
- /* c8 ignore start */
18
- const sigintHandler = () => {
19
- logger.debug('received SIGINT')
20
- logger.debug('checking command process')
21
- logger.debug(child)
22
-
23
- if (child) {
24
- logger.debug('sending SIGINT to command process')
25
- signalSent = 'SIGINT'
26
- child.kill('SIGINT') // Send SIGINT to the command process
27
- } else {
28
- logger.debug('no command process to send SIGINT to')
29
- }
30
- }
31
-
32
- const sigtermHandler = () => {
33
- logger.debug('received SIGTERM')
34
- logger.debug('checking command process')
35
- logger.debug(child)
36
-
37
- if (child) {
38
- logger.debug('sending SIGTERM to command process')
39
- signalSent = 'SIGTERM'
40
- child.kill('SIGTERM') // Send SIGTERM to the command process
41
- } else {
42
- logger.debug('no command process to send SIGTERM to')
43
- }
44
- }
45
-
46
- const handleOtherSignal = (signal) => {
47
- logger.debug(`received ${signal}`)
48
- child.kill(signal)
49
- }
50
- /* c8 ignore stop */
51
-
52
- try {
53
- // ensure the first command is expanded
54
- try {
55
- commandArgs[0] = path.resolve(which.sync(`${commandArgs[0]}`))
56
- logger.debug(`expanding process command to [${commandArgs.join(' ')}]`)
57
- } catch (e) {
58
- logger.debug(`could not expand process command. using [${commandArgs.join(' ')}]`)
59
- }
60
-
61
- // expand any other commands that follow a --
62
- let expandNext = false
63
- for (let i = 0; i < commandArgs.length; i++) {
64
- if (commandArgs[i] === '--') {
65
- expandNext = true
66
- } else if (expandNext) {
67
- try {
68
- commandArgs[i] = path.resolve(which.sync(`${commandArgs[i]}`))
69
- logger.debug(`expanding process command to [${commandArgs.join(' ')}]`)
70
- } catch (e) {
71
- logger.debug(`could not expand process command. using [${commandArgs.join(' ')}]`)
72
- }
73
- expandNext = false
74
- }
75
- }
76
-
77
- child = execute.execa(commandArgs[0], commandArgs.slice(1), {
78
- stdio: 'inherit'
79
- })
80
-
81
- process.on('SIGINT', sigintHandler)
82
- process.on('SIGTERM', sigtermHandler)
83
-
84
- signals.forEach(signal => {
85
- process.on(signal, () => handleOtherSignal(signal))
86
- })
87
-
88
- // Wait for the command process to finish
89
- const { exitCode } = await child
90
-
91
- if (exitCode !== 0) {
92
- logger.debug(`received exitCode ${exitCode}`)
93
- throw new Error(`Command exited with exit code ${exitCode}`)
94
- }
95
- } catch (error) {
96
- // no color on these errors as they can be standard errors for things like jest exiting with exitCode 1 for a single failed test.
97
- if (!['SIGINT', 'SIGTERM'].includes(signalSent || error.signal)) {
98
- if (error.code === 'ENOENT') {
99
- logger.error(`Unknown command: ${error.command}`)
100
- } else {
101
- logger.error(error.message)
102
- }
103
- }
104
-
105
- // Exit with the error code from the command process, or 1 if unavailable
106
- process.exit(error.exitCode || 1)
107
- } finally {
108
- // Clean up: Remove the SIGINT handler
109
- process.removeListener('SIGINT', sigintHandler)
110
- // Clean up: Remove the SIGTERM handler
111
- process.removeListener('SIGTERM', sigtermHandler)
112
- }
113
- }
114
-
115
- module.exports = executeCommand
@@ -1,8 +0,0 @@
1
- const { sha256 } = require('@noble/hashes/sha2.js')
2
- const { utf8ToBytes } = require('@noble/hashes/utils.js')
3
-
4
- function hash (message = '') {
5
- return sha256(utf8ToBytes(message))
6
- }
7
-
8
- module.exports = hash
@@ -1,25 +0,0 @@
1
- const { verify } = require('web-bot-auth')
2
- const { verifierFromJWK } = require('web-bot-auth/crypto')
3
-
4
- async function verifyWebBotAuth (httpMethod, uri, signatureHeader, signatureInputHeader, publicJwk) {
5
- let success = false
6
-
7
- const verifier = await verifierFromJWK(publicJwk)
8
- const signedRequest = new Request(uri, {
9
- headers: {
10
- Signature: signatureHeader,
11
- 'Signature-Input': signatureInputHeader
12
- }
13
- })
14
-
15
- try {
16
- await verify(signedRequest, verifier)
17
- success = true
18
- } catch (_e) {}
19
-
20
- return {
21
- success
22
- }
23
- }
24
-
25
- module.exports = verifyWebBotAuth