@auth0/ai 5.0.1 → 5.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/authorizers/token-vault/TokenVaultAuthorizerBase.js +20 -4
- package/dist/cjs/authorizers/token-vault/TokenVaultAuthorizerBase.js.map +1 -1
- package/dist/cjs/authorizers/token-vault/TokenVaultAuthorizerParams.js.map +1 -1
- package/dist/cjs/authorizers/token-vault/asyncLocalStorage.js.map +1 -1
- package/dist/cjs/interrupts/TokenVaultInterrupt.js +7 -5
- package/dist/cjs/interrupts/TokenVaultInterrupt.js.map +1 -1
- package/dist/esm/authorizers/token-vault/TokenVaultAuthorizerBase.js +23 -7
- package/dist/esm/authorizers/token-vault/TokenVaultAuthorizerBase.js.map +1 -1
- package/dist/esm/authorizers/token-vault/TokenVaultAuthorizerParams.d.ts +5 -1
- package/dist/esm/authorizers/token-vault/TokenVaultAuthorizerParams.js.map +1 -1
- package/dist/esm/authorizers/token-vault/asyncLocalStorage.d.ts +4 -0
- package/dist/esm/authorizers/token-vault/asyncLocalStorage.js.map +1 -1
- package/dist/esm/interrupts/TokenVaultInterrupt.d.ts +12 -2
- package/dist/esm/interrupts/TokenVaultInterrupt.js +7 -5
- package/dist/esm/interrupts/TokenVaultInterrupt.js.map +1 -1
- package/package.json +1 -1
|
@@ -71,9 +71,14 @@ class TokenVaultAuthorizerBase {
|
|
|
71
71
|
if (!store) {
|
|
72
72
|
throw new Error("The tool must be wrapped with the FederationConnectionAuthorizer.");
|
|
73
73
|
}
|
|
74
|
-
const { scopes, connection } = store;
|
|
74
|
+
const { scopes, connection, authorizationParams } = store;
|
|
75
75
|
if (!tokenResponse) {
|
|
76
|
-
throw new interrupts_1.TokenVaultInterrupt(`Authorization required to access the Token Vault: ${this.params.connection}`,
|
|
76
|
+
throw new interrupts_1.TokenVaultInterrupt(`Authorization required to access the Token Vault: ${this.params.connection}`, {
|
|
77
|
+
connection,
|
|
78
|
+
scopes,
|
|
79
|
+
requiredScopes: scopes,
|
|
80
|
+
authorizationParams,
|
|
81
|
+
});
|
|
77
82
|
}
|
|
78
83
|
const currentScopes = ((_a = tokenResponse.scope) !== null && _a !== void 0 ? _a : "")
|
|
79
84
|
.replace(/,/g, " ")
|
|
@@ -81,7 +86,12 @@ class TokenVaultAuthorizerBase {
|
|
|
81
86
|
const missingScopes = scopes.filter((s) => !currentScopes.includes(s));
|
|
82
87
|
store.currentScopes = currentScopes;
|
|
83
88
|
if (missingScopes.length > 0) {
|
|
84
|
-
throw new interrupts_1.TokenVaultInterrupt(`Authorization required to access the Token Vault: ${this.params.connection}.
|
|
89
|
+
throw new interrupts_1.TokenVaultInterrupt(`Authorization required to access the Token Vault: ${this.params.connection}. Authorized scopes: ${currentScopes.join(", ")}. Missing scopes: ${missingScopes.join(", ")}`, {
|
|
90
|
+
connection,
|
|
91
|
+
scopes,
|
|
92
|
+
requiredScopes: [...currentScopes, ...missingScopes],
|
|
93
|
+
authorizationParams,
|
|
94
|
+
});
|
|
85
95
|
}
|
|
86
96
|
}
|
|
87
97
|
async getAccessTokenImpl(...toolContext) {
|
|
@@ -175,6 +185,7 @@ class TokenVaultAuthorizerBase {
|
|
|
175
185
|
context: context,
|
|
176
186
|
scopes: this.params.scopes,
|
|
177
187
|
connection: this.params.connection,
|
|
188
|
+
authorizationParams: this.params.authorizationParams,
|
|
178
189
|
};
|
|
179
190
|
if (asyncLocalStorage_1.asyncLocalStorage.getStore()) {
|
|
180
191
|
throw new Error("Cannot nest tool calls that require Token Vault authorization.");
|
|
@@ -193,7 +204,12 @@ class TokenVaultAuthorizerBase {
|
|
|
193
204
|
catch (err) {
|
|
194
205
|
if (err instanceof interrupts_1.TokenVaultError) {
|
|
195
206
|
this.credentialsStore.delete(credentialsNS, "credential");
|
|
196
|
-
const interrupt = new interrupts_1.TokenVaultInterrupt(err.message,
|
|
207
|
+
const interrupt = new interrupts_1.TokenVaultInterrupt(err.message, {
|
|
208
|
+
connection: asyncStore.connection,
|
|
209
|
+
scopes: asyncStore.scopes,
|
|
210
|
+
requiredScopes: asyncStore.scopes,
|
|
211
|
+
authorizationParams: asyncStore.authorizationParams,
|
|
212
|
+
});
|
|
197
213
|
return this.handleAuthorizationInterrupts(interrupt);
|
|
198
214
|
}
|
|
199
215
|
if (err instanceof interrupts_1.Auth0Interrupt) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenVaultAuthorizerBase.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/TokenVaultAuthorizerBase.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"crypto\";\nimport stableHash from \"stable-hash\";\n\nimport { TokenResponse, TokenSet, tokenSetFromTokenResponse } from \"../../credentials\";\nimport { Auth0Interrupt, TokenVaultError, TokenVaultInterrupt } from \"../../interrupts\";\nimport { resolveParameter } from \"../../parameters\";\nimport { SubStore } from \"../../stores\";\nimport { omit, RequireFields } from \"../../util\";\nimport { ContextGetter, nsFromContext } from \"../context\";\nimport { Auth0ClientParams, Auth0ClientSchema } from \"../types\";\nimport { asyncLocalStorage, AsyncStorageValue } from \"./asyncLocalStorage\";\nimport { SUBJECT_TOKEN_TYPES, TokenVaultAuthorizerParams } from \"./TokenVaultAuthorizerParams\";\n\n/**\n * Requests authorization to a third party service via Token Vault.\n */\n\nexport class TokenVaultAuthorizerBase<ToolExecuteArgs extends any[]> {\n private readonly auth0: Auth0ClientParams;\n private readonly params: RequireFields<\n TokenVaultAuthorizerParams<ToolExecuteArgs>,\n \"credentialsContext\"\n >;\n private readonly credentialsStore: SubStore<TokenSet>;\n\n constructor(\n auth0: Partial<Auth0ClientParams>,\n params: TokenVaultAuthorizerParams<ToolExecuteArgs>\n ) {\n this.auth0 = Auth0ClientSchema.parse(auth0);\n this.params = {\n credentialsContext: \"thread\",\n ...params,\n };\n\n const instanceID = this.getInstanceID();\n\n this.credentialsStore = new SubStore<TokenSet>(params.store, {\n baseNamespace: [instanceID, \"Credentials\"],\n getTTL: (credentials) =>\n credentials.expiresIn ? credentials.expiresIn * 1000 : undefined,\n });\n\n // Validate that exactly one token source is provided\n const hasRefreshToken = typeof params.refreshToken !== \"undefined\";\n const hasAccessToken = typeof params.accessToken !== \"undefined\";\n const hasSubjectTokenType = typeof params.subjectTokenType !== \"undefined\";\n\n if (!hasRefreshToken && !hasAccessToken) {\n throw new Error(\n \"Either refreshToken or accessToken must be provided to initialize the Authorizer.\"\n );\n }\n\n if (hasRefreshToken && hasAccessToken) {\n throw new Error(\n \"Only one of refreshToken or accessToken can be provided to initialize the Authorizer.\"\n );\n }\n\n // Validate resource server client credentials when using access tokens for token exchange w/ Token Vault\n if (\n hasAccessToken &&\n hasSubjectTokenType &&\n params.subjectTokenType === SUBJECT_TOKEN_TYPES.SUBJECT_TYPE_ACCESS_TOKEN\n ) {\n if (!this.auth0.clientId || !this.auth0.clientSecret) {\n throw new Error(\n \"clientId and clientSecret must currently be provided when using accessToken for token exchange with Token Vault.\"\n );\n }\n }\n }\n\n private getInstanceID(): string {\n const props = {\n auth0: this.auth0,\n params: omit(this.params, [\n \"store\",\n \"refreshToken\",\n \"accessToken\",\n \"loginHint\",\n ]),\n };\n const sh = stableHash(props);\n return crypto.createHash(\"MD5\").update(sh).digest(\"hex\");\n }\n\n protected handleAuthorizationInterrupts(err: Auth0Interrupt) {\n throw err;\n }\n\n protected validateToken(tokenResponse?: TokenResponse) {\n const store = asyncLocalStorage.getStore();\n if (!store) {\n throw new Error(\n \"The tool must be wrapped with the FederationConnectionAuthorizer.\"\n );\n }\n\n const { scopes, connection } = store;\n\n if (!tokenResponse) {\n throw new TokenVaultInterrupt(\n `Authorization required to access the Token Vault: ${this.params.connection}`,\n connection,\n scopes,\n scopes\n );\n }\n\n const currentScopes = (tokenResponse.scope ?? \"\")\n .replace(/,/g, \" \")\n .split(\" \");\n const missingScopes = scopes.filter((s) => !currentScopes.includes(s));\n store.currentScopes = currentScopes;\n\n if (missingScopes.length > 0) {\n throw new TokenVaultInterrupt(\n `Authorization required to access the Token Vault: ${this.params.connection}. Missing scopes: ${missingScopes.join(\", \")}`,\n connection,\n scopes,\n [...currentScopes, ...scopes]\n );\n }\n }\n\n private async getAccessTokenImpl(\n ...toolContext: ToolExecuteArgs\n ): Promise<TokenResponse | undefined> {\n const store = asyncLocalStorage.getStore();\n if (!store) {\n throw new Error(\n \"The tool must be wrapped with the FederationConnectionAuthorizer.\"\n );\n }\n\n const { connection } = store;\n\n // Determine which token type to use and get the appropriate subject token\n let subjectToken: string | undefined;\n let subjectTokenType: string;\n\n if (typeof this.params.refreshToken === \"function\") {\n subjectToken = await this.getRefreshToken(...toolContext);\n subjectTokenType = \"urn:ietf:params:oauth:token-type:refresh_token\";\n } else if (typeof this.params.accessToken === \"function\") {\n subjectToken = (await this.getAccessTokenWithToolContext(\n ...toolContext\n )) as string;\n subjectTokenType = \"urn:ietf:params:oauth:token-type:access_token\";\n } else if (typeof this.params.accessToken === \"string\") {\n subjectToken = this.params.accessToken;\n subjectTokenType = \"urn:ietf:params:oauth:token-type:access_token\";\n } else {\n // This should never happen due to constructor validation, but TypeScript needs this\n throw new Error(\"Either refreshToken or accessToken must be configured\");\n }\n\n if (!subjectToken) {\n return;\n }\n\n // Get optional login hint if provided\n const loginHint =\n typeof this.params.loginHint === \"function\"\n ? await resolveParameter(this.params.loginHint, toolContext)\n : undefined;\n\n const exchangeParams = {\n grant_type:\n \"urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token\",\n client_id: this.auth0.clientId,\n client_secret: this.auth0.clientSecret,\n subject_token_type: subjectTokenType,\n subject_token: subjectToken,\n login_hint: loginHint,\n connection: connection,\n requested_token_type:\n \"http://auth0.com/oauth/token-type/federated-connection-access-token\",\n };\n\n const res = await fetch(`https://${this.auth0.domain}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(exchangeParams),\n });\n\n if (!res.ok) {\n //TODO: handle all type of response errors.\n return;\n }\n\n const tokenResponse: TokenResponse = await res.json();\n return tokenResponse;\n }\n\n protected async getAccessToken(\n ...toolContext: ToolExecuteArgs\n ): Promise<TokenSet> {\n let tokenResponse: TokenResponse | undefined;\n // Use token exchange for both refresh tokens and access tokens when subjectTokenType is provided\n if (\n typeof this.params.refreshToken === \"function\" ||\n (typeof this.params.accessToken !== \"undefined\" &&\n this.params.subjectTokenType ===\n SUBJECT_TOKEN_TYPES.SUBJECT_TYPE_ACCESS_TOKEN)\n ) {\n tokenResponse = await this.getAccessTokenImpl(...toolContext);\n } else {\n // fallback to existing behavior, where third party accessToken can be provided directly\n tokenResponse = (await resolveParameter(\n this.params.accessToken!,\n toolContext\n )) as TokenResponse;\n }\n this.validateToken(tokenResponse);\n return tokenSetFromTokenResponse(tokenResponse!);\n }\n\n protected async getRefreshToken(...toolContext: ToolExecuteArgs) {\n return await resolveParameter(this.params.refreshToken, toolContext);\n }\n\n protected async getAccessTokenWithToolContext(\n ...toolContext: ToolExecuteArgs\n ) {\n return await resolveParameter(this.params.accessToken, toolContext);\n }\n\n /**\n *\n * Wraps the execute method of an AI tool to handle Token Vaults authorization.\n *\n * @param getContext - A function that returns the context of the tool execution.\n * @param execute - The tool execute method.\n * @returns The wrapped execute method.\n */\n protect(\n getContext: ContextGetter<ToolExecuteArgs>,\n execute: (...args: ToolExecuteArgs) => any\n ): (...args: ToolExecuteArgs) => any {\n return async (...args: ToolExecuteArgs) => {\n const context = getContext(...args);\n const asyncStore: AsyncStorageValue = {\n context: context,\n scopes: this.params.scopes,\n connection: this.params.connection,\n };\n\n if (asyncLocalStorage.getStore()) {\n throw new Error(\n \"Cannot nest tool calls that require Token Vault authorization.\"\n );\n }\n\n return asyncLocalStorage.run(asyncStore, async () => {\n const credentialsNS = nsFromContext(\n this.params.credentialsContext,\n context\n );\n try {\n let credentials: TokenSet = await this.credentialsStore.get(\n credentialsNS,\n \"credential\"\n );\n if (!credentials) {\n credentials = await this.getAccessToken(...args);\n await this.credentialsStore.put(\n credentialsNS,\n \"credential\",\n credentials\n );\n }\n asyncStore.credentials = credentials;\n return await execute(...args);\n } catch (err) {\n if (err instanceof TokenVaultError) {\n this.credentialsStore.delete(credentialsNS, \"credential\");\n const interrupt = new TokenVaultInterrupt(\n err.message,\n asyncStore.connection,\n asyncStore.scopes,\n asyncStore.scopes\n );\n return this.handleAuthorizationInterrupts(interrupt);\n }\n if (err instanceof Auth0Interrupt) {\n this.credentialsStore.delete(credentialsNS, \"credential\");\n return this.handleAuthorizationInterrupts(err);\n }\n throw err;\n }\n });\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TokenVaultAuthorizerBase.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/TokenVaultAuthorizerBase.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"crypto\";\nimport stableHash from \"stable-hash\";\n\nimport {\n TokenResponse,\n TokenSet,\n tokenSetFromTokenResponse,\n} from \"../../credentials\";\nimport {\n Auth0Interrupt,\n TokenVaultError,\n TokenVaultInterrupt,\n} from \"../../interrupts\";\nimport { resolveParameter } from \"../../parameters\";\nimport { SubStore } from \"../../stores\";\nimport { omit, RequireFields } from \"../../util\";\nimport { ContextGetter, nsFromContext } from \"../context\";\nimport { Auth0ClientParams, Auth0ClientSchema } from \"../types\";\nimport { asyncLocalStorage, AsyncStorageValue } from \"./asyncLocalStorage\";\nimport {\n SUBJECT_TOKEN_TYPES,\n TokenVaultAuthorizerParams,\n} from \"./TokenVaultAuthorizerParams\";\n\n/**\n * Requests authorization to a third party service via Token Vault.\n */\n\nexport class TokenVaultAuthorizerBase<ToolExecuteArgs extends any[]> {\n private readonly auth0: Auth0ClientParams;\n private readonly params: RequireFields<\n TokenVaultAuthorizerParams<ToolExecuteArgs>,\n \"credentialsContext\"\n >;\n private readonly credentialsStore: SubStore<TokenSet>;\n\n constructor(\n auth0: Partial<Auth0ClientParams>,\n params: TokenVaultAuthorizerParams<ToolExecuteArgs>,\n ) {\n this.auth0 = Auth0ClientSchema.parse(auth0);\n this.params = {\n credentialsContext: \"thread\",\n ...params,\n };\n\n const instanceID = this.getInstanceID();\n\n this.credentialsStore = new SubStore<TokenSet>(params.store, {\n baseNamespace: [instanceID, \"Credentials\"],\n getTTL: (credentials) =>\n credentials.expiresIn ? credentials.expiresIn * 1000 : undefined,\n });\n\n // Validate that exactly one token source is provided\n const hasRefreshToken = typeof params.refreshToken !== \"undefined\";\n const hasAccessToken = typeof params.accessToken !== \"undefined\";\n const hasSubjectTokenType = typeof params.subjectTokenType !== \"undefined\";\n\n if (!hasRefreshToken && !hasAccessToken) {\n throw new Error(\n \"Either refreshToken or accessToken must be provided to initialize the Authorizer.\",\n );\n }\n\n if (hasRefreshToken && hasAccessToken) {\n throw new Error(\n \"Only one of refreshToken or accessToken can be provided to initialize the Authorizer.\",\n );\n }\n\n // Validate resource server client credentials when using access tokens for token exchange w/ Token Vault\n if (\n hasAccessToken &&\n hasSubjectTokenType &&\n params.subjectTokenType === SUBJECT_TOKEN_TYPES.SUBJECT_TYPE_ACCESS_TOKEN\n ) {\n if (!this.auth0.clientId || !this.auth0.clientSecret) {\n throw new Error(\n \"clientId and clientSecret must currently be provided when using accessToken for token exchange with Token Vault.\",\n );\n }\n }\n }\n\n private getInstanceID(): string {\n const props = {\n auth0: this.auth0,\n params: omit(this.params, [\n \"store\",\n \"refreshToken\",\n \"accessToken\",\n \"loginHint\",\n ]),\n };\n const sh = stableHash(props);\n return crypto.createHash(\"MD5\").update(sh).digest(\"hex\");\n }\n\n protected handleAuthorizationInterrupts(err: Auth0Interrupt) {\n throw err;\n }\n\n protected validateToken(tokenResponse?: TokenResponse) {\n const store = asyncLocalStorage.getStore();\n if (!store) {\n throw new Error(\n \"The tool must be wrapped with the FederationConnectionAuthorizer.\",\n );\n }\n\n const { scopes, connection, authorizationParams } = store;\n\n if (!tokenResponse) {\n throw new TokenVaultInterrupt(\n `Authorization required to access the Token Vault: ${this.params.connection}`,\n {\n connection,\n scopes,\n requiredScopes: scopes,\n authorizationParams,\n },\n );\n }\n\n const currentScopes = (tokenResponse.scope ?? \"\")\n .replace(/,/g, \" \")\n .split(\" \");\n const missingScopes = scopes.filter((s) => !currentScopes.includes(s));\n store.currentScopes = currentScopes;\n\n if (missingScopes.length > 0) {\n throw new TokenVaultInterrupt(\n `Authorization required to access the Token Vault: ${this.params.connection}. Authorized scopes: ${currentScopes.join(\", \")}. Missing scopes: ${missingScopes.join(\", \")}`,\n {\n connection,\n scopes,\n requiredScopes: [...currentScopes, ...missingScopes],\n authorizationParams,\n },\n );\n }\n }\n\n private async getAccessTokenImpl(\n ...toolContext: ToolExecuteArgs\n ): Promise<TokenResponse | undefined> {\n const store = asyncLocalStorage.getStore();\n if (!store) {\n throw new Error(\n \"The tool must be wrapped with the FederationConnectionAuthorizer.\",\n );\n }\n\n const { connection } = store;\n\n // Determine which token type to use and get the appropriate subject token\n let subjectToken: string | undefined;\n let subjectTokenType: string;\n\n if (typeof this.params.refreshToken === \"function\") {\n subjectToken = await this.getRefreshToken(...toolContext);\n subjectTokenType = \"urn:ietf:params:oauth:token-type:refresh_token\";\n } else if (typeof this.params.accessToken === \"function\") {\n subjectToken = (await this.getAccessTokenWithToolContext(\n ...toolContext,\n )) as string;\n subjectTokenType = \"urn:ietf:params:oauth:token-type:access_token\";\n } else if (typeof this.params.accessToken === \"string\") {\n subjectToken = this.params.accessToken;\n subjectTokenType = \"urn:ietf:params:oauth:token-type:access_token\";\n } else {\n // This should never happen due to constructor validation, but TypeScript needs this\n throw new Error(\"Either refreshToken or accessToken must be configured\");\n }\n\n if (!subjectToken) {\n return;\n }\n\n // Get optional login hint if provided\n const loginHint =\n typeof this.params.loginHint === \"function\"\n ? await resolveParameter(this.params.loginHint, toolContext)\n : undefined;\n\n const exchangeParams = {\n grant_type:\n \"urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token\",\n client_id: this.auth0.clientId,\n client_secret: this.auth0.clientSecret,\n subject_token_type: subjectTokenType,\n subject_token: subjectToken,\n login_hint: loginHint,\n connection: connection,\n requested_token_type:\n \"http://auth0.com/oauth/token-type/federated-connection-access-token\",\n };\n\n const res = await fetch(`https://${this.auth0.domain}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(exchangeParams),\n });\n\n if (!res.ok) {\n //TODO: handle all type of response errors.\n return;\n }\n\n const tokenResponse: TokenResponse = await res.json();\n return tokenResponse;\n }\n\n protected async getAccessToken(\n ...toolContext: ToolExecuteArgs\n ): Promise<TokenSet> {\n let tokenResponse: TokenResponse | undefined;\n // Use token exchange for both refresh tokens and access tokens when subjectTokenType is provided\n if (\n typeof this.params.refreshToken === \"function\" ||\n (typeof this.params.accessToken !== \"undefined\" &&\n this.params.subjectTokenType ===\n SUBJECT_TOKEN_TYPES.SUBJECT_TYPE_ACCESS_TOKEN)\n ) {\n tokenResponse = await this.getAccessTokenImpl(...toolContext);\n } else {\n // fallback to existing behavior, where third party accessToken can be provided directly\n tokenResponse = (await resolveParameter(\n this.params.accessToken!,\n toolContext,\n )) as TokenResponse;\n }\n this.validateToken(tokenResponse);\n return tokenSetFromTokenResponse(tokenResponse!);\n }\n\n protected async getRefreshToken(...toolContext: ToolExecuteArgs) {\n return await resolveParameter(this.params.refreshToken, toolContext);\n }\n\n protected async getAccessTokenWithToolContext(\n ...toolContext: ToolExecuteArgs\n ) {\n return await resolveParameter(this.params.accessToken, toolContext);\n }\n\n /**\n *\n * Wraps the execute method of an AI tool to handle Token Vaults authorization.\n *\n * @param getContext - A function that returns the context of the tool execution.\n * @param execute - The tool execute method.\n * @returns The wrapped execute method.\n */\n protect(\n getContext: ContextGetter<ToolExecuteArgs>,\n execute: (...args: ToolExecuteArgs) => any,\n ): (...args: ToolExecuteArgs) => any {\n return async (...args: ToolExecuteArgs) => {\n const context = getContext(...args);\n const asyncStore: AsyncStorageValue = {\n context: context,\n scopes: this.params.scopes,\n connection: this.params.connection,\n authorizationParams: this.params.authorizationParams,\n };\n\n if (asyncLocalStorage.getStore()) {\n throw new Error(\n \"Cannot nest tool calls that require Token Vault authorization.\",\n );\n }\n\n return asyncLocalStorage.run(asyncStore, async () => {\n const credentialsNS = nsFromContext(\n this.params.credentialsContext,\n context,\n );\n try {\n let credentials: TokenSet = await this.credentialsStore.get(\n credentialsNS,\n \"credential\",\n );\n if (!credentials) {\n credentials = await this.getAccessToken(...args);\n await this.credentialsStore.put(\n credentialsNS,\n \"credential\",\n credentials,\n );\n }\n asyncStore.credentials = credentials;\n return await execute(...args);\n } catch (err) {\n if (err instanceof TokenVaultError) {\n this.credentialsStore.delete(credentialsNS, \"credential\");\n const interrupt = new TokenVaultInterrupt(err.message, {\n connection: asyncStore.connection,\n scopes: asyncStore.scopes,\n requiredScopes: asyncStore.scopes,\n authorizationParams: asyncStore.authorizationParams,\n });\n return this.handleAuthorizationInterrupts(interrupt);\n }\n if (err instanceof Auth0Interrupt) {\n this.credentialsStore.delete(credentialsNS, \"credential\");\n return this.handleAuthorizationInterrupts(err);\n }\n throw err;\n }\n });\n };\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenVaultAuthorizerParams.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/TokenVaultAuthorizerParams.ts"],"names":[],"mappings":";;;AAKA,IAAY,mBAcX;AAdD,WAAY,mBAAmB;IAC7B;;;;OAIG;IACH,oGAA6E,CAAA;IAE7E;;;;OAIG;IACH,kGAA2E,CAAA;AAC7E,CAAC,EAdW,mBAAmB,mCAAnB,mBAAmB,QAc9B","sourcesContent":["import { TokenResponse } from \"../../credentials\";\nimport { AuthorizerToolParameter } from \"../../parameters\";\nimport { Store } from \"../../stores\";\nimport { AuthContext } from \"../context\";\n\nexport enum SUBJECT_TOKEN_TYPES {\n /**\n * Indicates that the token is an OAuth 2.0 refresh token issued by the given authorization server.\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8693#section-3-3.4 RFC 8693 Section 3-3.4}\n */\n SUBJECT_TYPE_REFRESH_TOKEN = \"urn:ietf:params:oauth:token-type:refresh_token\",\n\n /**\n * Indicates that the token is an OAuth 2.0 access token issued by the given authorization server.\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8693#section-3-3.2 RFC 8693 Section 3-3.2}\n */\n SUBJECT_TYPE_ACCESS_TOKEN = \"urn:ietf:params:oauth:token-type:access_token\",\n}\n\nexport type TokenVaultAuthorizerParams<ToolExecuteArgs extends any[]> =\n {\n /**\n * The Auth0 refresh token to exchange for an Token Vault access token.\n */\n refreshToken?: AuthorizerToolParameter<ToolExecuteArgs, string | undefined>;\n\n /**\n * The Token Vault access token if available in the tool context.\n * This can also be provided as a string exchange when exchanging an access token for a Token Vault access token.\n */\n accessToken?:\n | AuthorizerToolParameter<\n ToolExecuteArgs,\n TokenResponse | string | undefined\n >\n | string\n | undefined;\n\n /**\n * This is used to specify the type of token being requested from Auth0 during the OAuth 2.0 token exchange request.\n */\n subjectTokenType?: SUBJECT_TOKEN_TYPES | undefined;\n\n /**\n * Optional login hint to provide when exchanging an access or refresh token for a Token Vault access token.\n */\n loginHint?: AuthorizerToolParameter<ToolExecuteArgs, string | undefined>;\n\n /**\n * The scopes required in the access token of the token vault provider.\n */\n scopes: string[];\n\n /**\n * The connection name of the token vault provider.\n */\n connection: string;\n\n /**\n * AuthContext defines the scope of credential sharing:\n * - \"tool-call\": Credentials are valid only for a single invocation of the tool.\n * - \"tool\": Credentials are shared across multiple calls to the same tool within the same thread.\n * - \"thread\": Credentials are shared across all tools using the same authorizer within the current thread.\n * - \"agent\": Credentials are shared globally across all threads and tools in the agent.\n *\n * @default \"thread\"\n */\n credentialsContext?: AuthContext;\n\n /**\n *
|
|
1
|
+
{"version":3,"file":"TokenVaultAuthorizerParams.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/TokenVaultAuthorizerParams.ts"],"names":[],"mappings":";;;AAKA,IAAY,mBAcX;AAdD,WAAY,mBAAmB;IAC7B;;;;OAIG;IACH,oGAA6E,CAAA;IAE7E;;;;OAIG;IACH,kGAA2E,CAAA;AAC7E,CAAC,EAdW,mBAAmB,mCAAnB,mBAAmB,QAc9B","sourcesContent":["import { TokenResponse } from \"../../credentials\";\nimport { AuthorizerToolParameter } from \"../../parameters\";\nimport { Store } from \"../../stores\";\nimport { AuthContext } from \"../context\";\n\nexport enum SUBJECT_TOKEN_TYPES {\n /**\n * Indicates that the token is an OAuth 2.0 refresh token issued by the given authorization server.\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8693#section-3-3.4 RFC 8693 Section 3-3.4}\n */\n SUBJECT_TYPE_REFRESH_TOKEN = \"urn:ietf:params:oauth:token-type:refresh_token\",\n\n /**\n * Indicates that the token is an OAuth 2.0 access token issued by the given authorization server.\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8693#section-3-3.2 RFC 8693 Section 3-3.2}\n */\n SUBJECT_TYPE_ACCESS_TOKEN = \"urn:ietf:params:oauth:token-type:access_token\",\n}\n\nexport type TokenVaultAuthorizerParams<ToolExecuteArgs extends any[]> =\n {\n /**\n * The Auth0 refresh token to exchange for an Token Vault access token.\n */\n refreshToken?: AuthorizerToolParameter<ToolExecuteArgs, string | undefined>;\n\n /**\n * The Token Vault access token if available in the tool context.\n * This can also be provided as a string exchange when exchanging an access token for a Token Vault access token.\n */\n accessToken?:\n | AuthorizerToolParameter<\n ToolExecuteArgs,\n TokenResponse | string | undefined\n >\n | string\n | undefined;\n\n /**\n * This is used to specify the type of token being requested from Auth0 during the OAuth 2.0 token exchange request.\n */\n subjectTokenType?: SUBJECT_TOKEN_TYPES | undefined;\n\n /**\n * Optional login hint to provide when exchanging an access or refresh token for a Token Vault access token.\n */\n loginHint?: AuthorizerToolParameter<ToolExecuteArgs, string | undefined>;\n\n /**\n * The scopes required in the access token of the token vault provider.\n */\n scopes: string[];\n\n /**\n * The connection name of the token vault provider.\n */\n connection: string;\n\n /**\n * Additional authorization parameters to be passed during token acquisition.\n */\n authorizationParams?: Record<string, string>;\n\n /**\n * AuthContext defines the scope of credential sharing:\n * - \"tool-call\": Credentials are valid only for a single invocation of the tool.\n * - \"tool\": Credentials are shared across multiple calls to the same tool within the same thread.\n * - \"thread\": Credentials are shared across all tools using the same authorizer within the current thread.\n * - \"agent\": Credentials are shared globally across all threads and tools in the agent.\n *\n * @default \"thread\"\n */\n credentialsContext?: AuthContext;\n\n /**\n * A store used to store the authorization credentials according\n * to the `credentialsContext` scope.\n */\n store: Store;\n };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asyncLocalStorage.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/asyncLocalStorage.ts"],"names":[],"mappings":";;;AAAA,uDAAqD;AAGrD,iDAAmD;
|
|
1
|
+
{"version":3,"file":"asyncLocalStorage.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/asyncLocalStorage.ts"],"names":[],"mappings":";;;AAAA,uDAAqD;AAGrD,iDAAmD;AAmCtC,QAAA,iBAAiB,GAAG,IAAI,oCAAiB,EAAqB,CAAC;AAE5E;;;;;;GAMG;AACI,MAAM,4BAA4B,GAAG,GAAG,EAAE;IAC/C,MAAM,KAAK,GAAG,yBAAiB,CAAC,QAAQ,EAAE,CAAC;IAC3C,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,WAAW,CAAC;AAC5B,CAAC,CAAC;AARW,QAAA,4BAA4B,gCAQvC;AAEF;;;;;GAKG;AACI,MAAM,4BAA4B,GAAG,GAAG,EAAE;IAC/C,MAAM,WAAW,GAAG,IAAA,oCAA4B,GAAE,CAAC;IACnD,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,IAAI,4BAAe,CAAC,sBAAsB,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,WAAW,CAAC,WAAW,CAAC;AACjC,CAAC,CAAC;AANW,QAAA,4BAA4B,gCAMvC","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { TokenSet } from \"../../credentials\";\nimport { TokenVaultError } from \"../../interrupts\";\nimport { ToolCallContext } from \"../context\";\n\nexport type AsyncStorageValue = {\n /**\n * The Token Vault access token.\n */\n credentials?: TokenSet;\n\n /**\n * The tool execution context.\n */\n context: ToolCallContext;\n\n /**\n * The token vault name.\n */\n connection: string;\n\n /**\n * The scopes required to access the token vault.\n */\n scopes: string[];\n\n /**\n * The scopes that the current access token has.\n */\n currentScopes?: string[];\n\n /**\n * Additional authorization parameters to be passed during token acquisition.\n */\n authorizationParams?: Record<string, string>;\n};\n\nexport const asyncLocalStorage = new AsyncLocalStorage<AsyncStorageValue>();\n\n/**\n * Returns the entire tokenset for the current connection.\n *\n * Use `getAccessTokenFromTokenVault` if you only need the access token.\n *\n * @returns {TokenSet} The current token set.\n */\nexport const getCredentialsFromTokenVault = () => {\n const store = asyncLocalStorage.getStore();\n if (typeof store === \"undefined\") {\n throw new Error(\n \"The tool must be wrapped with the withTokenVault function.\"\n );\n }\n return store?.credentials;\n};\n\n/**\n *\n * Get the access token for the current connection.\n *\n * @returns The access token for the current connection.\n */\nexport const getAccessTokenFromTokenVault = () => {\n const credentials = getCredentialsFromTokenVault();\n if (!credentials || !credentials.accessToken) {\n throw new TokenVaultError(\"No credentials found\");\n }\n return credentials.accessToken;\n};\n"]}
|
|
@@ -8,12 +8,14 @@ const Auth0Interrupt_1 = require("./Auth0Interrupt");
|
|
|
8
8
|
* Throw this error if the service returns Unauthorized for the current access token.
|
|
9
9
|
*/
|
|
10
10
|
class TokenVaultInterrupt extends Auth0Interrupt_1.Auth0Interrupt {
|
|
11
|
-
constructor(message,
|
|
11
|
+
constructor(message, params) {
|
|
12
|
+
var _a, _b;
|
|
12
13
|
super(message, TokenVaultInterrupt.code);
|
|
13
|
-
this.
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
14
|
+
this.connection = params.connection;
|
|
15
|
+
this.scopes = params.scopes;
|
|
16
|
+
this.requiredScopes = params.requiredScopes;
|
|
17
|
+
this.authorizationParams = { ...((_a = params.authorizationParams) !== null && _a !== void 0 ? _a : {}) };
|
|
18
|
+
this.behavior = (_b = params.behavior) !== null && _b !== void 0 ? _b : "resume";
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
exports.TokenVaultInterrupt = TokenVaultInterrupt;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenVaultInterrupt.js","sourceRoot":"","sources":["../../../src/interrupts/TokenVaultInterrupt.ts"],"names":[],"mappings":";;;AAAA,qDAAkD;AAElD;;;;GAIG;AACH,MAAa,mBAAoB,SAAQ,+BAAc;
|
|
1
|
+
{"version":3,"file":"TokenVaultInterrupt.js","sourceRoot":"","sources":["../../../src/interrupts/TokenVaultInterrupt.ts"],"names":[],"mappings":";;;AAAA,qDAAkD;AAElD;;;;GAIG;AACH,MAAa,mBAAoB,SAAQ,+BAAc;IA2BrD,YAAY,OAAe,EAAE,MAM5B;;QACC,KAAK,CAAC,OAAO,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAC5C,IAAI,CAAC,mBAAmB,GAAG,EAAE,GAAG,CAAC,MAAA,MAAM,CAAC,mBAAmB,mCAAI,EAAE,CAAC,EAAE,CAAC;QACrE,IAAI,CAAC,QAAQ,GAAG,MAAA,MAAM,CAAC,QAAQ,mCAAI,QAAQ,CAAC;IAC9C,CAAC;;AAxCH,kDAyCC;AAhBe,wBAAI,GAAG,mBAA4B,CAAC;AAkBpD;;;;GAIG;AACH,MAAa,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;CACF;AAJD,0CAIC","sourcesContent":["import { Auth0Interrupt } from \"./Auth0Interrupt\";\n\n/**\n * Error thrown when a tool call requires an access token for an external service.\n *\n * Throw this error if the service returns Unauthorized for the current access token.\n */\nexport class TokenVaultInterrupt extends Auth0Interrupt {\n /**\n * The auth0 connection name.\n */\n public readonly connection: string;\n\n /**\n * The scopes required to access the external service as stated\n * in the authorizer.\n */\n public readonly scopes: string[];\n\n /**\n * The union between the current scopes of the Access Token plus the required scopes.\n * This is the list of scopes that will be used to request a new Access Token.\n */\n public readonly requiredScopes: string[];\n\n /**\n * Additional authorization parameters to be passed during token acquisition.\n */\n public readonly authorizationParams: Record<string, string>;\n\n public readonly behavior: \"resume\" | \"reload\";\n\n public static code = \"TOKEN_VAULT_ERROR\" as const;\n\n constructor(message: string, params: {\n connection: string;\n scopes: string[];\n requiredScopes: string[];\n authorizationParams?: Record<string, string>;\n behavior?: \"resume\" | \"reload\";\n }) {\n super(message, TokenVaultInterrupt.code);\n this.connection = params.connection;\n this.scopes = params.scopes;\n this.requiredScopes = params.requiredScopes;\n this.authorizationParams = { ...(params.authorizationParams ?? {}) };\n this.behavior = params.behavior ?? \"resume\";\n }\n}\n\n/**\n * Error thrown when a tool call requires an access token for an external service.\n *\n * The authorizer will automatically convert this class of error to TokenVaultInterrupt.\n */\nexport class TokenVaultError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n"]}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import crypto from "crypto";
|
|
2
2
|
import stableHash from "stable-hash";
|
|
3
|
-
import { tokenSetFromTokenResponse } from "../../credentials";
|
|
4
|
-
import { Auth0Interrupt, TokenVaultError, TokenVaultInterrupt } from "../../interrupts";
|
|
3
|
+
import { tokenSetFromTokenResponse, } from "../../credentials";
|
|
4
|
+
import { Auth0Interrupt, TokenVaultError, TokenVaultInterrupt, } from "../../interrupts";
|
|
5
5
|
import { resolveParameter } from "../../parameters";
|
|
6
6
|
import { SubStore } from "../../stores";
|
|
7
7
|
import { omit } from "../../util";
|
|
8
8
|
import { nsFromContext } from "../context";
|
|
9
9
|
import { Auth0ClientSchema } from "../types";
|
|
10
10
|
import { asyncLocalStorage } from "./asyncLocalStorage";
|
|
11
|
-
import { SUBJECT_TOKEN_TYPES } from "./TokenVaultAuthorizerParams";
|
|
11
|
+
import { SUBJECT_TOKEN_TYPES, } from "./TokenVaultAuthorizerParams";
|
|
12
12
|
/**
|
|
13
13
|
* Requests authorization to a third party service via Token Vault.
|
|
14
14
|
*/
|
|
@@ -65,9 +65,14 @@ export class TokenVaultAuthorizerBase {
|
|
|
65
65
|
if (!store) {
|
|
66
66
|
throw new Error("The tool must be wrapped with the FederationConnectionAuthorizer.");
|
|
67
67
|
}
|
|
68
|
-
const { scopes, connection } = store;
|
|
68
|
+
const { scopes, connection, authorizationParams } = store;
|
|
69
69
|
if (!tokenResponse) {
|
|
70
|
-
throw new TokenVaultInterrupt(`Authorization required to access the Token Vault: ${this.params.connection}`,
|
|
70
|
+
throw new TokenVaultInterrupt(`Authorization required to access the Token Vault: ${this.params.connection}`, {
|
|
71
|
+
connection,
|
|
72
|
+
scopes,
|
|
73
|
+
requiredScopes: scopes,
|
|
74
|
+
authorizationParams,
|
|
75
|
+
});
|
|
71
76
|
}
|
|
72
77
|
const currentScopes = ((_a = tokenResponse.scope) !== null && _a !== void 0 ? _a : "")
|
|
73
78
|
.replace(/,/g, " ")
|
|
@@ -75,7 +80,12 @@ export class TokenVaultAuthorizerBase {
|
|
|
75
80
|
const missingScopes = scopes.filter((s) => !currentScopes.includes(s));
|
|
76
81
|
store.currentScopes = currentScopes;
|
|
77
82
|
if (missingScopes.length > 0) {
|
|
78
|
-
throw new TokenVaultInterrupt(`Authorization required to access the Token Vault: ${this.params.connection}.
|
|
83
|
+
throw new TokenVaultInterrupt(`Authorization required to access the Token Vault: ${this.params.connection}. Authorized scopes: ${currentScopes.join(", ")}. Missing scopes: ${missingScopes.join(", ")}`, {
|
|
84
|
+
connection,
|
|
85
|
+
scopes,
|
|
86
|
+
requiredScopes: [...currentScopes, ...missingScopes],
|
|
87
|
+
authorizationParams,
|
|
88
|
+
});
|
|
79
89
|
}
|
|
80
90
|
}
|
|
81
91
|
async getAccessTokenImpl(...toolContext) {
|
|
@@ -169,6 +179,7 @@ export class TokenVaultAuthorizerBase {
|
|
|
169
179
|
context: context,
|
|
170
180
|
scopes: this.params.scopes,
|
|
171
181
|
connection: this.params.connection,
|
|
182
|
+
authorizationParams: this.params.authorizationParams,
|
|
172
183
|
};
|
|
173
184
|
if (asyncLocalStorage.getStore()) {
|
|
174
185
|
throw new Error("Cannot nest tool calls that require Token Vault authorization.");
|
|
@@ -187,7 +198,12 @@ export class TokenVaultAuthorizerBase {
|
|
|
187
198
|
catch (err) {
|
|
188
199
|
if (err instanceof TokenVaultError) {
|
|
189
200
|
this.credentialsStore.delete(credentialsNS, "credential");
|
|
190
|
-
const interrupt = new TokenVaultInterrupt(err.message,
|
|
201
|
+
const interrupt = new TokenVaultInterrupt(err.message, {
|
|
202
|
+
connection: asyncStore.connection,
|
|
203
|
+
scopes: asyncStore.scopes,
|
|
204
|
+
requiredScopes: asyncStore.scopes,
|
|
205
|
+
authorizationParams: asyncStore.authorizationParams,
|
|
206
|
+
});
|
|
191
207
|
return this.handleAuthorizationInterrupts(interrupt);
|
|
192
208
|
}
|
|
193
209
|
if (err instanceof Auth0Interrupt) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenVaultAuthorizerBase.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/TokenVaultAuthorizerBase.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"crypto\";\nimport stableHash from \"stable-hash\";\n\nimport { TokenResponse, TokenSet, tokenSetFromTokenResponse } from \"../../credentials\";\nimport { Auth0Interrupt, TokenVaultError, TokenVaultInterrupt } from \"../../interrupts\";\nimport { resolveParameter } from \"../../parameters\";\nimport { SubStore } from \"../../stores\";\nimport { omit, RequireFields } from \"../../util\";\nimport { ContextGetter, nsFromContext } from \"../context\";\nimport { Auth0ClientParams, Auth0ClientSchema } from \"../types\";\nimport { asyncLocalStorage, AsyncStorageValue } from \"./asyncLocalStorage\";\nimport { SUBJECT_TOKEN_TYPES, TokenVaultAuthorizerParams } from \"./TokenVaultAuthorizerParams\";\n\n/**\n * Requests authorization to a third party service via Token Vault.\n */\n\nexport class TokenVaultAuthorizerBase<ToolExecuteArgs extends any[]> {\n private readonly auth0: Auth0ClientParams;\n private readonly params: RequireFields<\n TokenVaultAuthorizerParams<ToolExecuteArgs>,\n \"credentialsContext\"\n >;\n private readonly credentialsStore: SubStore<TokenSet>;\n\n constructor(\n auth0: Partial<Auth0ClientParams>,\n params: TokenVaultAuthorizerParams<ToolExecuteArgs>\n ) {\n this.auth0 = Auth0ClientSchema.parse(auth0);\n this.params = {\n credentialsContext: \"thread\",\n ...params,\n };\n\n const instanceID = this.getInstanceID();\n\n this.credentialsStore = new SubStore<TokenSet>(params.store, {\n baseNamespace: [instanceID, \"Credentials\"],\n getTTL: (credentials) =>\n credentials.expiresIn ? credentials.expiresIn * 1000 : undefined,\n });\n\n // Validate that exactly one token source is provided\n const hasRefreshToken = typeof params.refreshToken !== \"undefined\";\n const hasAccessToken = typeof params.accessToken !== \"undefined\";\n const hasSubjectTokenType = typeof params.subjectTokenType !== \"undefined\";\n\n if (!hasRefreshToken && !hasAccessToken) {\n throw new Error(\n \"Either refreshToken or accessToken must be provided to initialize the Authorizer.\"\n );\n }\n\n if (hasRefreshToken && hasAccessToken) {\n throw new Error(\n \"Only one of refreshToken or accessToken can be provided to initialize the Authorizer.\"\n );\n }\n\n // Validate resource server client credentials when using access tokens for token exchange w/ Token Vault\n if (\n hasAccessToken &&\n hasSubjectTokenType &&\n params.subjectTokenType === SUBJECT_TOKEN_TYPES.SUBJECT_TYPE_ACCESS_TOKEN\n ) {\n if (!this.auth0.clientId || !this.auth0.clientSecret) {\n throw new Error(\n \"clientId and clientSecret must currently be provided when using accessToken for token exchange with Token Vault.\"\n );\n }\n }\n }\n\n private getInstanceID(): string {\n const props = {\n auth0: this.auth0,\n params: omit(this.params, [\n \"store\",\n \"refreshToken\",\n \"accessToken\",\n \"loginHint\",\n ]),\n };\n const sh = stableHash(props);\n return crypto.createHash(\"MD5\").update(sh).digest(\"hex\");\n }\n\n protected handleAuthorizationInterrupts(err: Auth0Interrupt) {\n throw err;\n }\n\n protected validateToken(tokenResponse?: TokenResponse) {\n const store = asyncLocalStorage.getStore();\n if (!store) {\n throw new Error(\n \"The tool must be wrapped with the FederationConnectionAuthorizer.\"\n );\n }\n\n const { scopes, connection } = store;\n\n if (!tokenResponse) {\n throw new TokenVaultInterrupt(\n `Authorization required to access the Token Vault: ${this.params.connection}`,\n connection,\n scopes,\n scopes\n );\n }\n\n const currentScopes = (tokenResponse.scope ?? \"\")\n .replace(/,/g, \" \")\n .split(\" \");\n const missingScopes = scopes.filter((s) => !currentScopes.includes(s));\n store.currentScopes = currentScopes;\n\n if (missingScopes.length > 0) {\n throw new TokenVaultInterrupt(\n `Authorization required to access the Token Vault: ${this.params.connection}. Missing scopes: ${missingScopes.join(\", \")}`,\n connection,\n scopes,\n [...currentScopes, ...scopes]\n );\n }\n }\n\n private async getAccessTokenImpl(\n ...toolContext: ToolExecuteArgs\n ): Promise<TokenResponse | undefined> {\n const store = asyncLocalStorage.getStore();\n if (!store) {\n throw new Error(\n \"The tool must be wrapped with the FederationConnectionAuthorizer.\"\n );\n }\n\n const { connection } = store;\n\n // Determine which token type to use and get the appropriate subject token\n let subjectToken: string | undefined;\n let subjectTokenType: string;\n\n if (typeof this.params.refreshToken === \"function\") {\n subjectToken = await this.getRefreshToken(...toolContext);\n subjectTokenType = \"urn:ietf:params:oauth:token-type:refresh_token\";\n } else if (typeof this.params.accessToken === \"function\") {\n subjectToken = (await this.getAccessTokenWithToolContext(\n ...toolContext\n )) as string;\n subjectTokenType = \"urn:ietf:params:oauth:token-type:access_token\";\n } else if (typeof this.params.accessToken === \"string\") {\n subjectToken = this.params.accessToken;\n subjectTokenType = \"urn:ietf:params:oauth:token-type:access_token\";\n } else {\n // This should never happen due to constructor validation, but TypeScript needs this\n throw new Error(\"Either refreshToken or accessToken must be configured\");\n }\n\n if (!subjectToken) {\n return;\n }\n\n // Get optional login hint if provided\n const loginHint =\n typeof this.params.loginHint === \"function\"\n ? await resolveParameter(this.params.loginHint, toolContext)\n : undefined;\n\n const exchangeParams = {\n grant_type:\n \"urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token\",\n client_id: this.auth0.clientId,\n client_secret: this.auth0.clientSecret,\n subject_token_type: subjectTokenType,\n subject_token: subjectToken,\n login_hint: loginHint,\n connection: connection,\n requested_token_type:\n \"http://auth0.com/oauth/token-type/federated-connection-access-token\",\n };\n\n const res = await fetch(`https://${this.auth0.domain}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(exchangeParams),\n });\n\n if (!res.ok) {\n //TODO: handle all type of response errors.\n return;\n }\n\n const tokenResponse: TokenResponse = await res.json();\n return tokenResponse;\n }\n\n protected async getAccessToken(\n ...toolContext: ToolExecuteArgs\n ): Promise<TokenSet> {\n let tokenResponse: TokenResponse | undefined;\n // Use token exchange for both refresh tokens and access tokens when subjectTokenType is provided\n if (\n typeof this.params.refreshToken === \"function\" ||\n (typeof this.params.accessToken !== \"undefined\" &&\n this.params.subjectTokenType ===\n SUBJECT_TOKEN_TYPES.SUBJECT_TYPE_ACCESS_TOKEN)\n ) {\n tokenResponse = await this.getAccessTokenImpl(...toolContext);\n } else {\n // fallback to existing behavior, where third party accessToken can be provided directly\n tokenResponse = (await resolveParameter(\n this.params.accessToken!,\n toolContext\n )) as TokenResponse;\n }\n this.validateToken(tokenResponse);\n return tokenSetFromTokenResponse(tokenResponse!);\n }\n\n protected async getRefreshToken(...toolContext: ToolExecuteArgs) {\n return await resolveParameter(this.params.refreshToken, toolContext);\n }\n\n protected async getAccessTokenWithToolContext(\n ...toolContext: ToolExecuteArgs\n ) {\n return await resolveParameter(this.params.accessToken, toolContext);\n }\n\n /**\n *\n * Wraps the execute method of an AI tool to handle Token Vaults authorization.\n *\n * @param getContext - A function that returns the context of the tool execution.\n * @param execute - The tool execute method.\n * @returns The wrapped execute method.\n */\n protect(\n getContext: ContextGetter<ToolExecuteArgs>,\n execute: (...args: ToolExecuteArgs) => any\n ): (...args: ToolExecuteArgs) => any {\n return async (...args: ToolExecuteArgs) => {\n const context = getContext(...args);\n const asyncStore: AsyncStorageValue = {\n context: context,\n scopes: this.params.scopes,\n connection: this.params.connection,\n };\n\n if (asyncLocalStorage.getStore()) {\n throw new Error(\n \"Cannot nest tool calls that require Token Vault authorization.\"\n );\n }\n\n return asyncLocalStorage.run(asyncStore, async () => {\n const credentialsNS = nsFromContext(\n this.params.credentialsContext,\n context\n );\n try {\n let credentials: TokenSet = await this.credentialsStore.get(\n credentialsNS,\n \"credential\"\n );\n if (!credentials) {\n credentials = await this.getAccessToken(...args);\n await this.credentialsStore.put(\n credentialsNS,\n \"credential\",\n credentials\n );\n }\n asyncStore.credentials = credentials;\n return await execute(...args);\n } catch (err) {\n if (err instanceof TokenVaultError) {\n this.credentialsStore.delete(credentialsNS, \"credential\");\n const interrupt = new TokenVaultInterrupt(\n err.message,\n asyncStore.connection,\n asyncStore.scopes,\n asyncStore.scopes\n );\n return this.handleAuthorizationInterrupts(interrupt);\n }\n if (err instanceof Auth0Interrupt) {\n this.credentialsStore.delete(credentialsNS, \"credential\");\n return this.handleAuthorizationInterrupts(err);\n }\n throw err;\n }\n });\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TokenVaultAuthorizerBase.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/TokenVaultAuthorizerBase.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"crypto\";\nimport stableHash from \"stable-hash\";\n\nimport {\n TokenResponse,\n TokenSet,\n tokenSetFromTokenResponse,\n} from \"../../credentials\";\nimport {\n Auth0Interrupt,\n TokenVaultError,\n TokenVaultInterrupt,\n} from \"../../interrupts\";\nimport { resolveParameter } from \"../../parameters\";\nimport { SubStore } from \"../../stores\";\nimport { omit, RequireFields } from \"../../util\";\nimport { ContextGetter, nsFromContext } from \"../context\";\nimport { Auth0ClientParams, Auth0ClientSchema } from \"../types\";\nimport { asyncLocalStorage, AsyncStorageValue } from \"./asyncLocalStorage\";\nimport {\n SUBJECT_TOKEN_TYPES,\n TokenVaultAuthorizerParams,\n} from \"./TokenVaultAuthorizerParams\";\n\n/**\n * Requests authorization to a third party service via Token Vault.\n */\n\nexport class TokenVaultAuthorizerBase<ToolExecuteArgs extends any[]> {\n private readonly auth0: Auth0ClientParams;\n private readonly params: RequireFields<\n TokenVaultAuthorizerParams<ToolExecuteArgs>,\n \"credentialsContext\"\n >;\n private readonly credentialsStore: SubStore<TokenSet>;\n\n constructor(\n auth0: Partial<Auth0ClientParams>,\n params: TokenVaultAuthorizerParams<ToolExecuteArgs>,\n ) {\n this.auth0 = Auth0ClientSchema.parse(auth0);\n this.params = {\n credentialsContext: \"thread\",\n ...params,\n };\n\n const instanceID = this.getInstanceID();\n\n this.credentialsStore = new SubStore<TokenSet>(params.store, {\n baseNamespace: [instanceID, \"Credentials\"],\n getTTL: (credentials) =>\n credentials.expiresIn ? credentials.expiresIn * 1000 : undefined,\n });\n\n // Validate that exactly one token source is provided\n const hasRefreshToken = typeof params.refreshToken !== \"undefined\";\n const hasAccessToken = typeof params.accessToken !== \"undefined\";\n const hasSubjectTokenType = typeof params.subjectTokenType !== \"undefined\";\n\n if (!hasRefreshToken && !hasAccessToken) {\n throw new Error(\n \"Either refreshToken or accessToken must be provided to initialize the Authorizer.\",\n );\n }\n\n if (hasRefreshToken && hasAccessToken) {\n throw new Error(\n \"Only one of refreshToken or accessToken can be provided to initialize the Authorizer.\",\n );\n }\n\n // Validate resource server client credentials when using access tokens for token exchange w/ Token Vault\n if (\n hasAccessToken &&\n hasSubjectTokenType &&\n params.subjectTokenType === SUBJECT_TOKEN_TYPES.SUBJECT_TYPE_ACCESS_TOKEN\n ) {\n if (!this.auth0.clientId || !this.auth0.clientSecret) {\n throw new Error(\n \"clientId and clientSecret must currently be provided when using accessToken for token exchange with Token Vault.\",\n );\n }\n }\n }\n\n private getInstanceID(): string {\n const props = {\n auth0: this.auth0,\n params: omit(this.params, [\n \"store\",\n \"refreshToken\",\n \"accessToken\",\n \"loginHint\",\n ]),\n };\n const sh = stableHash(props);\n return crypto.createHash(\"MD5\").update(sh).digest(\"hex\");\n }\n\n protected handleAuthorizationInterrupts(err: Auth0Interrupt) {\n throw err;\n }\n\n protected validateToken(tokenResponse?: TokenResponse) {\n const store = asyncLocalStorage.getStore();\n if (!store) {\n throw new Error(\n \"The tool must be wrapped with the FederationConnectionAuthorizer.\",\n );\n }\n\n const { scopes, connection, authorizationParams } = store;\n\n if (!tokenResponse) {\n throw new TokenVaultInterrupt(\n `Authorization required to access the Token Vault: ${this.params.connection}`,\n {\n connection,\n scopes,\n requiredScopes: scopes,\n authorizationParams,\n },\n );\n }\n\n const currentScopes = (tokenResponse.scope ?? \"\")\n .replace(/,/g, \" \")\n .split(\" \");\n const missingScopes = scopes.filter((s) => !currentScopes.includes(s));\n store.currentScopes = currentScopes;\n\n if (missingScopes.length > 0) {\n throw new TokenVaultInterrupt(\n `Authorization required to access the Token Vault: ${this.params.connection}. Authorized scopes: ${currentScopes.join(\", \")}. Missing scopes: ${missingScopes.join(\", \")}`,\n {\n connection,\n scopes,\n requiredScopes: [...currentScopes, ...missingScopes],\n authorizationParams,\n },\n );\n }\n }\n\n private async getAccessTokenImpl(\n ...toolContext: ToolExecuteArgs\n ): Promise<TokenResponse | undefined> {\n const store = asyncLocalStorage.getStore();\n if (!store) {\n throw new Error(\n \"The tool must be wrapped with the FederationConnectionAuthorizer.\",\n );\n }\n\n const { connection } = store;\n\n // Determine which token type to use and get the appropriate subject token\n let subjectToken: string | undefined;\n let subjectTokenType: string;\n\n if (typeof this.params.refreshToken === \"function\") {\n subjectToken = await this.getRefreshToken(...toolContext);\n subjectTokenType = \"urn:ietf:params:oauth:token-type:refresh_token\";\n } else if (typeof this.params.accessToken === \"function\") {\n subjectToken = (await this.getAccessTokenWithToolContext(\n ...toolContext,\n )) as string;\n subjectTokenType = \"urn:ietf:params:oauth:token-type:access_token\";\n } else if (typeof this.params.accessToken === \"string\") {\n subjectToken = this.params.accessToken;\n subjectTokenType = \"urn:ietf:params:oauth:token-type:access_token\";\n } else {\n // This should never happen due to constructor validation, but TypeScript needs this\n throw new Error(\"Either refreshToken or accessToken must be configured\");\n }\n\n if (!subjectToken) {\n return;\n }\n\n // Get optional login hint if provided\n const loginHint =\n typeof this.params.loginHint === \"function\"\n ? await resolveParameter(this.params.loginHint, toolContext)\n : undefined;\n\n const exchangeParams = {\n grant_type:\n \"urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token\",\n client_id: this.auth0.clientId,\n client_secret: this.auth0.clientSecret,\n subject_token_type: subjectTokenType,\n subject_token: subjectToken,\n login_hint: loginHint,\n connection: connection,\n requested_token_type:\n \"http://auth0.com/oauth/token-type/federated-connection-access-token\",\n };\n\n const res = await fetch(`https://${this.auth0.domain}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(exchangeParams),\n });\n\n if (!res.ok) {\n //TODO: handle all type of response errors.\n return;\n }\n\n const tokenResponse: TokenResponse = await res.json();\n return tokenResponse;\n }\n\n protected async getAccessToken(\n ...toolContext: ToolExecuteArgs\n ): Promise<TokenSet> {\n let tokenResponse: TokenResponse | undefined;\n // Use token exchange for both refresh tokens and access tokens when subjectTokenType is provided\n if (\n typeof this.params.refreshToken === \"function\" ||\n (typeof this.params.accessToken !== \"undefined\" &&\n this.params.subjectTokenType ===\n SUBJECT_TOKEN_TYPES.SUBJECT_TYPE_ACCESS_TOKEN)\n ) {\n tokenResponse = await this.getAccessTokenImpl(...toolContext);\n } else {\n // fallback to existing behavior, where third party accessToken can be provided directly\n tokenResponse = (await resolveParameter(\n this.params.accessToken!,\n toolContext,\n )) as TokenResponse;\n }\n this.validateToken(tokenResponse);\n return tokenSetFromTokenResponse(tokenResponse!);\n }\n\n protected async getRefreshToken(...toolContext: ToolExecuteArgs) {\n return await resolveParameter(this.params.refreshToken, toolContext);\n }\n\n protected async getAccessTokenWithToolContext(\n ...toolContext: ToolExecuteArgs\n ) {\n return await resolveParameter(this.params.accessToken, toolContext);\n }\n\n /**\n *\n * Wraps the execute method of an AI tool to handle Token Vaults authorization.\n *\n * @param getContext - A function that returns the context of the tool execution.\n * @param execute - The tool execute method.\n * @returns The wrapped execute method.\n */\n protect(\n getContext: ContextGetter<ToolExecuteArgs>,\n execute: (...args: ToolExecuteArgs) => any,\n ): (...args: ToolExecuteArgs) => any {\n return async (...args: ToolExecuteArgs) => {\n const context = getContext(...args);\n const asyncStore: AsyncStorageValue = {\n context: context,\n scopes: this.params.scopes,\n connection: this.params.connection,\n authorizationParams: this.params.authorizationParams,\n };\n\n if (asyncLocalStorage.getStore()) {\n throw new Error(\n \"Cannot nest tool calls that require Token Vault authorization.\",\n );\n }\n\n return asyncLocalStorage.run(asyncStore, async () => {\n const credentialsNS = nsFromContext(\n this.params.credentialsContext,\n context,\n );\n try {\n let credentials: TokenSet = await this.credentialsStore.get(\n credentialsNS,\n \"credential\",\n );\n if (!credentials) {\n credentials = await this.getAccessToken(...args);\n await this.credentialsStore.put(\n credentialsNS,\n \"credential\",\n credentials,\n );\n }\n asyncStore.credentials = credentials;\n return await execute(...args);\n } catch (err) {\n if (err instanceof TokenVaultError) {\n this.credentialsStore.delete(credentialsNS, \"credential\");\n const interrupt = new TokenVaultInterrupt(err.message, {\n connection: asyncStore.connection,\n scopes: asyncStore.scopes,\n requiredScopes: asyncStore.scopes,\n authorizationParams: asyncStore.authorizationParams,\n });\n return this.handleAuthorizationInterrupts(interrupt);\n }\n if (err instanceof Auth0Interrupt) {\n this.credentialsStore.delete(credentialsNS, \"credential\");\n return this.handleAuthorizationInterrupts(err);\n }\n throw err;\n }\n });\n };\n }\n}\n"]}
|
|
@@ -42,6 +42,10 @@ export type TokenVaultAuthorizerParams<ToolExecuteArgs extends any[]> = {
|
|
|
42
42
|
* The connection name of the token vault provider.
|
|
43
43
|
*/
|
|
44
44
|
connection: string;
|
|
45
|
+
/**
|
|
46
|
+
* Additional authorization parameters to be passed during token acquisition.
|
|
47
|
+
*/
|
|
48
|
+
authorizationParams?: Record<string, string>;
|
|
45
49
|
/**
|
|
46
50
|
* AuthContext defines the scope of credential sharing:
|
|
47
51
|
* - "tool-call": Credentials are valid only for a single invocation of the tool.
|
|
@@ -53,7 +57,7 @@ export type TokenVaultAuthorizerParams<ToolExecuteArgs extends any[]> = {
|
|
|
53
57
|
*/
|
|
54
58
|
credentialsContext?: AuthContext;
|
|
55
59
|
/**
|
|
56
|
-
*
|
|
60
|
+
* A store used to store the authorization credentials according
|
|
57
61
|
* to the `credentialsContext` scope.
|
|
58
62
|
*/
|
|
59
63
|
store: Store;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenVaultAuthorizerParams.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/TokenVaultAuthorizerParams.ts"],"names":[],"mappings":"AAKA,MAAM,CAAN,IAAY,mBAcX;AAdD,WAAY,mBAAmB;IAC7B;;;;OAIG;IACH,oGAA6E,CAAA;IAE7E;;;;OAIG;IACH,kGAA2E,CAAA;AAC7E,CAAC,EAdW,mBAAmB,KAAnB,mBAAmB,QAc9B","sourcesContent":["import { TokenResponse } from \"../../credentials\";\nimport { AuthorizerToolParameter } from \"../../parameters\";\nimport { Store } from \"../../stores\";\nimport { AuthContext } from \"../context\";\n\nexport enum SUBJECT_TOKEN_TYPES {\n /**\n * Indicates that the token is an OAuth 2.0 refresh token issued by the given authorization server.\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8693#section-3-3.4 RFC 8693 Section 3-3.4}\n */\n SUBJECT_TYPE_REFRESH_TOKEN = \"urn:ietf:params:oauth:token-type:refresh_token\",\n\n /**\n * Indicates that the token is an OAuth 2.0 access token issued by the given authorization server.\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8693#section-3-3.2 RFC 8693 Section 3-3.2}\n */\n SUBJECT_TYPE_ACCESS_TOKEN = \"urn:ietf:params:oauth:token-type:access_token\",\n}\n\nexport type TokenVaultAuthorizerParams<ToolExecuteArgs extends any[]> =\n {\n /**\n * The Auth0 refresh token to exchange for an Token Vault access token.\n */\n refreshToken?: AuthorizerToolParameter<ToolExecuteArgs, string | undefined>;\n\n /**\n * The Token Vault access token if available in the tool context.\n * This can also be provided as a string exchange when exchanging an access token for a Token Vault access token.\n */\n accessToken?:\n | AuthorizerToolParameter<\n ToolExecuteArgs,\n TokenResponse | string | undefined\n >\n | string\n | undefined;\n\n /**\n * This is used to specify the type of token being requested from Auth0 during the OAuth 2.0 token exchange request.\n */\n subjectTokenType?: SUBJECT_TOKEN_TYPES | undefined;\n\n /**\n * Optional login hint to provide when exchanging an access or refresh token for a Token Vault access token.\n */\n loginHint?: AuthorizerToolParameter<ToolExecuteArgs, string | undefined>;\n\n /**\n * The scopes required in the access token of the token vault provider.\n */\n scopes: string[];\n\n /**\n * The connection name of the token vault provider.\n */\n connection: string;\n\n /**\n * AuthContext defines the scope of credential sharing:\n * - \"tool-call\": Credentials are valid only for a single invocation of the tool.\n * - \"tool\": Credentials are shared across multiple calls to the same tool within the same thread.\n * - \"thread\": Credentials are shared across all tools using the same authorizer within the current thread.\n * - \"agent\": Credentials are shared globally across all threads and tools in the agent.\n *\n * @default \"thread\"\n */\n credentialsContext?: AuthContext;\n\n /**\n *
|
|
1
|
+
{"version":3,"file":"TokenVaultAuthorizerParams.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/TokenVaultAuthorizerParams.ts"],"names":[],"mappings":"AAKA,MAAM,CAAN,IAAY,mBAcX;AAdD,WAAY,mBAAmB;IAC7B;;;;OAIG;IACH,oGAA6E,CAAA;IAE7E;;;;OAIG;IACH,kGAA2E,CAAA;AAC7E,CAAC,EAdW,mBAAmB,KAAnB,mBAAmB,QAc9B","sourcesContent":["import { TokenResponse } from \"../../credentials\";\nimport { AuthorizerToolParameter } from \"../../parameters\";\nimport { Store } from \"../../stores\";\nimport { AuthContext } from \"../context\";\n\nexport enum SUBJECT_TOKEN_TYPES {\n /**\n * Indicates that the token is an OAuth 2.0 refresh token issued by the given authorization server.\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8693#section-3-3.4 RFC 8693 Section 3-3.4}\n */\n SUBJECT_TYPE_REFRESH_TOKEN = \"urn:ietf:params:oauth:token-type:refresh_token\",\n\n /**\n * Indicates that the token is an OAuth 2.0 access token issued by the given authorization server.\n *\n * @see {@link https://datatracker.ietf.org/doc/html/rfc8693#section-3-3.2 RFC 8693 Section 3-3.2}\n */\n SUBJECT_TYPE_ACCESS_TOKEN = \"urn:ietf:params:oauth:token-type:access_token\",\n}\n\nexport type TokenVaultAuthorizerParams<ToolExecuteArgs extends any[]> =\n {\n /**\n * The Auth0 refresh token to exchange for an Token Vault access token.\n */\n refreshToken?: AuthorizerToolParameter<ToolExecuteArgs, string | undefined>;\n\n /**\n * The Token Vault access token if available in the tool context.\n * This can also be provided as a string exchange when exchanging an access token for a Token Vault access token.\n */\n accessToken?:\n | AuthorizerToolParameter<\n ToolExecuteArgs,\n TokenResponse | string | undefined\n >\n | string\n | undefined;\n\n /**\n * This is used to specify the type of token being requested from Auth0 during the OAuth 2.0 token exchange request.\n */\n subjectTokenType?: SUBJECT_TOKEN_TYPES | undefined;\n\n /**\n * Optional login hint to provide when exchanging an access or refresh token for a Token Vault access token.\n */\n loginHint?: AuthorizerToolParameter<ToolExecuteArgs, string | undefined>;\n\n /**\n * The scopes required in the access token of the token vault provider.\n */\n scopes: string[];\n\n /**\n * The connection name of the token vault provider.\n */\n connection: string;\n\n /**\n * Additional authorization parameters to be passed during token acquisition.\n */\n authorizationParams?: Record<string, string>;\n\n /**\n * AuthContext defines the scope of credential sharing:\n * - \"tool-call\": Credentials are valid only for a single invocation of the tool.\n * - \"tool\": Credentials are shared across multiple calls to the same tool within the same thread.\n * - \"thread\": Credentials are shared across all tools using the same authorizer within the current thread.\n * - \"agent\": Credentials are shared globally across all threads and tools in the agent.\n *\n * @default \"thread\"\n */\n credentialsContext?: AuthContext;\n\n /**\n * A store used to store the authorization credentials according\n * to the `credentialsContext` scope.\n */\n store: Store;\n };\n"]}
|
|
@@ -22,6 +22,10 @@ export type AsyncStorageValue = {
|
|
|
22
22
|
* The scopes that the current access token has.
|
|
23
23
|
*/
|
|
24
24
|
currentScopes?: string[];
|
|
25
|
+
/**
|
|
26
|
+
* Additional authorization parameters to be passed during token acquisition.
|
|
27
|
+
*/
|
|
28
|
+
authorizationParams?: Record<string, string>;
|
|
25
29
|
};
|
|
26
30
|
export declare const asyncLocalStorage: AsyncLocalStorage<AsyncStorageValue>;
|
|
27
31
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asyncLocalStorage.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/asyncLocalStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"asyncLocalStorage.js","sourceRoot":"","sources":["../../../../src/authorizers/token-vault/asyncLocalStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAmCnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,EAAqB,CAAC;AAE5E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,EAAE;IAC/C,MAAM,KAAK,GAAG,iBAAiB,CAAC,QAAQ,EAAE,CAAC;IAC3C,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,WAAW,CAAC;AAC5B,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,EAAE;IAC/C,MAAM,WAAW,GAAG,4BAA4B,EAAE,CAAC;IACnD,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,IAAI,eAAe,CAAC,sBAAsB,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,WAAW,CAAC,WAAW,CAAC;AACjC,CAAC,CAAC","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { TokenSet } from \"../../credentials\";\nimport { TokenVaultError } from \"../../interrupts\";\nimport { ToolCallContext } from \"../context\";\n\nexport type AsyncStorageValue = {\n /**\n * The Token Vault access token.\n */\n credentials?: TokenSet;\n\n /**\n * The tool execution context.\n */\n context: ToolCallContext;\n\n /**\n * The token vault name.\n */\n connection: string;\n\n /**\n * The scopes required to access the token vault.\n */\n scopes: string[];\n\n /**\n * The scopes that the current access token has.\n */\n currentScopes?: string[];\n\n /**\n * Additional authorization parameters to be passed during token acquisition.\n */\n authorizationParams?: Record<string, string>;\n};\n\nexport const asyncLocalStorage = new AsyncLocalStorage<AsyncStorageValue>();\n\n/**\n * Returns the entire tokenset for the current connection.\n *\n * Use `getAccessTokenFromTokenVault` if you only need the access token.\n *\n * @returns {TokenSet} The current token set.\n */\nexport const getCredentialsFromTokenVault = () => {\n const store = asyncLocalStorage.getStore();\n if (typeof store === \"undefined\") {\n throw new Error(\n \"The tool must be wrapped with the withTokenVault function.\"\n );\n }\n return store?.credentials;\n};\n\n/**\n *\n * Get the access token for the current connection.\n *\n * @returns The access token for the current connection.\n */\nexport const getAccessTokenFromTokenVault = () => {\n const credentials = getCredentialsFromTokenVault();\n if (!credentials || !credentials.accessToken) {\n throw new TokenVaultError(\"No credentials found\");\n }\n return credentials.accessToken;\n};\n"]}
|
|
@@ -5,7 +5,6 @@ import { Auth0Interrupt } from "./Auth0Interrupt";
|
|
|
5
5
|
* Throw this error if the service returns Unauthorized for the current access token.
|
|
6
6
|
*/
|
|
7
7
|
export declare class TokenVaultInterrupt extends Auth0Interrupt {
|
|
8
|
-
behavior: "resume" | "reload";
|
|
9
8
|
/**
|
|
10
9
|
* The auth0 connection name.
|
|
11
10
|
*/
|
|
@@ -20,8 +19,19 @@ export declare class TokenVaultInterrupt extends Auth0Interrupt {
|
|
|
20
19
|
* This is the list of scopes that will be used to request a new Access Token.
|
|
21
20
|
*/
|
|
22
21
|
readonly requiredScopes: string[];
|
|
22
|
+
/**
|
|
23
|
+
* Additional authorization parameters to be passed during token acquisition.
|
|
24
|
+
*/
|
|
25
|
+
readonly authorizationParams: Record<string, string>;
|
|
26
|
+
readonly behavior: "resume" | "reload";
|
|
23
27
|
static code: "TOKEN_VAULT_ERROR";
|
|
24
|
-
constructor(message: string,
|
|
28
|
+
constructor(message: string, params: {
|
|
29
|
+
connection: string;
|
|
30
|
+
scopes: string[];
|
|
31
|
+
requiredScopes: string[];
|
|
32
|
+
authorizationParams?: Record<string, string>;
|
|
33
|
+
behavior?: "resume" | "reload";
|
|
34
|
+
});
|
|
25
35
|
}
|
|
26
36
|
/**
|
|
27
37
|
* Error thrown when a tool call requires an access token for an external service.
|
|
@@ -5,12 +5,14 @@ import { Auth0Interrupt } from "./Auth0Interrupt";
|
|
|
5
5
|
* Throw this error if the service returns Unauthorized for the current access token.
|
|
6
6
|
*/
|
|
7
7
|
export class TokenVaultInterrupt extends Auth0Interrupt {
|
|
8
|
-
constructor(message,
|
|
8
|
+
constructor(message, params) {
|
|
9
|
+
var _a, _b;
|
|
9
10
|
super(message, TokenVaultInterrupt.code);
|
|
10
|
-
this.
|
|
11
|
-
this.
|
|
12
|
-
this.
|
|
13
|
-
this.
|
|
11
|
+
this.connection = params.connection;
|
|
12
|
+
this.scopes = params.scopes;
|
|
13
|
+
this.requiredScopes = params.requiredScopes;
|
|
14
|
+
this.authorizationParams = { ...((_a = params.authorizationParams) !== null && _a !== void 0 ? _a : {}) };
|
|
15
|
+
this.behavior = (_b = params.behavior) !== null && _b !== void 0 ? _b : "resume";
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
18
|
TokenVaultInterrupt.code = "TOKEN_VAULT_ERROR";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenVaultInterrupt.js","sourceRoot":"","sources":["../../../src/interrupts/TokenVaultInterrupt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;GAIG;AACH,MAAM,OAAO,mBAAoB,SAAQ,cAAc;
|
|
1
|
+
{"version":3,"file":"TokenVaultInterrupt.js","sourceRoot":"","sources":["../../../src/interrupts/TokenVaultInterrupt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;GAIG;AACH,MAAM,OAAO,mBAAoB,SAAQ,cAAc;IA2BrD,YAAY,OAAe,EAAE,MAM5B;;QACC,KAAK,CAAC,OAAO,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAC5C,IAAI,CAAC,mBAAmB,GAAG,EAAE,GAAG,CAAC,MAAA,MAAM,CAAC,mBAAmB,mCAAI,EAAE,CAAC,EAAE,CAAC;QACrE,IAAI,CAAC,QAAQ,GAAG,MAAA,MAAM,CAAC,QAAQ,mCAAI,QAAQ,CAAC;IAC9C,CAAC;;AAfa,wBAAI,GAAG,mBAA4B,CAAC;AAkBpD;;;;GAIG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;CACF","sourcesContent":["import { Auth0Interrupt } from \"./Auth0Interrupt\";\n\n/**\n * Error thrown when a tool call requires an access token for an external service.\n *\n * Throw this error if the service returns Unauthorized for the current access token.\n */\nexport class TokenVaultInterrupt extends Auth0Interrupt {\n /**\n * The auth0 connection name.\n */\n public readonly connection: string;\n\n /**\n * The scopes required to access the external service as stated\n * in the authorizer.\n */\n public readonly scopes: string[];\n\n /**\n * The union between the current scopes of the Access Token plus the required scopes.\n * This is the list of scopes that will be used to request a new Access Token.\n */\n public readonly requiredScopes: string[];\n\n /**\n * Additional authorization parameters to be passed during token acquisition.\n */\n public readonly authorizationParams: Record<string, string>;\n\n public readonly behavior: \"resume\" | \"reload\";\n\n public static code = \"TOKEN_VAULT_ERROR\" as const;\n\n constructor(message: string, params: {\n connection: string;\n scopes: string[];\n requiredScopes: string[];\n authorizationParams?: Record<string, string>;\n behavior?: \"resume\" | \"reload\";\n }) {\n super(message, TokenVaultInterrupt.code);\n this.connection = params.connection;\n this.scopes = params.scopes;\n this.requiredScopes = params.requiredScopes;\n this.authorizationParams = { ...(params.authorizationParams ?? {}) };\n this.behavior = params.behavior ?? \"resume\";\n }\n}\n\n/**\n * Error thrown when a tool call requires an access token for an external service.\n *\n * The authorizer will automatically convert this class of error to TokenVaultInterrupt.\n */\nexport class TokenVaultError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n"]}
|