Your agent needs to pull data from Google Drive, post a summary to Slack, and create a Jira ticket. Simple request. But whose credentials does it use? Should it have permission to delete your entire Drive folder?
This authorization problem kills agent demos before they reach production. It's not about users logging into your agent (LangGraph Platform handles that). It's about your agent accessing other services on behalf of those users.
If you're building real agents, you've hit this wall. The question isn't "Who is this agent?" It's: "Can this agent, acting for this user, perform this action on this resource?"
This authorization complexity is exactly why we built Arcade. But first, let's understand the complete picture.
User Auth vs Agent Auth: Two Different Problems
Before diving into agent auth, let's clarify the two distinct challenges:
User Authentication (Handled by LangGraph Platform) This is about users proving who they are to access your agent. LangGraph Platform handles this well.
# LangGraph Platform verifies user identity
@auth.authenticate
async def authenticate(headers: dict) -> Auth.types.MinimalUserDict:
api_key = headers.get("x-api-key")
if not is_valid_key(api_key):
raise Auth.exceptions.HTTPException(status_code=401)
return {
"identity": "user-123", # Who is this user?
"is_authenticated": True # Are they allowed in?
}
Once authenticated, users can create threads, run agents, and access agent resources. LangGraph Platform manages this and makes user identity available throughout your agent via config["configuration"]["langgraph_auth_user"].
Agent Authorization (Handled by Arcade) But here's where it gets tricky. Your authenticated user asks the agent to "summarize last week's sales calls from Google Drive and post to #sales-team in Slack." Now your agent needs to:
- Connect to Google Drive (with what credentials?)
- Connect to Slack (with what permissions?)
- Do so safely (without access to everything)
- On behalf of the authenticated user
- Without creating security holes
This is agent auth. It's a completely different problem.
Why "Non-Human Identity" Misses the Point
Security vendors love buzzwords. "Non-Human identity" (NHI) is their latest. Here's the truth: agents aren't identities - they're applications acting on behalf of users.
Your agent is a client application that needs delegated access. It needs to access services not as some special new type of identity, but as an application acting for a specific user. The patterns for this have existed for almost two decades in OAuth.
The challenge isn't that agents are special. It's that the authorization complexity explodes when agents access multiple services dynamically.
Remember the real question: "Can this agent, acting for this user, perform this action on this resource?"
Why Agent Auth at the Tool Layer Matters
When your agent calls a tool, that's where security actually matters. You can't trust the agent's judgment about what it should and shouldn't be able to do. The authorization check needs to happen at the moment of action, with context about:
- Which agent is making the request
- On behalf of which user (from LangGraph Platform)
- What specific action they're trying to perform
- On what specific resource
- With what parameters
The rules for "can this agent send this Slack message" are different from "can this agent delete this Drive file." This is why agent auth couples tightly to tool execution (where the action happens).
The Two Naive Approaches (And Why They Fail)
Most teams start with one of two flawed agent auth approaches:
Approach 1: Service Accounts
"Let's create a service account for our agent with its own permissions!"
This seems logical, especially for RAG systems. Your agent needs company documents, so you create a service account with read access to the knowledge base. Simple, right?
Service accounts work well for backend processes, but they're overused in agent development because developers lacked better alternatives.
Service accounts create bypass vulnerabilities. Imagine your company has role-based access to documents. HR sees salary data, engineers see technical docs, sales sees customer data. But your RAG agent with its service account can see everything it was given access to. Now any user can ask the agent about any document, completely bypassing your existing access controls.
This is a common reason agents with killer demos don't make it to production - security teams (rightfully) shut them down when the bypass risk is flagged.
The alternative? Severely limited agents. Restrict service accounts to public information and your agent becomes glorified documentation. It can recite your FAQ but fails when someone asks "What's the status of my order?" - an useful question users actually care about.
Approach 2: Full User Permissions
"Fine, let's use the user's own credentials and permissions!"
This is more secure in theory - users can only access what they already have permission to see. But it's incredibly unsafe in practice.
I've watched Cursor try to delete my root directory. Thankfully, it didn't have sudo access. But do you want your agent to have full access to your email? Your entire Drive? Your production database?
Users might have permission to delete critical files or send emails to the entire company. That doesn't mean their agent should inherit those permissions without constraints. One hallucination or prompt injection away from disaster - security teams call this the "blast radius."
The Right Way: Just-in-Time, Least-Privileged Authorization
The solution requires three key principles:
1. Just-in-Time Authorization: Don't pre-authorize everything. When the agent needs Slack access, that's when you handle the OAuth flow. Users stay in control, authorizing only what's needed, when it's needed.
2. Least-Privileged Access: Even if a user can delete files in Drive, their agent should only get read access unless deletion is explicitly needed. This reduces the blast radius if something goes wrong. Define minimum required scopes for each tool.
3. Contextual Enforcement: Every tool call needs authorization checks. Can this specific agent, acting for this specific user, perform this specific action? The answer changes based on context.
Real-World Complexity
Here's what this actually means in practice:
Token Management: OAuth tokens expire. They need refreshing. Different services have different token lifetimes. Your agent might be mid-conversation when a token expires. You need to handle refresh flows without breaking the user experience.
Scale Problems: You need separate tokens for every combination of user × service × agent. User A using your sales agent to access Slack needs a different token than User A using your support agent. Scale this to 100 users, 10 services, and 5 agents, and you're managing 5,000 separate token relationships.
Dynamic Tool Authorization: Don't force users to pre-authorize every service upfront - they'll abandon the flow after 2-3 auth steps. Instead, handle OAuth just-in-time inside your agent loop. User asks about sales data? That's when you request Salesforce access.
Scope Granularity: Slack alone has dozens of OAuth scopes. Does your agent need chat:write or chat:write.public? What about files:read vs files:write? Get it wrong and your agent either can't function or has too much power.
How LangGraph Developers Can Solve This
You got into agent development to build intelligent workflows, not to manage OAuth tokens. The LangChain ecosystem gives you most of what you need: LangGraph for agent orchestration, LangGraph Platform for hosting and scaling, LangSmith for observability.
But there's a gap: the tool authorization layer.
To fill it, you'd need to build OAuth flows for every service (each with quirky differences despite OAuth being a "standard"). Token management across users and services. Authorization policies. Refresh logic. Security controls.
Many teams start down this path. Months later, they're still debugging OAuth edge cases instead of shipping agents.
Or you can use Arcade.
The Implementation Reality
To implement proper just-in-time authorization yourself, you'd need to build:
- OAuth flow management (initiation, callbacks, state handling)
- Token lifecycle management across user/agent/service combinations
- Authorization policy enforcement at the tool layer
- Token refresh logic that doesn't break agent execution
- Error handling for expired/revoked tokens
- Audit logging for compliance
That's thousands of lines of complex infrastructure code before you even get to your agent logic.
Here's what the same functionality looks like with Arcade:
# Get the authenticated user from LangGraph Platform
user_id = config["configuration"]["langgraph_auth_user"]["identity"]
# All the complexity above, handled by Arcade
result = arcade_client.tools.execute(
tool_name="Slack.SendMessage",
input={
"channel": "#general",
"message": "Hello World!"
},
user_id=user_id # Who the agent is acting for
)
What happens behind the scenes:
- LangGraph Platform has already authenticated the user
- Your agent sends the request to Arcade
- Arcade checks if your agent has valid OAuth tokens for Slack for this user
- If not, Arcade initiates the OAuth flow (inside your agent loop)
- Your agent authenticates to Slack with limited scopes
- Arcade executes the action with proper authorization and logging
- Arcade manages these tokens for future use
You can use prebuilt tools from our library or build your own with our Tool Development Kit. You set up the tools. Arcade ensures least-privileged access. Your users stay in control. Your agent stays functional. Your security team stays happy.
All designed to work smoothly with the entire LangChain ecosystem.
The Bottom Line
Agent auth is about how your agent accesses other services on behalf of users. It's related to, but distinct from, user auth which focuses on how users access the agent.
The naive approaches - service accounts and full user credentials - create security vulnerabilities or safety gaps. The right approach uses OAuth-based agent authentication with just-in-time, least-privileged access.
Arcade and LangGraph Platform handle this complexity for developers, letting your LangGraph agents securely access internal and external services while keeping authenticated users in control.
Start Building Secure Agents Today
Here's your next step: Add secure external access to your LangGraph agent in under 10 minutes.
- Start with your existing LangGraph agent (with LangGraph Platform user auth already set up)
- Sign up for Arcade at arcade.dev - no credit card required
- Follow our LangGraph integration guide to add Arcade to your agent
- Add your first tool (we recommend starting with Slack or Google Drive)
- Test the OAuth flow - watch your agent authenticate to external services properly
Ready to ship secure agents?
Stop building OAuth infrastructure. Start building agents that actually work.
Already using LangGraph? Our LangGraph guide takes 10 minutes.