Skip to content

Conversation

@jcenturion
Copy link

By submitting a PR to this repository, you agree to the terms within the Auth0 Code of Conduct. Please see the contributing guidelines for how to create and submit a high-quality PR for this repo.

Description

Describe the purpose of this PR along with any background information and the impacts of the proposed change. For the benefit of the community, please do not assume prior context.

Provide details that support your chosen implementation, including: breaking changes, alternatives considered, changes to the API, etc.

If the UI is being changed, please provide screenshots.

References

Include any links supporting this change such as a:

  • GitHub Issue/PR number addressed or fixed
  • Auth0 Community post
  • StackOverflow post
  • Support forum thread
  • Related pull requests/issues from other repos

If there are no references, simply delete this section.

Testing

Describe how this can be tested by reviewers. Be specific about anything not tested and reasons why. If this library has unit and/or integration testing, tests should be added for new functionality and existing tests should complete without errors.

Please include any manual steps for testing end-to-end or functionality not covered by unit/integration tests.

Also include details of the environment this PR was developed in (language/platform/browser version).

  • This change adds test coverage for new/changed/fixed functionality

Checklist

  • I have added documentation for new/changed functionality in this PR or in auth0.com/docs
  • All active GitHub checks for tests, formatting, and security are passing
  • The correct base branch is being used, if not the default branch

@jcenturion jcenturion changed the title updating AI [WIP] Updating AI Sep 16, 2025
Comment on lines +30 to +41
<Frame>
<img
className="hidden dark:block"
src="/img/intro/web_applications_with_spa_diagram_dark.png"
alt="Token Vault using Access Tokens"
/>
<img
className="block dark:hidden"
src="/img/intro/web_applications_with_spa_diagram_light.png"
alt="Token Vault using Access Tokens"
/>
</Frame>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

@@ -0,0 +1,139 @@
---
title: Calling third-party Party APIs
Copy link
Contributor

@priley86 priley86 Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"-party Party" 😸

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seeing a lot of instances, please find/replace :)

Comment on lines +7 to +9
Clone <Icon icon="github" iconType="solid" /> <a href={`https://github.com/${repository}.git`} target="_blank" rel="noreferrer" className="link">{repository}</a> and navigate to <code>{folderPath}</code> directory.
</div>
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be able to reference the DownloadQuickstartButton now inside of here i imagine?

export const DownloadQuickstartButton = ({

We have this feature recently added now w/ Download Sample button on these.

- Integrate with an AI agent to call Google APIs.
</Card>

<Prerequisites />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a lot of these Prerequisites have recently been adjusted, this one for example should pass these props:

<Prerequisites
createAuth0ApplicationStep={{
enableTokenVaultGrant: true,
}}
createAuth0ApiStep={{}}
createResourceServerClientStep={{}}
/>

Lets double check them..

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately these will also be conditional right now depending on framework selection, as our langchain-FastAPI / python example is using FCRT / embedded (precompiled) agent flow still.

<Prerequisites
createAuth0ApplicationStep={{
applicationType: "Regular Web Applications",
callbackUrl: "http://localhost:8000/api/auth/callback",
logoutUrl: "http://localhost:5173",
enableTokenVaultGrant: true,
}}
/>

So i suppose suggestion here would be to keep the contents here and below within the LangChainNextjsCallOthersApi / FastApiCallOthersApi components respectively.

samples today:

https://auth0.com/ai/docs/get-started/call-others-apis-on-users-behalf#langgraph-js-%2B-next-js

https://auth0.com/ai/docs/get-started/call-others-apis-on-users-behalf#langgraph-%2B-fastapi

Comment on lines +34 to +38
# LANGGRAPH
LANGGRAPH_API_URL=http://localhost:54367
LANGCHAIN_CALLBACKS_BACKGROUND=false
```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file is missing some important elements. Let's rebase it once more...e.g.:

AUTH0_CUSTOM_API_CLIENT_ID="{yourCustomApiClientId}"
AUTH0_CUSTOM_API_CLIENT_SECRET="{yourCustomApiClientSecret}"

},
});
## or Follow manual steps

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest re-adding <Prerequisites ... /> in these files

Comment on lines +104 to +113
...body,
config: {
configurable: {
_credentials: {
refreshToken: await getRefreshToken(),
},
},
},
};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets re-add snippets to match existing please, e.g.:

export const { GET, POST, PUT, PATCH, DELETE, OPTIONS, runtime } =
  initApiPassthrough({
    apiUrl: process.env.LANGGRAPH_API_URL,
    baseRoute: "chat/",
    headers: async () => {
      const accessToken = await getAccessToken();
      return {
        Authorization: `Bearer ${accessToken}`,
        ...

Comment on lines -278 to +171
if (!token) {
throw new HTTPException(401, {
message:
"Authorization header format must be of the form: Bearer <token>",
});
}

if (token) {
try {
// Verify the JWT using Auth0 JWKS
const { payload } = await jwtVerify(token, JWKS, {
issuer: `https://${AUTH0_DOMAIN}/`,
audience: AUTH0_AUDIENCE,
});
Add a new file, `src/components/auth0-ai/FederatedConnections/FederatedConnectionInterruptHandler.tsx`, with the following code:

console.log("✅ Auth0 JWT payload resolved!", payload);

// Return the verified payload - this becomes available in graph nodes
return {
identity: payload.sub!,
email: payload.email as string,
permissions:
typeof payload.scope === "string" ? payload.scope.split(" ") : [],
auth_type: "auth0",
// include the access token for use with Auth0 Token Vault exchanges by tools
getRawAccessToken: () => token,
// Add any other claims you need
...payload,
};
} catch (jwtError) {
console.log(
"Auth0 JWT validation failed:",
jwtError instanceof Error ? jwtError.message : "Unknown error"
);
throw new HTTPException(401, {
message: "Invalid Authorization token provided.",
});
}
}
});

export { auth as authHandler };
```
### Use access token to call APIs from a tool
Once the user is authenticated, you can fetch an access token from Token Vault using the Auth0 AI SDK. In this example, we fetch an access token for a Google social connection.
Once you've obtained the access token for a connection, you can use it with an AI agent to fetch data during a tool call and provide contextual data in its response.
This example uses `GmailSearch` from the `@langchain/community` tools. This tool will use the access token provided by Token Vault to query for emails.
```ts src/lib/tools/gmail-seatch.ts wrap lines highlight={10}
//...
import { getAccessTokenFromTokenVault } from "@auth0/ai-langchain";
import { GmailSearch } from "@langchain/community/tools/gmail";

import { withGmailSearch } from "../../lib/auth0-ai";

export const gmailSearchTool = withGmailSearch(
new GmailSearch({
credentials: {
accessToken: async () => getAccessTokenFromTokenVault(),
},
})
);
```
Update your tool call to request an access token, as shown in the following example:
```ts src/lib/agent.ts wrap lines highlight={2,10-13}
//...
import { gmailSearchTool } from './tools/gmail-search';

//... existing code

const tools = [gmailSearchTool];
//... existing code
export const agent = createReactAgent({
llm,
tools: new ToolNode(tools, {
// Error handler must be disabled in order to trigger interruptions from within tools.
handleToolErrors: false,
}),
// Modify the stock prompt in the prebuilt agent.
prompt: AGENT_SYSTEM_TEMPLATE,
store,
checkpointer,
});
```
### Add step-up authorization
When you try to use the tool, the application requests any additional Google scopes that are required but not yet authorized. This process is called step-up authorization.
To implement, install the Auth0 AI Components for Next.js SDK to get the required UI components:
```bash wrap lines
npx @auth0/ai-components add TokenVault
```
Add a new file, `src/components/auth0-ai/TokenVault/TokenVaultInterruptHandler.tsx`, with the following code:
```tsx src/components/auth0-ai/TokenVault/TokenVaultInterruptHandler.tsx wrap lines
import { TokenVaultInterrupt } from "@auth0/ai/interrupts";
import type { Interrupt } from "@langchain/langgraph-sdk";

import { TokenVaultConsent } from "@/components/auth0-ai/TokenVault";

interface TokenVaultInterruptHandlerProps {
interrupt: Interrupt | undefined | null;
onFinish: () => void;
}

export function TokenVaultInterruptHandler({
interrupt,
onFinish,
}: TokenVaultInterruptHandlerProps) {
if (
!interrupt ||
!TokenVaultInterrupt.isInterrupt(interrupt.value)
) {
return null;
}

return (
<div key={interrupt.ns?.join("")} className="whitespace-pre-wrap">
<TokenVaultConsent
mode="popup"
interrupt={interrupt.value}
onFinish={onFinish}
connectWidget={{
title: "Authorization Required.",
description: interrupt.value.message,
action: { label: "Authorize" },
}}
/>
</div>
);
}
```
Now, update your chat window code to include the `TokenVaultInterruptHandler` component, for example:
```tsx src/components/chat-window.tsx wrap lines highlight={2,3,8-19,36-38}
//...
import { TokenVaultInterruptHandler } from '@/components/auth0-ai/TokenVault/TokenVaultInterruptHandler';

//... existing code
export function ChatWindow(props: {
//... existing code
}) {
const [threadId, setThreadId] = useQueryState('threadId');
const [input, setInput] = useState('');
const chat = useStream({
apiUrl: props.endpoint,
assistantId: 'agent',
threadId,
onThreadId: setThreadId,
onError: (e: any) => {
console.error('Error: ', e);
toast.error(`Error while processing your request`, { description: e.message });
},
});
//... existing code
return (
<StickToBottom>
<StickyToBottomContent
className="absolute inset-0"
contentClassName="py-8 px-2"
content={
chat.messages.length === 0 ? (
<div>{props.emptyStateComponent}</div>
) : (
<>
<ChatMessages
aiEmoji={props.emoji}
messages={chat.messages}
emptyStateComponent={props.emptyStateComponent}
/>
<div className="flex flex-col max-w-[768px] mx-auto pb-12 w-full">
<TokenVaultInterruptHandler interrupt={chat.interrupt} onFinish={() => chat.submit(null)} />
</div>
</>
)
}
{/* ... existing code */}
></StickyToBottomContent>
</StickToBottom>
);
}
```
Now when step-up authorization is required, the user will see a prompt in the chat window asking them to authorize.
```tsx src/components/auth0-ai/FederatedConnections/FederatedConnectionInterruptHandler.tsx wrap lines
import { FederatedConnectionInterrupt } from "@auth0/ai/interrupts";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do a quick find for all existing FederatedConnectionInterruptHandler / FederatedConnectionInterrupt refs plz 🙏 - these are all adjusted after naming update

Start your application. If you are already logged in, make sure to log out and log back in using Google. Then, ask your AI agent to fetch emails from your Gmail account!

That's it! You successfully integrated third-party API access using Token Vault into your app.
</Step>
Copy link
Contributor

@priley86 priley86 Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Largely, i think this file should just mimic existing template in main... w/ any new semantic elements you still need. Seems just needs a fresh rebase/re-review.


Create a file at `app/core/auth0_ai.py` to instantiate the Auth0 AI SDK client:
## or Follow manual steps

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest adding Prerequisites within here (same advice w/ all get-started snippets)

)
)

with_calendar_access = auth0_ai.with_federated_connection(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one needs fresh rebase/update too... seeing with_federated_connection and a bunch of old refs.

@priley86
Copy link
Contributor

priley86 commented Oct 24, 2025

Really like this navigation restructuring (and think it looks vastly better from my standpoint). 👏

One minor annoyance i'm now noting is then when changing Agent framworks using the left-hand nav selector, it seems to also always change back to the Overview -> "What is Calling APIs" navigation, instead of staying on the current navigation. Do we have any control of this? Seems a minor minor thing and figure i would ask.
Screenshot 2025-10-24 at 3 57 49 PM

(after framework navigation selection from LangGraph -> AI SDK)

Screenshot 2025-10-24 at 3 55 12 PM

Should not be blocking at all i.m.o., just noting it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants