Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Delay the AI Overlords: How OAuth and OpenFGA C...

Delay the AI Overlords: How OAuth and OpenFGA Can Keep Your AI Agents from Going Rogue

What happens when your AI agents bypass controls, abuse tool permissions, or hallucinate sensitive data from RAG pipelines? The path to an “AI Overlord” starts with one unguarded API call.

In this talk, you’ll learn how to weaponize OAuth2, OpenFGA, and battle-tested authorization strategies to keep AI agents in check. We’ll cover:

✅ Role-Based Shackles: Enforce least privilege for AI toolchains using RBAC and Fine-Grained Authorization (FGA).
✅ Credential-Free Tool Calls: Fortify API integrations with OAuth2 token exchange, letting agents act on behalf of users without ever touching raw credentials.
✅ RAG Jailbreaking Fixes: Embed FGA directly into retrieval workflows to prevent agents from leaking confidential data
✅ Human Guardrails: Leverage asynchronous authorization workflows to audit high-stakes actions.

Forget sci-fi doomsday scenarios—we’re tackling today’s threats. Walk away with knowledge to armor your AI agents against rogue behavior and security nightmares.

Avatar for Deepu K Sasidharan

Deepu K Sasidharan

October 01, 2025
Tweet

More Decks by Deepu K Sasidharan

Other Decks in Programming

Transcript

  1. Delay the AI Overlords How OAuth and OpenFGA Can Keep

    Your AI Agents from Going Rogue Deepu K Sasidharan
  2. @auth0 | @deepu105 | deepu.tech ➔ JHipster co-chair ➔ Java

    Champion ➔ Creator of KDash, JDL Studio, JWT UI ➔ Developer Advocate @ Auth0 ➔ OSS aficionado, polyglot dev, author, speaker Hi, I’m Deepu K Sasidharan @[email protected] deepu.tech @deepu105.bsky.social deepu05
  3. @auth0 | @deepu105 | deepu.tech The Current State of AI

    Security Agents, RAG and everything in between
  4. @auth0 | @deepu105 | deepu.tech • Prompt Injection • Sensitive

    Information Disclosure • Supply Chain Attacks • Data and Model Poisoning • Improper Output Handling • Excessive Agency • System Prompt Leakage • Vector and Embedding Weaknesses • Misinformation • Unbounded Consumption OWASP LLM top 10
  5. @auth0 | @deepu105 | deepu.tech • Prompt Injection • Sensitive

    Information Disclosure • Supply Chain Attacks • Data and Model Poisoning • Improper Output Handling • Excessive Agency • System Prompt Leakage • Vector and Embedding Weaknesses • Misinformation • Unbounded Consumption OWASP LLM top 10
  6. @auth0 | @deepu105 | deepu.tech • Prompt Injection • Sensitive

    Information Disclosure • Supply Chain Attacks • Data and Model Poisoning • Improper Output Handling • Excessive Agency • System Prompt Leakage • Vector and Embedding Weaknesses • Misinformation • Unbounded Consumption OWASP LLM top 10
  7. @auth0 | @deepu105 | deepu.tech Security Challenges Dynamic Context Complex

    Relationships Granular Control Performance Requirements
  8. @auth0 | @deepu105 | deepu.tech How does it work? FGA

    Store Authorization Model Relationship Tuples Check/ListObject/ListUser endpoints
  9. @auth0 | @deepu105 | deepu.tech // Authorization Model model schema

    1.1 type doc relations define viewer: [domain#member, user] define commenter: [domain#member, user] define editor: [domain#member, user] define owner: [domain#member, user] define can_view: owner or viewer or editor or commenter type domain relations define member: [user] type user // Relationship Tuple [{ "user": "user:anne", "relation": "editor", "object": "doc:new-roadmap" }] FGA Model
  10. @auth0 | @deepu105 | deepu.tech export const getDocumentsTool = tool({

    description : 'Use the tool when user asks for anything from the knowledge base.' , parameters: z.object({ question: z.string().describe('the users question' ) }), execute: async ({ question }) => { const session = await auth0.getSession(); if (!session?.user) { return 'There is no user logged in.' ; } const retriever = FGAFilter.create({ buildQuery: (doc: DocumentWithScore ) => ({ user: `user:${session?.user?.email}`, object: `doc:${doc.documentId}`, relation: 'can_view', }), }); const documents = await findRelevantContent (question, 25); // filter docs based on FGA authorization const context = await retriever.filter(documents); return context; }, }); AuthZ for RAG with OpenFGA
  11. @auth0 | @deepu105 | deepu.tech export const someTool = tool({

    description: 'A custom tool.' , parameters: z.object({}), execute: async () => { const session = await auth0.getSession(); if (!session) { return 'There is no user logged in.' ; } const userRoles = getUserRoles(session); if (!userRoles.includes('can_use_tools' )) { return 'User does not have sufficient permissions for this tool.' ; } return "Successful tool action"; }, }); AuthZ with RBAC
  12. @auth0 | @deepu105 | deepu.tech export const buyStock = (context:

    Context) => { return auth0AI.withFGA({ buildQuery: async ({ ticker }) => { return { user: `user:${context.userId}`, object: `asset:${ticker}`, relation: "can_buy", }; }, onUnauthorized ({ ticker }) { return `The user is not allowed to buy ${ ticker}.`; }, tool({ description: "Use this tool to buy stock" , parameters: z.object({ ticker: z.string(), qty: z.number(), }), execute: async ({ ticker, qty }) => { return `Purchased ${qty} shares of ${ ticker}`; }, }) ); }; AuthZ with FGA
  13. @auth0 | @deepu105 | deepu.tech export const getInfoFromAPI = tool({

    description: 'Get information from my own API.' , parameters: z.object({}), execute: async () => { const session = await auth0.getSession(); if (!session) { return 'There is no user logged in.' ; } const response = await fetch(`https://my-own-api` , { headers: { Authorization: `Bearer ${session.tokenSet.accessToken}`, }, }); if (response.ok) { return { result: await response.json() }; } return "I couldn't verify your identity" ; }, }); Call First Party APIs with OAuth
  14. @auth0 | @deepu105 | deepu.tech // Connection for Google services

    export const withGoogleConnection = auth0AI.withTokenForConnection ({ connection : 'google-oauth2' , scopes: ['https://www.googleapis.com/auth/calendar.events' ], refreshToken : getRefreshToken , }); // Wrapped tool export const checkUsersCalendarTool = withGoogleConnection ( tool({ description : 'Check user availability on a given date time on their calendar' , parameters : z.object({ date: z.coerce.date() }), execute: async ({ date }) => { // Get the access token from Auth0 AI const accessToken = await getAccessToken (); // Google SDK const calendar = getGoogleCalendar (accessToken ); const response = await calendar .freebusy .query({ auth, requestBody : { timeMin: formatISO (date), timeMax: addHours (date, 1).toISOString (), timeZone : 'UTC', items: [{ id: 'primary' }], }, }); return response .data?.calendars ?.primary?.busy?.length, }; }, }), ); Call Third Party APIs With Auth0 Token Vault
  15. @auth0 | @deepu105 | deepu.tech export const withAsyncAuthorization = auth0AI.withAsyncUserConfirmation({

    userID: async () => { const user = await getUser(); return user?.sub as string; }, bindingMessage: async ({ product, qty }) => `Do you want to buy ${qty} of ${product}`, scopes: ['openid', 'product:buy'], audience: process.env['AUDIENCE']!, onUnauthorized: async (e: Error) => { if (e instanceof AccessDeniedInterrupt) { return 'The user has denied the request'; } return e.message; }, }); export const shopOnlineTool = withAsyncAuthorization( tool({ description: 'Tool to buy products online', parameters: z.object({ product: z.string(), qty: z.number() }), execute: async ({ product, qty, priceLimit }) => { const credentials = getCIBACredentials(); const accessToken = credentials?.accessToken; // Use access token to call first party APIs return `Ordering ${qty} ${product} with price limit ${priceLimit}`; }, }), ); Async AuthZ with Auth0