@absolutejs/auth 0.56.12 → 0.56.14

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.
@@ -0,0 +1,18 @@
1
+ import type { RouteString } from '../types';
2
+ export type AgentOAuthGuideResource = {
3
+ metadataUrl: string;
4
+ name: string;
5
+ resource: string;
6
+ scopes: readonly string[];
7
+ };
8
+ export type AgentOAuthGuideConfig = {
9
+ authorizationServer: string;
10
+ resources: readonly AgentOAuthGuideResource[];
11
+ route?: RouteString;
12
+ serviceName: string;
13
+ };
14
+ export declare const agentOAuthGuideRoute: (config: AgentOAuthGuideConfig) => `/${string}`;
15
+ export declare const agentOAuthGuideUrl: (config: AgentOAuthGuideConfig) => string;
16
+ /** Generate an agent-readable OAuth companion from exact application-owned
17
+ * resource metadata. OAuth discovery remains authoritative. */
18
+ export declare const generateAgentOAuthGuide: (config: AgentOAuthGuideConfig) => string;
@@ -1,12 +1,20 @@
1
+ import { type SigningKeyIdentity } from '../oidc/keys';
1
2
  import type { AgentCredentialVerifier } from './types';
3
+ type OidcAgentCredentialVerifierKeys = {
4
+ publicJwk: JsonWebKey;
5
+ publicKeys?: never;
6
+ } | {
7
+ publicJwk?: never;
8
+ publicKeys: readonly SigningKeyIdentity[];
9
+ };
2
10
  /** Adapter for Absolute Auth's RFC 9068-style JWT access tokens. It validates
3
11
  * signature, issuer, audience, expiry, and extracts the OAuth client as the
4
12
  * agent identity while retaining `sub` as the authorizing user. */
5
- export declare const createOidcAgentCredentialVerifier: ({ issuer, isUsedDpopJti, maxDpopAgeMs, publicJwk, requireDpop, resource }: {
13
+ export declare const createOidcAgentCredentialVerifier: ({ issuer, isUsedDpopJti, maxDpopAgeMs, publicJwk, publicKeys, requireDpop, resource }: {
6
14
  issuer: string;
7
15
  isUsedDpopJti?: (jti: string) => boolean | Promise<boolean>;
8
16
  maxDpopAgeMs?: number;
9
- publicJwk: JsonWebKey;
10
17
  requireDpop?: boolean;
11
18
  resource: string;
12
- }) => AgentCredentialVerifier;
19
+ } & OidcAgentCredentialVerifierKeys) => AgentCredentialVerifier;
20
+ export {};
@@ -28,26 +28,7 @@ export declare const agentAuthPlugin: (config?: AgentAuthConfig) => Elysia<"", {
28
28
  message: "Agent is not authenticated" | "Insufficient agent scopes";
29
29
  }) => AuthFailReturn | Promise<AuthFailReturn>) => Promise<Response | AuthReturn | NonNullable<Awaited<AuthFailReturn>>>;
30
30
  }>;
31
- }, {} | {
32
- [x: string]: {
33
- get: {
34
- body: unknown;
35
- params: {};
36
- query: unknown;
37
- headers: unknown;
38
- response: {
39
- 200: {
40
- resource: string;
41
- scopes_supported: string[];
42
- resource_name?: string | undefined;
43
- resource_logo_uri?: string | undefined;
44
- authorization_servers: string[];
45
- bearer_methods_supported: string[];
46
- };
47
- };
48
- };
49
- };
50
- } | ({
31
+ }, {} | ({
51
32
  [x: string]: {
52
33
  get: {
53
34
  body: unknown;
@@ -200,52 +181,6 @@ export declare const agentAuthRoutes: (config?: AgentAuthConfig) => Elysia<"", {
200
181
  };
201
182
  };
202
183
  };
203
- }, {
204
- derive: {};
205
- resolve: {};
206
- schema: {};
207
- standaloneSchema: {};
208
- response: {};
209
- }, {
210
- derive: {};
211
- resolve: {};
212
- schema: {};
213
- standaloneSchema: {};
214
- response: {};
215
- }> | Elysia<"", {
216
- decorator: {};
217
- store: {};
218
- derive: {};
219
- resolve: {};
220
- }, {
221
- typebox: {};
222
- error: {};
223
- }, {
224
- schema: {};
225
- standaloneSchema: {};
226
- macro: {};
227
- macroFn: {};
228
- parser: {};
229
- response: {};
230
- }, {
231
- [x: string]: {
232
- get: {
233
- body: unknown;
234
- params: {};
235
- query: unknown;
236
- headers: unknown;
237
- response: {
238
- 200: {
239
- resource: string;
240
- scopes_supported: string[];
241
- resource_name?: string | undefined;
242
- resource_logo_uri?: string | undefined;
243
- authorization_servers: string[];
244
- bearer_methods_supported: string[];
245
- };
246
- };
247
- };
248
- };
249
184
  } & {
250
185
  [x: string]: {
251
186
  get: {
package/dist/index.d.ts CHANGED
@@ -3317,26 +3317,7 @@ export declare const createAuthApplications: <UserType>(configuration: AuthConfi
3317
3317
  };
3318
3318
  };
3319
3319
  };
3320
- }))) & ({} | {
3321
- [x: string]: {
3322
- get: {
3323
- body: unknown;
3324
- params: {};
3325
- query: unknown;
3326
- headers: unknown;
3327
- response: {
3328
- 200: {
3329
- resource: string;
3330
- scopes_supported: string[];
3331
- resource_name?: string | undefined;
3332
- resource_logo_uri?: string | undefined;
3333
- authorization_servers: string[];
3334
- bearer_methods_supported: string[];
3335
- };
3336
- };
3337
- };
3338
- };
3339
- } | ({
3320
+ }))) & ({} | ({
3340
3321
  [x: string]: {
3341
3322
  get: {
3342
3323
  body: unknown;
@@ -3568,6 +3549,7 @@ export * from './agents/types';
3568
3549
  export * from './agents/registration';
3569
3550
  export * from './agents/registrationClient';
3570
3551
  export * from './agents/idJag';
3552
+ export * from './agents/oauthGuide';
3571
3553
  export { agentAuthPlugin, agentAuthChallenge } from './agents/routes';
3572
3554
  export { resolveAgentPrincipal, agentHasScopes } from './agents/principal';
3573
3555
  export { createOidcAgentCredentialVerifier } from './agents/oidcAdapter';
@@ -3579,8 +3561,8 @@ export * from './oidc/config';
3579
3561
  export * from './oidc/clientIdMetadata';
3580
3562
  export * from './oidc/types';
3581
3563
  export { oidcProviderRoutes } from './oidc/routes';
3582
- export { generateSigningKey, jwkThumbprint, signJwt, toPublicJwk, verifyJwt } from './oidc/keys';
3583
- export type { SigningKey } from './oidc/keys';
3564
+ export { generateSigningKey, jwkThumbprint, signJwt, signingVerificationKeys, toPublicJwk, verifyJwt, verifyJwtWithKeys } from './oidc/keys';
3565
+ export type { SigningKey, SigningKeyIdentity } from './oidc/keys';
3584
3566
  export { extractDpopNonceClaim, mintDpopNonce, verifyDpopNonce, verifyDpopProof } from './oidc/dpop';
3585
3567
  export type { DpopResult } from './oidc/dpop';
3586
3568
  export { CLIENT_ASSERTION_TYPE, verifyClientAssertion, verifyJwtSignedByClient } from './oidc/clientAuth';
package/dist/index.js CHANGED
@@ -3206,6 +3206,95 @@ var agentAuthContextPlugin = (config) => new Elysia2({
3206
3206
  }
3207
3207
  })).as("global");
3208
3208
 
3209
+ // src/agents/oauthGuide.ts
3210
+ var DEFAULT_GUIDE_ROUTE = "/auth.md";
3211
+ var secureUrl = (value, label) => {
3212
+ const url = new URL(value);
3213
+ const loopback = url.protocol === "http:" && (url.hostname === "localhost" || url.hostname === "127.0.0.1");
3214
+ if (url.protocol !== "https:" && !loopback)
3215
+ throw new Error(`${label} must use HTTPS outside loopback development`);
3216
+ if (url.username || url.password || url.hash)
3217
+ throw new Error(`${label} cannot contain credentials or a fragment`);
3218
+ return url.toString();
3219
+ };
3220
+ var agentOAuthGuideRoute = (config) => config.route ?? DEFAULT_GUIDE_ROUTE;
3221
+ var agentOAuthGuideUrl = (config) => new URL(agentOAuthGuideRoute(config), secureUrl(config.authorizationServer, "OAuth authorization server")).toString();
3222
+ var normalizedResources = (config) => {
3223
+ if (config.resources.length === 0)
3224
+ throw new Error("Agent OAuth guide requires at least one resource");
3225
+ const resources = config.resources.map((resource) => ({
3226
+ metadataUrl: secureUrl(resource.metadataUrl, "Protected-resource metadata URL"),
3227
+ name: resource.name.trim(),
3228
+ resource: secureUrl(resource.resource, "OAuth protected resource"),
3229
+ scopes: [
3230
+ ...new Set(resource.scopes.map((scope) => scope.trim()))
3231
+ ].filter(Boolean)
3232
+ }));
3233
+ if (resources.some(({ name, scopes }) => !name || scopes.length === 0))
3234
+ throw new Error("Every agent OAuth guide resource requires a name and at least one scope");
3235
+ if (new Set(resources.map(({ resource }) => resource)).size !== resources.length)
3236
+ throw new Error("Agent OAuth guide resources must be unique");
3237
+ return resources;
3238
+ };
3239
+ var resourceSections = (resources) => resources.map((resource) => `### ${resource.name}
3240
+
3241
+ - Protected resource: \`${resource.resource}\`
3242
+ - Metadata: ${resource.metadataUrl}
3243
+ - Allowed scopes: ${resource.scopes.map((scope) => `\`${scope}\``).join(", ")}
3244
+ `).join(`
3245
+ `);
3246
+ var generateAgentOAuthGuide = (config) => {
3247
+ if (!config.serviceName.trim())
3248
+ throw new Error("Agent OAuth guide requires a service name");
3249
+ const authorizationServer = secureUrl(config.authorizationServer, "OAuth authorization server");
3250
+ const resources = normalizedResources(config);
3251
+ const authorizationMetadata = new URL("/.well-known/oauth-authorization-server", authorizationServer).toString();
3252
+ return `# OAuth access for ${config.serviceName.trim()}
3253
+
3254
+ This guide is the agent-readable companion to the service's standards-based
3255
+ OAuth metadata. Discovery metadata is authoritative. Do not infer endpoints,
3256
+ scopes, audiences, or capabilities that are not advertised.
3257
+
3258
+ ## 1. Discover
3259
+
3260
+ Fetch the protected-resource metadata for the exact interface you intend to
3261
+ use, then fetch the authorization-server metadata at
3262
+ ${authorizationMetadata}.
3263
+
3264
+ ${resourceSections(resources)}
3265
+ ## 2. Register the OAuth client
3266
+
3267
+ Use an existing registered client or the advertised \`registration_endpoint\`.
3268
+ Request only scopes listed for the selected protected resource. Never register
3269
+ redirect URIs, grant types, or authentication methods the metadata rejects.
3270
+
3271
+ ## 3. Obtain user delegation
3272
+
3273
+ For an interactive user, use authorization code with PKCE. For a device or
3274
+ headless client, use the device authorization grant only when
3275
+ \`device_authorization_endpoint\` is advertised. Send the selected protected
3276
+ resource as the OAuth \`resource\` value and show the exact requested scopes to
3277
+ the user before consent.
3278
+
3279
+ ## 4. Call the selected interface
3280
+
3281
+ Present the access token in the Authorization header. The token must name the
3282
+ selected resource as its audience and contain the required scope. A token for
3283
+ one resource or transport is not authority for another.
3284
+
3285
+ ## Safety
3286
+
3287
+ - Never ask a user to send a password, passkey response, MFA code, device code,
3288
+ authorization code, client secret, refresh token, or access token to the
3289
+ agent or place one in model context.
3290
+ - Stop on issuer, signature, audience, expiry, delegation, or scope failure.
3291
+ - Treat consent denial, revocation, and disabled interfaces as final until the
3292
+ user explicitly starts a new authorization flow.
3293
+ - Discovery is not authorization, and this guide grants no capability by
3294
+ itself.
3295
+ `;
3296
+ };
3297
+
3209
3298
  // src/agents/registration.ts
3210
3299
  init_constants();
3211
3300
  init_crypto();
@@ -3289,6 +3378,26 @@ var verifyJwt = async (token, publicJwk) => {
3289
3378
  payload
3290
3379
  };
3291
3380
  };
3381
+ var signingVerificationKeys = (active, previous = []) => {
3382
+ const keys = [active, ...previous];
3383
+ const keyIds = new Set(keys.map(({ kid }) => kid));
3384
+ if (keyIds.size !== keys.length)
3385
+ throw new Error("OIDC signing key IDs must be unique");
3386
+ return keys;
3387
+ };
3388
+ var verifyJwtWithKeys = async (token, keys) => {
3389
+ const [headerSegment] = token.split(".");
3390
+ if (!headerSegment)
3391
+ return;
3392
+ const header = decodeSegment(headerSegment);
3393
+ const kid = header?.kid;
3394
+ if (typeof kid !== "string" || kid.length === 0)
3395
+ return;
3396
+ const key = keys.find((candidate) => candidate.kid === kid);
3397
+ if (!key)
3398
+ return;
3399
+ return verifyJwt(token, key.publicJwk);
3400
+ };
3292
3401
 
3293
3402
  // src/agents/registration.ts
3294
3403
  var AGENT_CLAIM_GRANT_TYPE = "urn:workos:agent-auth:grant-type:claim";
@@ -3297,7 +3406,7 @@ var AGENT_IDENTITY_ASSERTION_TYPE = "urn:ietf:params:oauth:token-type:id-jag";
3297
3406
  var DEFAULT_IDENTITY_ROUTE = "/agent/identity";
3298
3407
  var DEFAULT_CLAIM_ROUTE = "/agent/identity/claim";
3299
3408
  var DEFAULT_COMPLETE_ROUTE = "/agent/identity/claim/complete";
3300
- var DEFAULT_GUIDE_ROUTE = "/auth.md";
3409
+ var DEFAULT_GUIDE_ROUTE2 = "/auth.md";
3301
3410
  var DEFAULT_CLAIM_TTL_MS = 24 * 60 * MILLISECONDS_IN_A_MINUTE;
3302
3411
  var DEFAULT_ATTEMPT_TTL_MS = 10 * MILLISECONDS_IN_A_MINUTE;
3303
3412
  var DEFAULT_ASSERTION_TTL_MS = 60 * MILLISECONDS_IN_A_MINUTE;
@@ -3332,7 +3441,7 @@ var agentRegistrationEndpoints = (config) => {
3332
3441
  return {
3333
3442
  claimEndpoint: new URL(registration.claimRoute ?? DEFAULT_CLAIM_ROUTE, base).toString(),
3334
3443
  completeEndpoint: new URL(registration.completeRoute ?? DEFAULT_COMPLETE_ROUTE, base).toString(),
3335
- guide: new URL(registration.guideRoute ?? DEFAULT_GUIDE_ROUTE, base).toString(),
3444
+ guide: new URL(registration.guideRoute ?? DEFAULT_GUIDE_ROUTE2, base).toString(),
3336
3445
  identityEndpoint: new URL(registration.identityRoute ?? DEFAULT_IDENTITY_ROUTE, base).toString(),
3337
3446
  tokenEndpoint: new URL(`${oidcRoute}/token`, base).toString()
3338
3447
  };
@@ -3960,7 +4069,18 @@ var agentAuthRoutes = (config) => {
3960
4069
  if (config === undefined)
3961
4070
  return plugin.as("global");
3962
4071
  if (config.agentRegistration === undefined) {
3963
- return plugin.get(config.metadataRoute ?? DEFAULT_AGENT_RESOURCE_METADATA_ROUTE, () => agentProtectedResourceMetadata(config)).as("global");
4072
+ plugin.get(config.metadataRoute ?? DEFAULT_AGENT_RESOURCE_METADATA_ROUTE, () => agentProtectedResourceMetadata(config));
4073
+ const { oauthGuide } = config;
4074
+ if (oauthGuide === undefined)
4075
+ return plugin.as("global");
4076
+ const guide = generateAgentOAuthGuide(oauthGuide);
4077
+ plugin.get(agentOAuthGuideRoute(oauthGuide), () => new Response(guide, {
4078
+ headers: {
4079
+ "cache-control": "public, max-age=300",
4080
+ "content-type": "text/markdown; charset=utf-8"
4081
+ }
4082
+ }));
4083
+ return plugin.as("global");
3964
4084
  }
3965
4085
  const registration = config.agentRegistration;
3966
4086
  const identityRoute = registration.identityRoute ?? "/agent/identity";
@@ -6086,7 +6206,7 @@ var exchangeToken = async ({
6086
6206
  requestedScopes,
6087
6207
  subjectToken
6088
6208
  }) => {
6089
- const verified = await verifyJwt(subjectToken, config.signingKey.publicJwk);
6209
+ const verified = await verifyJwtWithKeys(subjectToken, signingVerificationKeys(config.signingKey, config.previousSigningKeys));
6090
6210
  const payload = verified?.payload;
6091
6211
  if (payload === undefined || typeof payload.sub !== "string" || typeof payload.exp !== "number" || payload.exp <= nowSeconds(now)) {
6092
6212
  return { error: "invalid_grant", ok: false };
@@ -6207,7 +6327,7 @@ var introspectToken = async ({
6207
6327
  token
6208
6328
  }) => {
6209
6329
  if (hint !== "refresh_token") {
6210
- const verified = await verifyJwt(token, config.signingKey.publicJwk);
6330
+ const verified = await verifyJwtWithKeys(token, signingVerificationKeys(config.signingKey, config.previousSigningKeys));
6211
6331
  const payload = verified?.payload;
6212
6332
  if (payload !== undefined && typeof payload.sub === "string" && typeof payload.exp === "number" && payload.exp > nowSeconds(now)) {
6213
6333
  return {
@@ -7123,7 +7243,7 @@ var verifyIdTokenHint = async ({
7123
7243
  config,
7124
7244
  idTokenHint
7125
7245
  }) => {
7126
- const verified = await verifyJwt(idTokenHint, config.signingKey.publicJwk);
7246
+ const verified = await verifyJwtWithKeys(idTokenHint, signingVerificationKeys(config.signingKey, config.previousSigningKeys));
7127
7247
  const payload = verified?.payload;
7128
7248
  if (payload === undefined || typeof payload.sub !== "string" || typeof payload.aud !== "string" || payload.iss !== config.issuer) {
7129
7249
  return;
@@ -7353,7 +7473,7 @@ var fetchUserInfo = async ({
7353
7473
  ok: false
7354
7474
  };
7355
7475
  }
7356
- const verified = await verifyJwt(token, config.signingKey.publicJwk);
7476
+ const verified = await verifyJwtWithKeys(token, signingVerificationKeys(config.signingKey, config.previousSigningKeys));
7357
7477
  if (verified === undefined) {
7358
7478
  return {
7359
7479
  body: { error: "invalid_token" },
@@ -8694,7 +8814,9 @@ var oidcProviderRoutes = (config) => {
8694
8814
  headers: t15.Object({
8695
8815
  authorization: t15.Optional(t15.String())
8696
8816
  })
8697
- }).get(jwksRoute, () => ({ keys: [toPublicJwk(signingKey)] })).get("/.well-known/openid-configuration", () => discovery).get("/.well-known/oauth-authorization-server", () => discovery);
8817
+ }).get(jwksRoute, () => ({
8818
+ keys: signingVerificationKeys(signingKey, config.previousSigningKeys).map(toPublicJwk)
8819
+ })).get("/.well-known/openid-configuration", () => discovery).get("/.well-known/oauth-authorization-server", () => discovery);
8698
8820
  };
8699
8821
 
8700
8822
  // src/organizations/routes.ts
@@ -26741,7 +26863,7 @@ var createPostgresScimTokenStore = (db) => ({
26741
26863
  });
26742
26864
  // src/agents/registrationClient.ts
26743
26865
  var isObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
26744
- var secureUrl = (value, allowLocalhost) => {
26866
+ var secureUrl2 = (value, allowLocalhost) => {
26745
26867
  if (typeof value !== "string")
26746
26868
  return;
26747
26869
  try {
@@ -26831,32 +26953,32 @@ var discoverAgentRegistration = async (resource, options = {}) => {
26831
26953
  const request = options.request ?? fetch;
26832
26954
  const maxBytes = options.maxResponseBytes ?? 256 * 1024;
26833
26955
  const allowLocalhost = options.allowInsecureLocalhost === true;
26834
- const resourceUrl = secureUrl(resource, allowLocalhost);
26956
+ const resourceUrl = secureUrl2(resource, allowLocalhost);
26835
26957
  if (resourceUrl === undefined)
26836
26958
  throw new Error("Resource URL must use HTTPS");
26837
26959
  const resourceMetadataUrl = new URL("/.well-known/oauth-protected-resource", resourceUrl).toString();
26838
26960
  const prm = await requestJson(request, resourceMetadataUrl, {}, maxBytes);
26839
- const advertisedResource = secureUrl(prm.body.resource, allowLocalhost);
26961
+ const advertisedResource = secureUrl2(prm.body.resource, allowLocalhost);
26840
26962
  if (advertisedResource === undefined || advertisedResource !== resourceUrl) {
26841
26963
  throw new Error("Protected resource metadata identity mismatch");
26842
26964
  }
26843
- const authorizationServer = secureUrl(stringArray(prm.body.authorization_servers)[0], allowLocalhost);
26965
+ const authorizationServer = secureUrl2(stringArray(prm.body.authorization_servers)[0], allowLocalhost);
26844
26966
  if (authorizationServer === undefined) {
26845
26967
  throw new Error("No secure authorization server is advertised");
26846
26968
  }
26847
26969
  const asUrl = new URL("/.well-known/oauth-authorization-server", authorizationServer).toString();
26848
26970
  const metadata = await requestJson(request, asUrl, {}, maxBytes);
26849
- if (secureUrl(metadata.body.issuer, allowLocalhost) !== authorizationServer) {
26971
+ if (secureUrl2(metadata.body.issuer, allowLocalhost) !== authorizationServer) {
26850
26972
  throw new Error("Authorization server issuer mismatch");
26851
26973
  }
26852
- const tokenEndpoint = secureUrl(metadata.body.token_endpoint, allowLocalhost);
26974
+ const tokenEndpoint = secureUrl2(metadata.body.token_endpoint, allowLocalhost);
26853
26975
  const agentAuth = metadata.body.agent_auth;
26854
26976
  if (tokenEndpoint === undefined || !isObject2(agentAuth)) {
26855
26977
  throw new Error("Authorization server does not advertise agent registration");
26856
26978
  }
26857
- const identityEndpoint = secureUrl(agentAuth.identity_endpoint, allowLocalhost);
26858
- const claimEndpoint = secureUrl(agentAuth.claim_endpoint, allowLocalhost);
26859
- const skill = secureUrl(agentAuth.skill, allowLocalhost);
26979
+ const identityEndpoint = secureUrl2(agentAuth.identity_endpoint, allowLocalhost);
26980
+ const claimEndpoint = secureUrl2(agentAuth.claim_endpoint, allowLocalhost);
26981
+ const skill = secureUrl2(agentAuth.skill, allowLocalhost);
26860
26982
  const assertionMetadata = agentAuth.identity_assertion;
26861
26983
  if (identityEndpoint === undefined || claimEndpoint === undefined || skill === undefined || !isObject2(assertionMetadata)) {
26862
26984
  throw new Error("Agent registration metadata is incomplete");
@@ -27033,6 +27155,7 @@ var createOidcAgentCredentialVerifier = ({
27033
27155
  isUsedDpopJti,
27034
27156
  maxDpopAgeMs,
27035
27157
  publicJwk,
27158
+ publicKeys,
27036
27159
  requireDpop = false,
27037
27160
  resource
27038
27161
  }) => {
@@ -27044,13 +27167,14 @@ var createOidcAgentCredentialVerifier = ({
27044
27167
  const token = authorization.slice(authorization.indexOf(" ") + 1).trim();
27045
27168
  if (token.length === 0)
27046
27169
  return;
27047
- const verified = await verifyJwt(token, publicJwk);
27170
+ const verified = publicKeys ? await verifyJwtWithKeys(token, publicKeys) : await verifyJwt(token, publicJwk);
27048
27171
  const payload = verified?.payload;
27049
27172
  if (payload === undefined || payload.iss !== issuer || typeof payload.exp !== "number" || payload.exp <= Math.floor(Date.now() / MS_PER_SECOND7) || !readAudience(payload.aud).includes(resource) || typeof payload.client_id !== "string") {
27050
27173
  return;
27051
27174
  }
27052
27175
  const confirmation = payload.cnf;
27053
- const boundJkt = typeof confirmation === "object" && confirmation !== null && typeof confirmation.jkt === "string" ? confirmation.jkt : undefined;
27176
+ const boundJktValue = typeof confirmation === "object" && confirmation !== null ? Reflect.get(confirmation, "jkt") : undefined;
27177
+ const boundJkt = typeof boundJktValue === "string" ? boundJktValue : undefined;
27054
27178
  if (boundJkt !== undefined || requireDpop) {
27055
27179
  if (!authorization.startsWith("DPoP "))
27056
27180
  return;
@@ -27614,7 +27738,7 @@ var createPostgresApiKeyStore = (db) => ({
27614
27738
  }
27615
27739
  });
27616
27740
  // src/oidc/clientIdMetadata.ts
27617
- var secureUrl2 = (value) => {
27741
+ var secureUrl3 = (value) => {
27618
27742
  try {
27619
27743
  return new URL(value).protocol === "https:";
27620
27744
  } catch {
@@ -27625,7 +27749,7 @@ var validateClientIdMetadataDocument = (document, expectedClientId) => {
27625
27749
  const errors = [];
27626
27750
  if (document.client_id !== expectedClientId)
27627
27751
  errors.push("client_id does not match the metadata document URL");
27628
- if (!secureUrl2(document.client_id))
27752
+ if (!secureUrl3(document.client_id))
27629
27753
  errors.push("client_id must use HTTPS");
27630
27754
  if (!Array.isArray(document.redirect_uris) || document.redirect_uris.length === 0)
27631
27755
  errors.push("redirect_uris is required");
@@ -27645,7 +27769,7 @@ var validateClientIdMetadataDocument = (document, expectedClientId) => {
27645
27769
  ["tos_uri", document.tos_uri],
27646
27770
  ["jwks_uri", document.jwks_uri]
27647
27771
  ]) {
27648
- if (value !== undefined && !secureUrl2(value))
27772
+ if (value !== undefined && !secureUrl3(value))
27649
27773
  errors.push(`${name2} must use HTTPS`);
27650
27774
  }
27651
27775
  return errors;
@@ -27668,7 +27792,7 @@ var createClientIdMetadataResolver = ({
27668
27792
  }) => {
27669
27793
  const cache = new Map;
27670
27794
  return async (clientId) => {
27671
- if (!secureUrl2(clientId) || !await allow(clientId))
27795
+ if (!secureUrl3(clientId) || !await allow(clientId))
27672
27796
  return;
27673
27797
  const cached = cache.get(clientId);
27674
27798
  if (cached !== undefined && cached.expiresAt > now())
@@ -30347,6 +30471,22 @@ var buildAuthApplications = async (configuration) => {
30347
30471
  tokenTtlMs: registration2.tokenTtlMs
30348
30472
  });
30349
30473
  }
30474
+ if (agentAuth?.oauthGuide !== undefined) {
30475
+ if (oidc === undefined)
30476
+ throw new Error("agentAuth.oauthGuide requires the OIDC provider");
30477
+ if (agentAuth.authorizationServer !== oidc.issuer)
30478
+ throw new Error("agentAuth.authorizationServer must equal oidc.issuer");
30479
+ if (agentAuth.oauthGuide.authorizationServer !== agentAuth.authorizationServer)
30480
+ throw new Error("agentAuth.oauthGuide.authorizationServer must equal agentAuth.authorizationServer");
30481
+ const unknownGuideScopes = agentAuth.oauthGuide.resources.flatMap(({ scopes }) => scopes).filter((scope) => !agentAuth.scopes.includes(scope));
30482
+ if (unknownGuideScopes.length > 0)
30483
+ throw new Error(`Agent OAuth guide uses undeclared scopes: ${[
30484
+ ...new Set(unknownGuideScopes)
30485
+ ].join(", ")}`);
30486
+ if (agentAuth.agentRegistration !== undefined && (agentAuth.agentRegistration.guideRoute ?? "/auth.md") === (agentAuth.oauthGuide.route ?? "/auth.md"))
30487
+ throw new Error("Agent OAuth and registration guides cannot use the same route");
30488
+ generateAgentOAuthGuide(agentAuth.oauthGuide);
30489
+ }
30350
30490
  if (tracing !== undefined)
30351
30491
  await initTracing(tracing);
30352
30492
  const clientProviders = await buildClientProviders(providersConfiguration, createOAuth2Client, customProviders);
@@ -30368,6 +30508,9 @@ var buildAuthApplications = async (configuration) => {
30368
30508
  ...oidc,
30369
30509
  additionalDiscoveryMetadata: {
30370
30510
  ...oidc.additionalDiscoveryMetadata,
30511
+ ...resolvedAgentAuth?.oauthGuide === undefined ? {} : {
30512
+ service_documentation: agentOAuthGuideUrl(resolvedAgentAuth.oauthGuide)
30513
+ },
30371
30514
  ...resolvedAgentAuth?.agentRegistration === undefined ? {} : {
30372
30515
  agent_auth: agentRegistrationDiscoveryMetadata(resolvedAgentAuth)
30373
30516
  }
@@ -30590,6 +30733,7 @@ export {
30590
30733
  verifyPresentationResponse,
30591
30734
  verifyPkce,
30592
30735
  verifyPassword,
30736
+ verifyJwtWithKeys,
30593
30737
  verifyJwtSignedByClient,
30594
30738
  verifyJwt,
30595
30739
  verifyIdTokenHint,
@@ -30624,6 +30768,7 @@ export {
30624
30768
  startAgentRegistration,
30625
30769
  ssoDiscoveryRoute,
30626
30770
  ssoConnectionsTable,
30771
+ signingVerificationKeys,
30627
30772
  signWebhook,
30628
30773
  signStatusList,
30629
30774
  signJwt,
@@ -30771,6 +30916,7 @@ export {
30771
30916
  generateEncryptionKey,
30772
30917
  generateBackupCodes,
30773
30918
  generateAgentRegistrationGuide,
30919
+ generateAgentOAuthGuide,
30774
30920
  fromBase64Url2 as fromBase64Url,
30775
30921
  fingerprintDevice,
30776
30922
  fetchUserInfo,
@@ -31000,6 +31146,8 @@ export {
31000
31146
  agentRegistrationEndpoints,
31001
31147
  agentRegistrationDiscoveryMetadata,
31002
31148
  agentProtectedResourceMetadata,
31149
+ agentOAuthGuideUrl,
31150
+ agentOAuthGuideRoute,
31003
31151
  agentIdentityRegistrationsTable,
31004
31152
  agentHasScopes,
31005
31153
  agentDelegationsTable,
@@ -31057,5 +31205,5 @@ export {
31057
31205
  AGENT_CLAIM_GRANT_TYPE
31058
31206
  };
31059
31207
 
31060
- //# debugId=CEE9F9BEA5B2A4F264756E2164756E21
31208
+ //# debugId=58447B50393B8A7664756E2164756E21
31061
31209
  //# sourceMappingURL=index.js.map