vestauth 0.21.0 → 0.22.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/CHANGELOG.md +14 -2
- package/README.md +220 -93
- package/package.json +2 -2
- package/src/cli/actions/agent/curl.js +52 -1
- package/src/lib/helpers/touch.js +1 -1
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.
|
|
5
|
+
[Unreleased](https://github.com/vestauth/vestauth/compare/v0.22.0...main)
|
|
6
|
+
|
|
7
|
+
## [0.22.0](https://github.com/vestauth/vestauth/compare/v0.21.1...v0.22.0) (2026-03-02)
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
* `agent curl` now by default prepends `-X POST` and `-H "Content-Type: application/json"` ([#45](https://github.com/vestauth/vestauth/pull/45))
|
|
12
|
+
|
|
13
|
+
## [0.21.1](https://github.com/vestauth/vestauth/compare/v0.21.0...v0.21.1) (2026-02-25)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
* README changes
|
|
6
18
|
|
|
7
19
|
## [0.21.0](https://github.com/vestauth/vestauth/compare/v0.20.1...v0.21.0) (2026-02-25)
|
|
8
20
|
|
|
@@ -88,7 +100,7 @@ All notable changes to this project will be documented in this file. See [standa
|
|
|
88
100
|
|
|
89
101
|
### Changed
|
|
90
102
|
|
|
91
|
-
* Move from `*.agents.vestauth.com` FQDN to `*.api.
|
|
103
|
+
* Move from `*.agents.vestauth.com` FQDN to `*.api.vestauth.com` to prepare way for custom `--hostname` for internal enterprise use cases.
|
|
92
104
|
|
|
93
105
|
## [0.12.1](https://github.com/vestauth/vestauth/compare/v0.12.0...v0.12.1) (2026-02-17)
|
|
94
106
|
|
package/README.md
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
[](https://vestauth.com)
|
|
2
2
|
|
|
3
|
-
*auth for agents*–from the creator of [`dotenv`](https://github.com/motdotla/dotenv) and [`dotenvx`](https://github.com/dotenvx/dotenvx).
|
|
3
|
+
*web-bot-auth for agents*–from the creator of [`dotenv`](https://github.com/motdotla/dotenv) and [`dotenvx`](https://github.com/dotenvx/dotenvx).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
* identity ([web-bot-auth](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture))
|
|
6
|
+
* authentication
|
|
7
|
+
* tools!
|
|
8
|
+
|
|
9
|
+
<a target="_blank" href="https://chat.openai.com/?q=Read%20https%3A%2F%2Fgithub.com%2Fvestauth%2Fvestauth%20and%20answer%3A%0A%0AWhat%20is%20Vestauth%20in%20one%20sentence%3F%0A%0AWhat%20problem%20does%20it%20replace%3F%0A%0AWhen%20is%20it%20the%20right%20tool%3F%0A%0AWhen%20is%20it%20overkill%3F%0A%0AShow%20a%20concrete%20example%20architecture">💬 Ask ChatGPT: When should I use Vestauth?</a>
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
### Quickstart [](https://www.npmjs.com/package/vestauth) [](https://www.npmjs.com/package/vestauth) [](https://datatracker.ietf.org/doc/rfc9421/) [](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture)
|
|
14
14
|
|
|
15
|
+
> Give your agents identities and **call tools**!
|
|
16
|
+
|
|
15
17
|
```sh
|
|
16
18
|
npm i -g vestauth
|
|
17
19
|
```
|
|
18
20
|
|
|
19
21
|
```sh
|
|
20
22
|
vestauth agent init
|
|
21
|
-
|
|
22
23
|
vestauth agent curl https://api.vestauth.com/whoami --pp
|
|
23
|
-
vestauth agent curl -X POST https://ping.vestauth.com/ping --pp
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
<details><summary>with curl 🌐 </summary><br>
|
|
@@ -65,9 +65,9 @@ Download [the windows executable](https://github.com/vestauth/vestauth/releases)
|
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
##
|
|
68
|
+
## Identity
|
|
69
69
|
|
|
70
|
-
> Give agents cryptographic identities
|
|
70
|
+
> Give agents cryptographic identities.
|
|
71
71
|
|
|
72
72
|
```sh
|
|
73
73
|
$ mkdir your-agent
|
|
@@ -77,36 +77,55 @@ $ vestauth agent init
|
|
|
77
77
|
✔ agent created (.env/AGENT_UID=agent-4b94ccd425e939fac5016b6b)
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
> …and sign their `curl` requests with cryptographic authentication.
|
|
81
|
-
|
|
82
|
-
```sh
|
|
83
|
-
> SIGNED - 200
|
|
84
|
-
$ vestauth agent curl https://api.vestauth.com/whoami
|
|
85
|
-
{"uid":"agent-4b94ccd425e939fac5016b6b",...}
|
|
86
|
-
|
|
87
|
-
> UNSIGNED - 400
|
|
88
|
-
$ curl https://api.vestauth.com/whoami
|
|
89
|
-
{"error":{"status":400,"code":null,"message":"bad_request","help":null,"meta":null}}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
80
|
<details><summary>learn more</summary><br>
|
|
93
81
|
|
|
94
|
-
|
|
82
|
+
Your agent's identity lives in a simple `.env` file.
|
|
95
83
|
|
|
96
84
|
```ini
|
|
97
85
|
# .env
|
|
86
|
+
AGENT_UID="agent-4b94ccd425e939fac5016b6b"
|
|
98
87
|
AGENT_PUBLIC_JWK="{"crv":"Ed25519","x":"py2xNaAfjKZiau-jtmJls6h_3n8xJ1Ur0ie-n9b8zWg","kty":"OKP","kid":"B0u80Gw28W9U2Jl5t_EBiWeBajO2104kOYZ9Ikucl5I"}"
|
|
99
88
|
AGENT_PRIVATE_JWK="{"crv":"Ed25519","d":"Z9vbwN-3eiFMVv_TPWXOxqSMJAT21kZvejWi72yiAaQ","x":"py2xNaAfjKZiau-jtmJls6h_3n8xJ1Ur0ie-n9b8zWg","kty":"OKP","kid":"B0u80Gw28W9U2Jl5t_EBiWeBajO2104kOYZ9Ikucl5I"}"
|
|
100
|
-
AGENT_UID="agent-4b94ccd425e939fac5016b6b"
|
|
101
89
|
```
|
|
102
90
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
91
|
+
[💬 Ask ChatGPT: Are HTTP message signatures more secure than API keys?](https://chat.openai.com/?q=Are%20HTTP%20message%20signatures%20more%20secure%20than%20API%20keys%3F)
|
|
92
|
+
|
|
93
|
+
</details>
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
## Authentication
|
|
98
|
+
|
|
99
|
+
> Authenticate agents – `vestauth.tool.verify`…
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
...
|
|
103
|
+
const vestauth = require('vestauth')
|
|
104
|
+
|
|
105
|
+
app.get('/whoami', async (req, res) => {
|
|
106
|
+
try {
|
|
107
|
+
const url = `${req.protocol}://${req.get('host')}${req.originalUrl}`
|
|
108
|
+
const agent = await vestauth.tool.verify(req.method, url, req.headers)
|
|
109
|
+
|
|
110
|
+
res.json(agent)
|
|
111
|
+
} catch (err) {
|
|
112
|
+
res.status(401).json({ code: 401, error: { message: err.message }})
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
...
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
> …the agents sign HTTP requests with a drop-in curl wrapper.
|
|
119
|
+
|
|
120
|
+
```sh
|
|
121
|
+
> SIGNED - 200
|
|
122
|
+
$ vestauth agent curl https://api.vestauth.com/whoami
|
|
123
|
+
{"uid":"agent-4b94ccd425e939fac5016b6b",...}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
<details><summary>learn more</summary><br>
|
|
108
127
|
|
|
109
|
-
|
|
128
|
+
`vestauth agent curl` autosigns `curl` requests – injecting valid signed headers according to the [web-bot-auth draft](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture). You can peek these with the built-in `headers` primitive.
|
|
110
129
|
|
|
111
130
|
```sh
|
|
112
131
|
$ vestauth primitives headers GET https://api.vestauth.com/whoami --pp
|
|
@@ -117,73 +136,177 @@ $ vestauth primitives headers GET https://api.vestauth.com/whoami --pp
|
|
|
117
136
|
}
|
|
118
137
|
```
|
|
119
138
|
|
|
120
|
-
|
|
139
|
+
</details>
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
## Tools
|
|
144
|
+
|
|
145
|
+
> Call tools!
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
$ vestauth agent curl https://sfs.vestauth.com/write -d '{"filepath":"/hello.md", "content":"hello"}'
|
|
149
|
+
$ vestauth agent curl https://sfs.vestauth.com/list
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### First Party Tools
|
|
153
|
+
|
|
154
|
+
<details><summary>`SFS` Simple File System</summary><br/>
|
|
155
|
+
|
|
156
|
+
> SFS is a simple file system for vestauth agents.
|
|
157
|
+
> [sfs.vestauth.com](https://sfs.vestauth.com)
|
|
158
|
+
|
|
159
|
+
```sh
|
|
160
|
+
# write a file
|
|
161
|
+
vestauth agent curl https://sfs.vestauth.com/write -d '{"filepath":"/hello.md", "content":"hello"}'
|
|
162
|
+
|
|
163
|
+
# delete a file
|
|
164
|
+
vestauth agent curl https://sfs.vestauth.com/delete -d '{"filepath":"/hello.md"}'
|
|
165
|
+
|
|
166
|
+
# list files
|
|
167
|
+
vestauth agent curl https://sfs.vestauth.com/list
|
|
168
|
+
|
|
169
|
+
# read a file
|
|
170
|
+
vestauth agent curl https://sfs.vestauth.com/read -d '{"filepath":"/hello.md"}'
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
|
|
121
174
|
|
|
122
175
|
</details>
|
|
176
|
+
<details><summary>`Ping` ping.vestauth.com</summary><br/>
|
|
177
|
+
|
|
178
|
+
> Ping is a demonstration of vestauth.
|
|
179
|
+
> [ping.vestauth.com](https://ping.vestauth.com)
|
|
180
|
+
|
|
181
|
+
```sh
|
|
182
|
+
# make a ping
|
|
183
|
+
vestauth agent curl https://ping.vestauth.com/ping
|
|
184
|
+
```
|
|
123
185
|
|
|
124
186
|
|
|
125
187
|
|
|
126
|
-
|
|
188
|
+
</details>
|
|
127
189
|
|
|
128
|
-
|
|
190
|
+
#### Third Party Tools
|
|
129
191
|
|
|
130
|
-
|
|
131
|
-
// index.js
|
|
132
|
-
const express = require('express')
|
|
133
|
-
const vestauth = require('vestauth')
|
|
134
|
-
const app = express()
|
|
192
|
+
<details><summary>`AS2` Agentic Secret Storage</summary><br/>
|
|
135
193
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
try {
|
|
139
|
-
const url = `${req.protocol}://${req.get('host')}${req.originalUrl}`
|
|
194
|
+
> AS2 is a simple, agent-friendly secret storage.
|
|
195
|
+
> [as2.dotenvx.com](https://as2.dotenvx.com)
|
|
140
196
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// authenticated tool — verifying signatures, keys, and returning the agent. //
|
|
145
|
-
// --------------------------------------------------------------------------------
|
|
146
|
-
const agent = await vestauth.tool.verify(req.method, url, req.headers)
|
|
197
|
+
```sh
|
|
198
|
+
# set a secret
|
|
199
|
+
vestauth agent curl https://as2.dotenvx.com/set -d '{"KEY":"value"}'
|
|
147
200
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
res.status(401).json({ code: 401, error: { message: err.message }})
|
|
151
|
-
}
|
|
152
|
-
})
|
|
201
|
+
# get all secrets
|
|
202
|
+
vestauth agent curl "https://as2.dotenvx.com/get"
|
|
153
203
|
|
|
154
|
-
|
|
204
|
+
# get single secret
|
|
205
|
+
vestauth agent curl "https://as2.dotenvx.com/get?key=KEY"
|
|
206
|
+
|
|
207
|
+
# get multiple secrets
|
|
208
|
+
vestauth agent curl "https://as2.dotenvx.com/get?key=KEY,TWILIO"
|
|
155
209
|
```
|
|
156
210
|
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
</details>
|
|
214
|
+
<details><summary>`Docle` Check if email address is real</summary><br>
|
|
215
|
+
|
|
216
|
+
> Check if an email address is real before you hit send. Verifies syntax, DNS, MX records, SMTP mailbox existence, and cross-references multiple providers. All in real time, no signup required.
|
|
217
|
+
>
|
|
218
|
+
> [learn more](https://github.com/treadiehq/docle)
|
|
219
|
+
|
|
157
220
|
```sh
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
221
|
+
# verify an email
|
|
222
|
+
vestauth agent curl https://docle.co/api/verify -d '{"emails":["test@example.com"]}'
|
|
223
|
+
|
|
224
|
+
# check your usage
|
|
225
|
+
vestauth agent curl https://docle.co/api/agent/usage -X GET
|
|
161
226
|
```
|
|
162
227
|
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
</details>
|
|
231
|
+
<details><summary>more coming soon</summary><br/>
|
|
232
|
+
|
|
233
|
+
* Geo IP - coming soon
|
|
234
|
+
* Send/Receive Email - coming
|
|
235
|
+
* Send/Receive SMS - coming
|
|
236
|
+
* Send/Receive Telegram - coming
|
|
237
|
+
* Send/Receive WhatsApp - coming
|
|
238
|
+
* Human-in-the-loop - coming
|
|
239
|
+
* Rotate NPM Tokens - coming
|
|
240
|
+
* Rotate GitHub Tokens - coming
|
|
241
|
+
* Working on a tool? Tell us and wel'll list it.
|
|
242
|
+
|
|
243
|
+
</details>
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
## Self-hosting
|
|
248
|
+
|
|
249
|
+
> Run your own Vestauth server.
|
|
250
|
+
|
|
251
|
+
| |
|
|
252
|
+
|---|
|
|
253
|
+
| <a target="_blank" href="https://github.com/user-attachments/assets/b05ba917-c37a-4a53-9ec7-c5c8d78ad1c7"><img src="https://github.com/user-attachments/assets/b05ba917-c37a-4a53-9ec7-c5c8d78ad1c7" alt="self-hosting vestauth" width="480"></a> |
|
|
254
|
+
|
|
255
|
+
Initialize the server and run migrations (postgres).
|
|
256
|
+
|
|
163
257
|
```sh
|
|
164
|
-
$ vestauth
|
|
165
|
-
|
|
258
|
+
$ curl -sSf https://vestauth.sh | sh
|
|
259
|
+
$ vestauth server init
|
|
260
|
+
$ vestauth server db:create
|
|
261
|
+
$ vestauth server db:migrate
|
|
166
262
|
```
|
|
167
263
|
|
|
168
|
-
|
|
264
|
+
Start the server.
|
|
169
265
|
|
|
170
266
|
```sh
|
|
171
|
-
|
|
267
|
+
$ vestauth server start
|
|
268
|
+
vestauth server listening on http://localhost:3000
|
|
172
269
|
```
|
|
173
270
|
|
|
174
|
-
|
|
271
|
+
And use your server's hostname when creating agents.
|
|
175
272
|
|
|
176
|
-
|
|
273
|
+
```sh
|
|
274
|
+
$ mkdir your-agent
|
|
275
|
+
$ cd your-agent
|
|
177
276
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
277
|
+
$ vestauth agent init --hostname http://localhost:3000
|
|
278
|
+
✔ agent created (.env/AGENT_UID=agent-4b94ccd425e939fac5016b6b)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
That's it. Your Vestauth ([web-bot-auth](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture)) infrastructure is now running under your control.
|
|
282
|
+
|
|
283
|
+
More details
|
|
284
|
+
|
|
285
|
+
<details><summary>config</summary><br>
|
|
286
|
+
|
|
287
|
+
Edit the `.env` file to configure your server.
|
|
288
|
+
|
|
289
|
+
```ini
|
|
290
|
+
PORT="3000"
|
|
291
|
+
HOSTNAME="http://localhost:3000"
|
|
292
|
+
DATABASE_URL="postgres://localhost/vestauth_production"
|
|
293
|
+
```
|
|
183
294
|
|
|
184
|
-
|
|
295
|
+
For example, in production:
|
|
185
296
|
|
|
186
|
-
|
|
297
|
+
* Change `HOSTNAME` to its production url - e.g. `vestauth.yoursite.com`
|
|
298
|
+
* Change `DATABASE_URL` to a managed postgres - e.g. `postgresql://USER:PASS@aws-1-us-east-1.pooler.supabase.com:5432/postgres`
|
|
299
|
+
|
|
300
|
+
</details>
|
|
301
|
+
<details><summary>production note</summary><br>
|
|
302
|
+
|
|
303
|
+
> [!WARNING]
|
|
304
|
+
>
|
|
305
|
+
> **Production note:** Configure a wildcard DNS record for `*.${HOSTNAME}`.
|
|
306
|
+
>
|
|
307
|
+
> Example: if `HOSTNAME=vestauth.yourapp.com`, add `*.vestauth.yourapp.com`.
|
|
308
|
+
>
|
|
309
|
+
> Required for `.well-known` discovery per the [web-bot-auth](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture) spec.
|
|
187
310
|
|
|
188
311
|
</details>
|
|
189
312
|
|
|
@@ -313,6 +436,17 @@ $ vestauth tool verify GET https://api.vestauth.com/whoami --signature "sig1=:H1
|
|
|
313
436
|
{"uid":"agent-609a4fd2ebf4e6347108c517",...}
|
|
314
437
|
```
|
|
315
438
|
|
|
439
|
+
</details>
|
|
440
|
+
<details><summary>`server init`</summary><br>
|
|
441
|
+
|
|
442
|
+
Create/update server `.env` for self-hosting (`PORT`, `HOSTNAME`, `DATABASE_URL`).
|
|
443
|
+
|
|
444
|
+
```sh
|
|
445
|
+
$ vestauth server init
|
|
446
|
+
✔ ready (.env/HOSTNAME=http://localhost:3000)
|
|
447
|
+
⮕ next run: [vestauth server start]
|
|
448
|
+
```
|
|
449
|
+
|
|
316
450
|
</details>
|
|
317
451
|
<details><summary>`server db:create`</summary><br>
|
|
318
452
|
|
|
@@ -461,11 +595,16 @@ await vestauth.primitives.verify(httpMethod, url, headers, publicJwk)
|
|
|
461
595
|
|
|
462
596
|
|
|
463
597
|
|
|
464
|
-
##
|
|
598
|
+
## Standards
|
|
465
599
|
|
|
466
|
-
>
|
|
600
|
+
> 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 tools verify those requests using the agent's public key. All built on open internet standards. It's elegant and the future.
|
|
467
601
|
|
|
468
|
-
|
|
602
|
+
| Specification | Purpose |
|
|
603
|
+
|------------|------------|
|
|
604
|
+
| **[RFC 9421](https://datatracker.ietf.org/doc/rfc9421/)** | Defines how requests are cryptographically signed and verified |
|
|
605
|
+
| **[Web-Bot-Auth Draft](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture)** | Defines headers and authentication architecture for autonomous agents |
|
|
606
|
+
|
|
607
|
+
Vestauth follows these specifications to ensure interoperability between agents and tools while avoiding vendor lock-in. Vestauth focuses on developer ergonomics while staying compliant with these emerging standards.
|
|
469
608
|
|
|
470
609
|
|
|
471
610
|
|
|
@@ -497,26 +636,6 @@ Legend: ✅ strong fit, ⚠️ partial/conditional, ❌ poor fit
|
|
|
497
636
|
|
|
498
637
|
|
|
499
638
|
|
|
500
|
-
## Standards
|
|
501
|
-
|
|
502
|
-
Vestauth builds on open internet standards for agent authentication.
|
|
503
|
-
|
|
504
|
-
| Specification | Purpose |
|
|
505
|
-
|------------|------------|
|
|
506
|
-
| **[RFC 9421 – HTTP Message Signatures](https://datatracker.ietf.org/doc/rfc9421/)** | Defines how requests are cryptographically signed and verified |
|
|
507
|
-
| **[Web-Bot-Auth Draft](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture)** | Defines headers and authentication architecture for autonomous agents |
|
|
508
|
-
|
|
509
|
-
Vestauth follows these specifications to ensure interoperability between agents and tools while avoiding vendor lock-in. Vestauth focuses on developer ergonomics while staying compliant with these emerging standards.
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
## Demo
|
|
514
|
-
|
|
515
|
-
[](https://ping.vestauth.com)
|
|
516
|
-
> [https://ping.vestauth.com](https://ping.vestauth.com)
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
639
|
## FAQ
|
|
521
640
|
|
|
522
641
|
<details><summary>What problem does Vestauth solve?</summary><br>
|
|
@@ -530,7 +649,15 @@ Vestauth follows these specifications to ensure interoperability between agents
|
|
|
530
649
|
|
|
531
650
|
|
|
532
651
|
</details>
|
|
652
|
+
<details><summary>Is there a demo video?</summary><br>
|
|
533
653
|
|
|
654
|
+
> Yes
|
|
655
|
+
>
|
|
656
|
+
> [Watch the demo](https://www.youtube.com/watch?v=cHARyULr_qk)
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
</details>
|
|
534
661
|
<details><summary>Why not just use API keys?</summary><br>
|
|
535
662
|
|
|
536
663
|
> API keys are shared secrets. Anyone who obtains the key can impersonate the client, and keys are difficult to rotate safely.
|
package/package.json
CHANGED
|
@@ -5,6 +5,53 @@ const Errors = require('./../../../lib/helpers/errors')
|
|
|
5
5
|
const findUrl = require('./../../../lib/helpers/findUrl')
|
|
6
6
|
const catchAndLog = require('./../../../lib/helpers/catchAndLog')
|
|
7
7
|
|
|
8
|
+
function requestMethodFromArgs (args) {
|
|
9
|
+
for (let i = 0; i < args.length; i++) {
|
|
10
|
+
const arg = args[i]
|
|
11
|
+
|
|
12
|
+
if (arg === '-X' || arg === '--request') {
|
|
13
|
+
const method = args[i + 1]
|
|
14
|
+
if (method) return method.toUpperCase()
|
|
15
|
+
continue
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (arg.startsWith('--request=')) {
|
|
19
|
+
return arg.slice('--request='.length).toUpperCase()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (arg.startsWith('-X') && arg.length > 2) {
|
|
23
|
+
return arg.slice(2).toUpperCase()
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return null
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function hasContentTypeHeader (args) {
|
|
31
|
+
for (let i = 0; i < args.length; i++) {
|
|
32
|
+
const arg = args[i]
|
|
33
|
+
|
|
34
|
+
if (arg === '-H' || arg === '--header') {
|
|
35
|
+
const header = args[i + 1] || ''
|
|
36
|
+
if (header.toLowerCase().startsWith('content-type:')) return true
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (arg.startsWith('--header=')) {
|
|
41
|
+
const header = arg.slice('--header='.length)
|
|
42
|
+
if (header.toLowerCase().startsWith('content-type:')) return true
|
|
43
|
+
continue
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (arg.startsWith('-H') && arg.length > 2) {
|
|
47
|
+
const header = arg.slice(2)
|
|
48
|
+
if (header.toLowerCase().startsWith('content-type:')) return true
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
|
|
8
55
|
async function curl () {
|
|
9
56
|
try {
|
|
10
57
|
const commandArgs = this.args
|
|
@@ -13,14 +60,18 @@ async function curl () {
|
|
|
13
60
|
const options = this.opts()
|
|
14
61
|
logger.debug(`options: ${JSON.stringify(options)}`)
|
|
15
62
|
|
|
16
|
-
const httpMethod = '
|
|
63
|
+
const httpMethod = requestMethodFromArgs(commandArgs) || 'POST'
|
|
17
64
|
const url = findUrl(commandArgs)
|
|
18
65
|
const headers = await agent.headers(httpMethod, url)
|
|
66
|
+
const includeRequestMethod = requestMethodFromArgs(commandArgs) === null
|
|
67
|
+
const includeContentType = !hasContentTypeHeader(commandArgs)
|
|
19
68
|
const injected = [
|
|
20
69
|
'curl',
|
|
21
70
|
'-H', `Signature: ${headers.Signature}`,
|
|
22
71
|
'-H', `Signature-Input: ${headers['Signature-Input']}`,
|
|
23
72
|
'-H', `Signature-Agent: ${headers['Signature-Agent']}`,
|
|
73
|
+
...(includeRequestMethod ? ['-X', 'POST'] : []),
|
|
74
|
+
...(includeContentType ? ['-H', 'Content-Type: application/json'] : []),
|
|
24
75
|
...commandArgs
|
|
25
76
|
]
|
|
26
77
|
|
package/src/lib/helpers/touch.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
|
|
3
|
-
const DEFAULT_HEADER_COMMENT = '# [vestauth] auth for agents–from the creator of `dotenv` and `dotenvx`'
|
|
3
|
+
const DEFAULT_HEADER_COMMENT = '# [vestauth] web-bot-auth for agents–from the creator of `dotenv` and `dotenvx`'
|
|
4
4
|
|
|
5
5
|
function touch (filepath, headerComment = null) {
|
|
6
6
|
if (!fs.existsSync(filepath)) {
|