Inspiration

AI agents are rapidly gaining capabilities to act on behalf of users: sending emails, creating calendar events, managing code repositories. However, most agent frameworks treat all actions equally, granting the same level of access regardless of risk. One prompt injection and your agent sends emails to your entire contact list. We built Shekara to fix this.

What it does

Shekara ("шекара" - "boundary" in Kazakh) is a security-first AI agent that classifies every tool call by risk before execution using a 4-tier authorization model:

  • Tier C (1.0–2.0): Silent execution list calendar events, search emails
  • Tier B (2.5–4.0): Intent preview + user consent create events, send emails
  • Tier A (4.5–8.0): Step-up authentication merge PRs, bulk operations
  • Tier S (8.5+): CIBA async approval delete repositories

Risk is scored as Severity (1-5) × Context Multiplier (1.0-2.5), where multipliers escalate for PII detection (×1.5), cross-service chains (×2.0), and bulk operations (×2.5).

The agent connects to Google Calendar, Gmail, and GitHub through Auth0 Token Vault with per-tool scope isolation. Every action is logged to a transparent audit trail with PII redaction.

How we built it

  • Frontend: Next.js 16 with Auth0 v4 middleware, React 19, dark theme UI with risk badges
  • Backend: FastAPI + LangGraph ReAct agent with interrupt/resume for consent flows
  • Auth: Auth0 Token Vault for scoped token exchange per federated connection
  • LLM: OpenAI GPT-4o-mini for tool selection and response generation
  • Security: OWASP LLM Top 10 mitigations including prompt injection sanitizer

Challenges we ran into

Auth0's Token Exchange grant returned "Federated connection Refresh Token not found" despite the token existing in the user profile. After instrumenting the SDK's HTTP layer, we traced the issue to a tenant-level Token Exchange configuration. We solved it by implementing a hybrid authorization architecture: a Management API fallback that securely extracts federated tokens via /api/v2/users/{user_id} when standard Token Exchange fails.

What we learned

Token Vault's scope isolation is the right abstraction for AI agent authorization. The LangGraph interrupt/resume mechanism pairs naturally with Token Vault's consent flow. We also discovered that error messages in the Token Exchange flow could be more descriptive to help developers distinguish configuration issues from missing tokens.

What's next for Shekara

  • Step-up authentication for Tier A actions via Auth0 MFA
  • CIBA async approval flow for Tier S critical actions
  • Multi-agent scope isolation with sub-agent token boundaries
  • Production deployment with token caching and rate limiting

Blog Post: Building a Secure AI Agent with Auth0 Token Vault

What Token Vault Gets Right

Token Vault's core abstraction is scope isolation: each tool in our agent receives only the OAuth scopes it needs. list_upcoming_events gets calendar.readonly. gmail_send gets gmail.send. If one tool is compromised through prompt injection, the blast radius is contained to that single scope. This is exactly the kind of least-privilege enforcement that production AI agents require.

The integration with LangGraph's interrupt/resume mechanism is particularly elegant. When Shekara's agent needs Google Calendar access for the first time, Token Vault raises an interrupt. LangGraph pauses execution. The frontend renders an authorization card showing the requested scopes. The user consents. LangGraph resumes from the exact checkpoint.

What We Discovered

During development, we encountered an issue with Token Vault's Token Exchange grant type. Despite correctly configuring the Token Vault grant in the application settings and verifying that the Google refresh token existed in the user's identity profile (confirmed via the Management API), the exchange endpoint consistently returned 401 Unauthorized with the message "Federated connection Refresh Token not found."

The diagnostic process involved instrumenting the auth0-ai-langchain SDK's HTTP requests to capture the exact payload sent to /oauth/token. The request format was correct. The error appeared to be a tenant-level configuration issue rather than a client-side bug.

Our Solution: Management API Fallback

Rather than abandoning Token Vault, we implemented a hybrid authorization architecture. When standard Token Exchange fails, the backend falls back to a secure Management API flow:

  1. Exchange the user's Auth0 session refresh token for an access token
  2. Resolve the user identity via /userinfo
  3. Authenticate as a machine client via client_credentials
  4. Fetch the user's federated identity tokens directly via GET /api/v2/users/{user_id}

This approach maintains identical security guarantees: the Google token never reaches the frontend, and the Management API call is authenticated with credentials stored exclusively on the backend.

Recommendations for the Auth0 Community

  1. More descriptive error responses distinguishing "token not found" from "token exchange not configured"
  2. A diagnostic endpoint to verify Token Vault configuration before going live
  3. Documentation of the Management API fallback pattern for production resilience

Token Vault solves the right problem: giving AI agents scoped, revocable, user-controlled access to external services. The architecture is sound, and with incremental improvements to developer experience, it has the potential to become the standard authorization layer for agentic AI.

Built With

Share this project:

Updates