auth-agents 0.4.0 → 0.4.2
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 +22 -6
- package/dist/index.d.mts +12 -6
- package/dist/index.d.ts +12 -6
- package/dist/index.js +57 -12
- package/dist/index.mjs +57 -12
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# auth-agents
|
|
2
2
|
|
|
3
|
-
Verify AI agent identities with [Agent Auth](https://
|
|
3
|
+
Verify AI agent identities with [Agent Auth](https://usevigil.dev). DID-based authentication using Ed25519 and Verifiable Credentials.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -126,7 +126,7 @@ if (auth.valid) {
|
|
|
126
126
|
## Website Integration (Next.js)
|
|
127
127
|
|
|
128
128
|
```typescript
|
|
129
|
-
// app/api/auth/agent/route.ts
|
|
129
|
+
// app/api/auth/agent-login/route.ts
|
|
130
130
|
import { AuthAgents } from "auth-agents"
|
|
131
131
|
|
|
132
132
|
const authAgents = new AuthAgents()
|
|
@@ -164,7 +164,7 @@ import { AuthAgents } from "auth-agents"
|
|
|
164
164
|
const app = express()
|
|
165
165
|
const authAgents = new AuthAgents()
|
|
166
166
|
|
|
167
|
-
app.post("/auth/agent", express.json(), async (req, res) => {
|
|
167
|
+
app.post("/auth/agent-login", express.json(), async (req, res) => {
|
|
168
168
|
const { credential } = req.body
|
|
169
169
|
const result = await authAgents.verify(credential)
|
|
170
170
|
|
|
@@ -188,7 +188,7 @@ app.post("/auth/agent", express.json(), async (req, res) => {
|
|
|
188
188
|
|
|
189
189
|
### `new AuthAgents(config?)`
|
|
190
190
|
|
|
191
|
-
- `config.baseUrl` — API base URL (default: `https://auth.
|
|
191
|
+
- `config.baseUrl` — API base URL (default: `https://auth.usevigil.dev`). The SDK enforces HTTPS for all API communication. HTTP is only allowed for `localhost` during development.
|
|
192
192
|
|
|
193
193
|
### `AuthAgents.generateKeyPair()` — Static
|
|
194
194
|
|
|
@@ -229,9 +229,21 @@ Returns `VerifyResult` on success:
|
|
|
229
229
|
}
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
+
Returns `VerifyError` (HTTP 401) without throwing:
|
|
233
|
+
```typescript
|
|
234
|
+
{
|
|
235
|
+
valid: false
|
|
236
|
+
error: "credential_expired" | "invalid_issuer" | "signature_invalid" | "credential_revoked"
|
|
237
|
+
message: string
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
232
241
|
### `client.register(input)` — Register a new agent identity
|
|
233
242
|
|
|
234
243
|
`input.public_key_jwk` is optional. Omit it for server-generated keys (Flow A). Provide it for BYOK (Flow B).
|
|
244
|
+
You can also pass:
|
|
245
|
+
- `credential_expires_in` — credential lifetime in seconds (`0` means non-expiring)
|
|
246
|
+
- `metadata` — key/value metadata map (max key/value sizes enforced server-side)
|
|
235
247
|
|
|
236
248
|
Returns `RegisterResult`:
|
|
237
249
|
```typescript
|
|
@@ -244,13 +256,17 @@ Returns `RegisterResult`:
|
|
|
244
256
|
}
|
|
245
257
|
```
|
|
246
258
|
|
|
247
|
-
### `client.challenge(did)` — Request an auth challenge
|
|
259
|
+
### `client.challenge(did, site_id?)` — Request an auth challenge
|
|
260
|
+
|
|
261
|
+
`site_id` is optional and scopes the challenge/session when your deployment uses site-level org provisioning.
|
|
248
262
|
|
|
249
263
|
### `client.authenticate(input)` — Submit signed challenge
|
|
250
264
|
|
|
265
|
+
`input` supports optional `credential_expires_in` to customize the issued credential lifetime (`0` means non-expiring).
|
|
266
|
+
|
|
251
267
|
## Documentation
|
|
252
268
|
|
|
253
|
-
Full API reference at [
|
|
269
|
+
Full API reference at [usevigil.dev/docs](https://usevigil.dev/docs/)
|
|
254
270
|
|
|
255
271
|
## License
|
|
256
272
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
interface AuthAgentsConfig {
|
|
2
|
-
/** Base URL of the Agent Auth API. Defaults to https://auth.
|
|
2
|
+
/** Base URL of the Agent Auth API. Defaults to https://auth.usevigil.dev */
|
|
3
3
|
baseUrl?: string;
|
|
4
4
|
}
|
|
5
5
|
/** Ed25519 key pair in JWK format, returned by generateKeyPair() */
|
|
@@ -30,7 +30,7 @@ interface VerifyResult {
|
|
|
30
30
|
}
|
|
31
31
|
interface VerifyError {
|
|
32
32
|
valid: false;
|
|
33
|
-
error: "credential_expired" | "invalid_issuer" | "signature_invalid";
|
|
33
|
+
error: "credential_expired" | "invalid_issuer" | "signature_invalid" | "credential_revoked";
|
|
34
34
|
message: string;
|
|
35
35
|
}
|
|
36
36
|
type VerifyResponse = VerifyResult | VerifyError;
|
|
@@ -44,6 +44,8 @@ interface RegisterInput {
|
|
|
44
44
|
crv: string;
|
|
45
45
|
x: string;
|
|
46
46
|
};
|
|
47
|
+
credential_expires_in?: number;
|
|
48
|
+
metadata?: Record<string, string>;
|
|
47
49
|
}
|
|
48
50
|
interface RegisterResult {
|
|
49
51
|
did: string;
|
|
@@ -67,6 +69,7 @@ interface AuthVerifyInput {
|
|
|
67
69
|
challenge_id: string;
|
|
68
70
|
did: string;
|
|
69
71
|
signature: string;
|
|
72
|
+
credential_expires_in?: number;
|
|
70
73
|
}
|
|
71
74
|
interface AuthVerifyResult {
|
|
72
75
|
valid: true;
|
|
@@ -120,7 +123,8 @@ declare class AuthAgents {
|
|
|
120
123
|
* Verify a VC-JWT credential issued by Agent Auth.
|
|
121
124
|
*
|
|
122
125
|
* @param credential - The VC-JWT string from the agent
|
|
123
|
-
* @returns Verified agent identity
|
|
126
|
+
* @returns Verified agent identity. If API returns 401, returns
|
|
127
|
+
* `{ valid: false, error, message }` instead of throwing.
|
|
124
128
|
*/
|
|
125
129
|
verify(credential: string): Promise<VerifyResponse>;
|
|
126
130
|
/**
|
|
@@ -136,14 +140,16 @@ declare class AuthAgents {
|
|
|
136
140
|
* Request an authentication challenge nonce.
|
|
137
141
|
*
|
|
138
142
|
* @param did - The agent's DID
|
|
143
|
+
* @param site_id - Optional site scope for provisioned deployments
|
|
139
144
|
* @returns Challenge ID and nonce to sign
|
|
140
145
|
*/
|
|
141
|
-
challenge(did: string): Promise<ChallengeResult>;
|
|
146
|
+
challenge(did: string, site_id?: string): Promise<ChallengeResult>;
|
|
142
147
|
/**
|
|
143
148
|
* Submit a signed challenge to authenticate and receive a fresh credential.
|
|
144
149
|
*
|
|
145
|
-
* @param input - challenge_id, did, and
|
|
146
|
-
* @returns Session token and fresh VC-JWT credential
|
|
150
|
+
* @param input - challenge_id, did, base64url signature, and optional credential_expires_in
|
|
151
|
+
* @returns Session token and fresh VC-JWT credential. If API returns 401,
|
|
152
|
+
* returns `{ valid: false, error, message }` instead of throwing.
|
|
147
153
|
*/
|
|
148
154
|
authenticate(input: AuthVerifyInput): Promise<AuthVerifyResponse>;
|
|
149
155
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
interface AuthAgentsConfig {
|
|
2
|
-
/** Base URL of the Agent Auth API. Defaults to https://auth.
|
|
2
|
+
/** Base URL of the Agent Auth API. Defaults to https://auth.usevigil.dev */
|
|
3
3
|
baseUrl?: string;
|
|
4
4
|
}
|
|
5
5
|
/** Ed25519 key pair in JWK format, returned by generateKeyPair() */
|
|
@@ -30,7 +30,7 @@ interface VerifyResult {
|
|
|
30
30
|
}
|
|
31
31
|
interface VerifyError {
|
|
32
32
|
valid: false;
|
|
33
|
-
error: "credential_expired" | "invalid_issuer" | "signature_invalid";
|
|
33
|
+
error: "credential_expired" | "invalid_issuer" | "signature_invalid" | "credential_revoked";
|
|
34
34
|
message: string;
|
|
35
35
|
}
|
|
36
36
|
type VerifyResponse = VerifyResult | VerifyError;
|
|
@@ -44,6 +44,8 @@ interface RegisterInput {
|
|
|
44
44
|
crv: string;
|
|
45
45
|
x: string;
|
|
46
46
|
};
|
|
47
|
+
credential_expires_in?: number;
|
|
48
|
+
metadata?: Record<string, string>;
|
|
47
49
|
}
|
|
48
50
|
interface RegisterResult {
|
|
49
51
|
did: string;
|
|
@@ -67,6 +69,7 @@ interface AuthVerifyInput {
|
|
|
67
69
|
challenge_id: string;
|
|
68
70
|
did: string;
|
|
69
71
|
signature: string;
|
|
72
|
+
credential_expires_in?: number;
|
|
70
73
|
}
|
|
71
74
|
interface AuthVerifyResult {
|
|
72
75
|
valid: true;
|
|
@@ -120,7 +123,8 @@ declare class AuthAgents {
|
|
|
120
123
|
* Verify a VC-JWT credential issued by Agent Auth.
|
|
121
124
|
*
|
|
122
125
|
* @param credential - The VC-JWT string from the agent
|
|
123
|
-
* @returns Verified agent identity
|
|
126
|
+
* @returns Verified agent identity. If API returns 401, returns
|
|
127
|
+
* `{ valid: false, error, message }` instead of throwing.
|
|
124
128
|
*/
|
|
125
129
|
verify(credential: string): Promise<VerifyResponse>;
|
|
126
130
|
/**
|
|
@@ -136,14 +140,16 @@ declare class AuthAgents {
|
|
|
136
140
|
* Request an authentication challenge nonce.
|
|
137
141
|
*
|
|
138
142
|
* @param did - The agent's DID
|
|
143
|
+
* @param site_id - Optional site scope for provisioned deployments
|
|
139
144
|
* @returns Challenge ID and nonce to sign
|
|
140
145
|
*/
|
|
141
|
-
challenge(did: string): Promise<ChallengeResult>;
|
|
146
|
+
challenge(did: string, site_id?: string): Promise<ChallengeResult>;
|
|
142
147
|
/**
|
|
143
148
|
* Submit a signed challenge to authenticate and receive a fresh credential.
|
|
144
149
|
*
|
|
145
|
-
* @param input - challenge_id, did, and
|
|
146
|
-
* @returns Session token and fresh VC-JWT credential
|
|
150
|
+
* @param input - challenge_id, did, base64url signature, and optional credential_expires_in
|
|
151
|
+
* @returns Session token and fresh VC-JWT credential. If API returns 401,
|
|
152
|
+
* returns `{ valid: false, error, message }` instead of throwing.
|
|
147
153
|
*/
|
|
148
154
|
authenticate(input: AuthVerifyInput): Promise<AuthVerifyResponse>;
|
|
149
155
|
}
|
package/dist/index.js
CHANGED
|
@@ -24,10 +24,20 @@ __export(index_exports, {
|
|
|
24
24
|
verify: () => verify
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(index_exports);
|
|
27
|
-
var DEFAULT_BASE_URL = "https://auth.
|
|
27
|
+
var DEFAULT_BASE_URL = "https://auth.usevigil.dev";
|
|
28
28
|
var AuthAgents = class {
|
|
29
29
|
constructor(config) {
|
|
30
|
-
|
|
30
|
+
const url = (config?.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
31
|
+
try {
|
|
32
|
+
const parsed = new URL(url);
|
|
33
|
+
if (parsed.protocol !== "https:" && parsed.hostname !== "localhost" && parsed.hostname !== "127.0.0.1") {
|
|
34
|
+
throw new Error("AuthAgents: baseUrl must use HTTPS (http://localhost allowed for development)");
|
|
35
|
+
}
|
|
36
|
+
} catch (e) {
|
|
37
|
+
if (e instanceof Error && e.message.startsWith("AuthAgents:")) throw e;
|
|
38
|
+
throw new Error("AuthAgents: baseUrl must be a valid URL");
|
|
39
|
+
}
|
|
40
|
+
this.baseUrl = url;
|
|
31
41
|
}
|
|
32
42
|
// ---- Static Crypto Helpers ---------------------------------------------
|
|
33
43
|
/**
|
|
@@ -72,6 +82,12 @@ var AuthAgents = class {
|
|
|
72
82
|
* @returns base64url-encoded Ed25519 signature
|
|
73
83
|
*/
|
|
74
84
|
static async signChallenge(privateKeyJwk, nonce) {
|
|
85
|
+
if (!privateKeyJwk?.d) {
|
|
86
|
+
throw new Error("privateKeyJwk must contain the 'd' (private key) parameter");
|
|
87
|
+
}
|
|
88
|
+
if (!nonce) {
|
|
89
|
+
throw new Error("nonce must not be empty");
|
|
90
|
+
}
|
|
75
91
|
const key = await crypto.subtle.importKey(
|
|
76
92
|
"jwk",
|
|
77
93
|
{ ...privateKeyJwk, key_ops: ["sign"] },
|
|
@@ -94,15 +110,28 @@ var AuthAgents = class {
|
|
|
94
110
|
* Verify a VC-JWT credential issued by Agent Auth.
|
|
95
111
|
*
|
|
96
112
|
* @param credential - The VC-JWT string from the agent
|
|
97
|
-
* @returns Verified agent identity
|
|
113
|
+
* @returns Verified agent identity. If API returns 401, returns
|
|
114
|
+
* `{ valid: false, error, message }` instead of throwing.
|
|
98
115
|
*/
|
|
99
116
|
async verify(credential) {
|
|
100
117
|
const res = await fetch(`${this.baseUrl}/v1/credentials/verify`, {
|
|
101
118
|
method: "POST",
|
|
102
119
|
headers: { "Content-Type": "application/json" },
|
|
103
|
-
body: JSON.stringify({ credential })
|
|
120
|
+
body: JSON.stringify({ credential }),
|
|
121
|
+
signal: AbortSignal.timeout(1e4)
|
|
104
122
|
});
|
|
105
|
-
|
|
123
|
+
const body = await res.json().catch(() => ({}));
|
|
124
|
+
if (res.status === 401) {
|
|
125
|
+
return {
|
|
126
|
+
valid: false,
|
|
127
|
+
error: body.error ?? "signature_invalid",
|
|
128
|
+
message: body.message ?? "Credential verification failed"
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (!res.ok) {
|
|
132
|
+
throw new Error(body.error ?? body.message ?? `Verify failed (${res.status})`);
|
|
133
|
+
}
|
|
134
|
+
return body;
|
|
106
135
|
}
|
|
107
136
|
// ---- Agent Registration ------------------------------------------------
|
|
108
137
|
/**
|
|
@@ -117,7 +146,8 @@ var AuthAgents = class {
|
|
|
117
146
|
const res = await fetch(`${this.baseUrl}/v1/identities`, {
|
|
118
147
|
method: "POST",
|
|
119
148
|
headers: { "Content-Type": "application/json" },
|
|
120
|
-
body: JSON.stringify(input)
|
|
149
|
+
body: JSON.stringify(input),
|
|
150
|
+
signal: AbortSignal.timeout(1e4)
|
|
121
151
|
});
|
|
122
152
|
if (!res.ok) {
|
|
123
153
|
const body = await res.json().catch(() => ({}));
|
|
@@ -132,13 +162,15 @@ var AuthAgents = class {
|
|
|
132
162
|
* Request an authentication challenge nonce.
|
|
133
163
|
*
|
|
134
164
|
* @param did - The agent's DID
|
|
165
|
+
* @param site_id - Optional site scope for provisioned deployments
|
|
135
166
|
* @returns Challenge ID and nonce to sign
|
|
136
167
|
*/
|
|
137
|
-
async challenge(did) {
|
|
168
|
+
async challenge(did, site_id) {
|
|
138
169
|
const res = await fetch(`${this.baseUrl}/v1/auth/challenge`, {
|
|
139
170
|
method: "POST",
|
|
140
171
|
headers: { "Content-Type": "application/json" },
|
|
141
|
-
body: JSON.stringify({ did })
|
|
172
|
+
body: JSON.stringify(site_id ? { did, site_id } : { did }),
|
|
173
|
+
signal: AbortSignal.timeout(1e4)
|
|
142
174
|
});
|
|
143
175
|
if (!res.ok) {
|
|
144
176
|
const body = await res.json().catch(() => ({}));
|
|
@@ -151,16 +183,29 @@ var AuthAgents = class {
|
|
|
151
183
|
/**
|
|
152
184
|
* Submit a signed challenge to authenticate and receive a fresh credential.
|
|
153
185
|
*
|
|
154
|
-
* @param input - challenge_id, did, and
|
|
155
|
-
* @returns Session token and fresh VC-JWT credential
|
|
186
|
+
* @param input - challenge_id, did, base64url signature, and optional credential_expires_in
|
|
187
|
+
* @returns Session token and fresh VC-JWT credential. If API returns 401,
|
|
188
|
+
* returns `{ valid: false, error, message }` instead of throwing.
|
|
156
189
|
*/
|
|
157
190
|
async authenticate(input) {
|
|
158
191
|
const res = await fetch(`${this.baseUrl}/v1/auth/verify`, {
|
|
159
192
|
method: "POST",
|
|
160
193
|
headers: { "Content-Type": "application/json" },
|
|
161
|
-
body: JSON.stringify(input)
|
|
194
|
+
body: JSON.stringify(input),
|
|
195
|
+
signal: AbortSignal.timeout(1e4)
|
|
162
196
|
});
|
|
163
|
-
|
|
197
|
+
const body = await res.json().catch(() => ({}));
|
|
198
|
+
if (res.status === 401) {
|
|
199
|
+
return {
|
|
200
|
+
valid: false,
|
|
201
|
+
error: body.error ?? "signature_invalid",
|
|
202
|
+
message: body.message ?? "Authentication failed"
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
if (!res.ok) {
|
|
206
|
+
throw new Error(body.error ?? body.message ?? `Authentication failed (${res.status})`);
|
|
207
|
+
}
|
|
208
|
+
return body;
|
|
164
209
|
}
|
|
165
210
|
};
|
|
166
211
|
async function verify(credential) {
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
var DEFAULT_BASE_URL = "https://auth.
|
|
2
|
+
var DEFAULT_BASE_URL = "https://auth.usevigil.dev";
|
|
3
3
|
var AuthAgents = class {
|
|
4
4
|
constructor(config) {
|
|
5
|
-
|
|
5
|
+
const url = (config?.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
6
|
+
try {
|
|
7
|
+
const parsed = new URL(url);
|
|
8
|
+
if (parsed.protocol !== "https:" && parsed.hostname !== "localhost" && parsed.hostname !== "127.0.0.1") {
|
|
9
|
+
throw new Error("AuthAgents: baseUrl must use HTTPS (http://localhost allowed for development)");
|
|
10
|
+
}
|
|
11
|
+
} catch (e) {
|
|
12
|
+
if (e instanceof Error && e.message.startsWith("AuthAgents:")) throw e;
|
|
13
|
+
throw new Error("AuthAgents: baseUrl must be a valid URL");
|
|
14
|
+
}
|
|
15
|
+
this.baseUrl = url;
|
|
6
16
|
}
|
|
7
17
|
// ---- Static Crypto Helpers ---------------------------------------------
|
|
8
18
|
/**
|
|
@@ -47,6 +57,12 @@ var AuthAgents = class {
|
|
|
47
57
|
* @returns base64url-encoded Ed25519 signature
|
|
48
58
|
*/
|
|
49
59
|
static async signChallenge(privateKeyJwk, nonce) {
|
|
60
|
+
if (!privateKeyJwk?.d) {
|
|
61
|
+
throw new Error("privateKeyJwk must contain the 'd' (private key) parameter");
|
|
62
|
+
}
|
|
63
|
+
if (!nonce) {
|
|
64
|
+
throw new Error("nonce must not be empty");
|
|
65
|
+
}
|
|
50
66
|
const key = await crypto.subtle.importKey(
|
|
51
67
|
"jwk",
|
|
52
68
|
{ ...privateKeyJwk, key_ops: ["sign"] },
|
|
@@ -69,15 +85,28 @@ var AuthAgents = class {
|
|
|
69
85
|
* Verify a VC-JWT credential issued by Agent Auth.
|
|
70
86
|
*
|
|
71
87
|
* @param credential - The VC-JWT string from the agent
|
|
72
|
-
* @returns Verified agent identity
|
|
88
|
+
* @returns Verified agent identity. If API returns 401, returns
|
|
89
|
+
* `{ valid: false, error, message }` instead of throwing.
|
|
73
90
|
*/
|
|
74
91
|
async verify(credential) {
|
|
75
92
|
const res = await fetch(`${this.baseUrl}/v1/credentials/verify`, {
|
|
76
93
|
method: "POST",
|
|
77
94
|
headers: { "Content-Type": "application/json" },
|
|
78
|
-
body: JSON.stringify({ credential })
|
|
95
|
+
body: JSON.stringify({ credential }),
|
|
96
|
+
signal: AbortSignal.timeout(1e4)
|
|
79
97
|
});
|
|
80
|
-
|
|
98
|
+
const body = await res.json().catch(() => ({}));
|
|
99
|
+
if (res.status === 401) {
|
|
100
|
+
return {
|
|
101
|
+
valid: false,
|
|
102
|
+
error: body.error ?? "signature_invalid",
|
|
103
|
+
message: body.message ?? "Credential verification failed"
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (!res.ok) {
|
|
107
|
+
throw new Error(body.error ?? body.message ?? `Verify failed (${res.status})`);
|
|
108
|
+
}
|
|
109
|
+
return body;
|
|
81
110
|
}
|
|
82
111
|
// ---- Agent Registration ------------------------------------------------
|
|
83
112
|
/**
|
|
@@ -92,7 +121,8 @@ var AuthAgents = class {
|
|
|
92
121
|
const res = await fetch(`${this.baseUrl}/v1/identities`, {
|
|
93
122
|
method: "POST",
|
|
94
123
|
headers: { "Content-Type": "application/json" },
|
|
95
|
-
body: JSON.stringify(input)
|
|
124
|
+
body: JSON.stringify(input),
|
|
125
|
+
signal: AbortSignal.timeout(1e4)
|
|
96
126
|
});
|
|
97
127
|
if (!res.ok) {
|
|
98
128
|
const body = await res.json().catch(() => ({}));
|
|
@@ -107,13 +137,15 @@ var AuthAgents = class {
|
|
|
107
137
|
* Request an authentication challenge nonce.
|
|
108
138
|
*
|
|
109
139
|
* @param did - The agent's DID
|
|
140
|
+
* @param site_id - Optional site scope for provisioned deployments
|
|
110
141
|
* @returns Challenge ID and nonce to sign
|
|
111
142
|
*/
|
|
112
|
-
async challenge(did) {
|
|
143
|
+
async challenge(did, site_id) {
|
|
113
144
|
const res = await fetch(`${this.baseUrl}/v1/auth/challenge`, {
|
|
114
145
|
method: "POST",
|
|
115
146
|
headers: { "Content-Type": "application/json" },
|
|
116
|
-
body: JSON.stringify({ did })
|
|
147
|
+
body: JSON.stringify(site_id ? { did, site_id } : { did }),
|
|
148
|
+
signal: AbortSignal.timeout(1e4)
|
|
117
149
|
});
|
|
118
150
|
if (!res.ok) {
|
|
119
151
|
const body = await res.json().catch(() => ({}));
|
|
@@ -126,16 +158,29 @@ var AuthAgents = class {
|
|
|
126
158
|
/**
|
|
127
159
|
* Submit a signed challenge to authenticate and receive a fresh credential.
|
|
128
160
|
*
|
|
129
|
-
* @param input - challenge_id, did, and
|
|
130
|
-
* @returns Session token and fresh VC-JWT credential
|
|
161
|
+
* @param input - challenge_id, did, base64url signature, and optional credential_expires_in
|
|
162
|
+
* @returns Session token and fresh VC-JWT credential. If API returns 401,
|
|
163
|
+
* returns `{ valid: false, error, message }` instead of throwing.
|
|
131
164
|
*/
|
|
132
165
|
async authenticate(input) {
|
|
133
166
|
const res = await fetch(`${this.baseUrl}/v1/auth/verify`, {
|
|
134
167
|
method: "POST",
|
|
135
168
|
headers: { "Content-Type": "application/json" },
|
|
136
|
-
body: JSON.stringify(input)
|
|
169
|
+
body: JSON.stringify(input),
|
|
170
|
+
signal: AbortSignal.timeout(1e4)
|
|
137
171
|
});
|
|
138
|
-
|
|
172
|
+
const body = await res.json().catch(() => ({}));
|
|
173
|
+
if (res.status === 401) {
|
|
174
|
+
return {
|
|
175
|
+
valid: false,
|
|
176
|
+
error: body.error ?? "signature_invalid",
|
|
177
|
+
message: body.message ?? "Authentication failed"
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
if (!res.ok) {
|
|
181
|
+
throw new Error(body.error ?? body.message ?? `Authentication failed (${res.status})`);
|
|
182
|
+
}
|
|
183
|
+
return body;
|
|
139
184
|
}
|
|
140
185
|
};
|
|
141
186
|
async function verify(credential) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "auth-agents",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Verify AI agent identities with Agent Auth. DID-based authentication using Ed25519 and Verifiable Credentials.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"keywords": [
|
|
24
24
|
"agent-auth",
|
|
25
|
-
"
|
|
25
|
+
"usevigil",
|
|
26
26
|
"auth-agents",
|
|
27
27
|
"ai-agent",
|
|
28
28
|
"did",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"type": "git",
|
|
39
39
|
"url": "https://github.com/AgenthAgent/auth-agents-sdk-node"
|
|
40
40
|
},
|
|
41
|
-
"homepage": "https://
|
|
41
|
+
"homepage": "https://usevigil.dev",
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"tsup": "^8.0.0",
|
|
44
44
|
"typescript": "^5.0.0"
|