How to Build an AI Agent with Per-User OAuth Access [Full Handbook]

When your AI agent serves more than one person, every tool call must answer: who's the agent acting for? Let's learn how to solve this by building an AI agent that connects with Slack and GitHub.


A Slack read uses that user's workspace. A GitHub issue is created as that user, in a repository they can access. An agent can make the wrong call, but it must never act with the wrong user's access.


The fix has two parts, and both appear in the first half of this tutorial:


  1. Each user grants access separately. Alice authorizes Slack for herself. Bob authorizes it for himself.

    1. Your agent passes an identifier, not a token. A string like [email protected] selects whose grant to use. One function turns it into a token at the moment of the call, and that token never reaches your model inputs, your tool schemas, or your logs.

    2. Most agent tutorials stop before either point. They hand you an API key, wire up one function, and the model calls it. The design works until a second person shows up.


      To make the pattern concrete, you'll build a command-line agent that watches a Slack channel, decides on its own which messages describe real work, files a GitHub issue for those, and replies in the Slack thread with the issue link. Every call runs as one user's own OAuth grant.


      You'll write the OAuth flow yourself: the consent redirect, the state check, the token exchange, an encrypted store, and the refresh path. None of it is long, and seeing it whole is what makes the identity argument checkable instead of a claim you take on faith.


      Two topics stay out of scope here: we won't cover Model Context Protocol servers or voice or realtime hosts. The identity pattern holds in both settings, but the surrounding plumbing deserves its own article.


      Table of Contents


      • [What You'll Build]

      via FreeCodeCamp

Related