Skip to main content

Auth0 AI for AI SDK

This SDK provides building blocks for using Auth0 for AI Agents with the AI SDK. It includes tools for implementing asynchronous user authentication, tools for getting access tokens for third-party connections, building blocks to handle interrupts, and OpenFGA-based tool authorizers. It supports:
  • Tools for implementing asynchronous user authentication
  • Tools for getting access tokens for third-party connections
  • OpenFGA-based tool authorizers
npm install @auth0/ai-vercel
Below are examples that demonstrate how to integrate Auth0’s token vault and authorization flows with AI tools. You’ll see how to:
  • Use a token vault to call third-party APIs on behalf of the user
  • Use Client-Initiated Backchannel Authentication (CIBA) for consent flows
For more examples, click here.
Token Vault allows you to exchange refresh tokens for access tokens for third-party APIs. This is useful when you want to use a token vault (like Google, Facebook, etc.) to authenticate users and then use the access token to call the API on behalf of the user.First initialize the Token Vault Authorizer as follows:
import { auth0 } from "./auth0";

export const withGoogleAccess = auth0AI.withTokenVault({
  // A function to retrieve the refresh token of the context.
  refreshToken: async () => {
    const session = await auth0.getSession();
    const refreshToken = session?.tokenSet.refreshToken!;
    return refreshToken;
  },
  // The connection name.
  connection: 'google-oauth2',
  // The scopes to request.
  scopes: ["https://www.googleapis.com/auth/calendar.freebusy"],
});
Then use the withGoogleAccess to wrap the tool and use getAccessTokenFromTokenVault from the SDK to get the access token.
import { tool } from "ai";
import { getAccessTokenFromTokenVault } from "@auth0/ai-vercel";
import { TokenVaultError } from "@auth0/ai/interrupts";
import { addHours } from "date-fns";

export const checkUsersCalendar = withGoogleAccess(
  tool({
    description:
      "Check user availability on a given date time on their calendar",
    parameters: z.object({
      date: z.coerce.date(),
    }),
    execute: async ({ date }) => {
      const accessToken = getAccessTokenFromTokenVault();
      const url = "https://www.googleapis.com/calendar/v3/freeBusy";
      const body = JSON.stringify({
        timeMin: date,
        timeMax: addHours(date, 1),
        timeZone: "UTC",
        items: [{ id: "primary" }],
      });

      const response = await fetch(url, {
        method: "POST",
        headers: {
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": "application/json",
        },
        body,
      });

      if (!response.ok) {
        if (response.status === 401) {
          throw new TokenVaultError(
            `Authorization required to access the Token Vault`
          );
        }
        throw new Error(
          `Invalid response from Google Calendar API: ${
            response.status
          } - ${await response.text()}`
        );
      }

      const busyResp = await response.json();
      return { available: busyResp.calendars.primary.busy.length === 0 };
    },
  })
);
CIBA (Client-Initiated Backchannel Authentication) enables secure, user-in-the-loop authentication for sensitive operations. This flow allows you to request user authorization asynchronously and resume execution once authorization is granted.
import { auth0 } from "./auth0";

export const buyStockAuthorizer = auth0AI.withAsyncAuthorization({
  // Same parameters passed to the tool execute function
  userID: (params: { userID: string }, ctx) => params.userID,

  // The message the user will see on the notification
  bindingMessage: async ({ qty , ticker }) => {
    return `Confirm the purchase of ${qty} ${ticker}`;
  },
  // Expiration for this request in seconds (default=300s)
  requestedExpiry: 300,
  // The scopes and audience to request
  scope: "openid stock:trade",
  audience: "http://localhost:8081",
});
Then wrap the tool as follows:
export const purchaseStock = buyStockAuthorizer({
  description: "Execute a stock purchase given stock ticker and quantity",
  parameters: z.object({
    tradeID: z
      .string()
      .uuid()
      .describe("The unique identifier for the trade provided by the user"),
    userID: z
      .string()
      .describe("The user ID of the user who created the conditional trade"),
    ticker: z.string().describe("The stock ticker to trade"),
    qty: z
      .number()
      .int()
      .positive()
      .describe("The quantity of shares to trade"),
  }),
  execute: async ({
    userID,
    ticker,
    qty,
  }: {
    userID: string;
    ticker: string;
    qty: number;
  }): Promise<string> => {
    const credentials = getAsyncAuthorizationCredentials();
    // Use credentials.accessToken to call the stock API.
    return `Just bought ${qty} shares of ${ticker} for ${userID}`;
  },
});