Skip to content

Jesut0ni/agentgate

Repository files navigation

AgentGate

OAuth for AI Agents — Auth & Permissions Platform

CI License: MIT PRs Welcome

AgentGate is the missing auth layer for AI agents. It gives developers scoped permissions, users consent controls, and everyone an audit trail.

This is an open-source project — contributions welcome! See CONTRIBUTING.md to get started.


The Problem

AI agents are increasingly acting on behalf of users — sending emails, creating PRs, managing CRMs, making payments. But there is no standard way to control what agents can do.

What's broken today:

  1. No scoped permissions. When you give an AI agent your API key, it gets full access. There's no way to say "you can read my emails but not send them."

  2. No user consent. Users have no visibility into what an agent is requesting access to, and no way to approve or deny specific capabilities.

  3. No audit trail. When an agent acts on your behalf, there's no centralized log of what it did, when, or whether it was authorized.

  4. No revocation. If you want to stop an agent from accessing your accounts, there's no standard "off switch" — you have to rotate API keys, breaking everything else.

  5. No policy enforcement. There's no way to say "this agent can only send 10 emails per hour" or "this agent can only operate during business hours."

This is the same problem OAuth solved for web apps in 2010 — but for AI agents. Every company deploying agents will need this.


The Solution

AgentGate provides a complete authorization layer between AI agents and the services they access:

┌──────────┐     ┌──────────────┐     ┌─────────────┐
│ AI Agent │────▶│  AgentGate   │────▶│  Your APIs  │
│          │◀────│ (Auth Layer) │◀────│  & Services │
└──────────┘     └──────────────┘     └─────────────┘
                       │
                  ┌────┴────┐
                  │  User   │
                  │ Consent │
                  └─────────┘

Core Capabilities

Feature Description
Scoped Permissions 28 predefined scopes across 10 categories (email, GitHub, CRM, payments, etc.). Agents only get what users approve.
Consent Flow OAuth-style consent screen where users see exactly what an agent wants to do, with risk-level indicators.
Token Management Short-lived JWTs (15 min) with refresh token rotation. Replay detection automatically revokes compromised token families.
Policy Engine Configurable rate limits, time windows, action allowlists/blocklists. Control agent behavior at scale.
Audit Logging Every agent action is logged with outcome (allowed/denied), the policy that blocked it, and full request metadata.
Instant Revocation Users revoke any agent's access with one click. All tokens invalidated immediately.

Architecture

agentgate/
├── packages/
│   ├── shared/     # Zod schemas, TypeScript types, scope catalog
│   ├── api/        # Hono REST API (core auth engine)
│   ├── web/        # Next.js dashboard + consent screen
│   └── sdk/        # TypeScript SDK for agent developers
├── .github/
│   └── workflows/  # CI/CD pipeline
└── docker-compose.yml

Tech Stack

  • API: Hono (TypeScript) on Node.js
  • Database: SQLite (dev) / PostgreSQL (production) via Drizzle ORM
  • Cache: In-memory (dev) / Redis (production)
  • Frontend: Next.js 15 + Tailwind CSS
  • Auth: JWT (HS256) via jose, Argon2 password hashing
  • Validation: Zod schemas shared between API and frontend

Data Model

developers ──┐
             ├── agents ──┐
users ───────┤            ├── consents ── tokens ── refresh_tokens
             │            │
             └── policies ┘
                          └── audit_logs

Quick Start

Prerequisites

  • Node.js >= 20

Setup

git clone https://github.com/your-username/agentgate.git
cd agentgate
npm install

Run

# Push the database schema (creates SQLite DB)
npm run db:push

# Start the API (port 3001)
npm run dev -w @agentgate/api

# Start the frontend (port 3000) — in another terminal
npm run dev -w @agentgate/web

How It Works

The Complete Flow

1. DEVELOPER registers → gets API key
2. DEVELOPER registers an AGENT → gets clientId + clientSecret
3. AGENT requests consent from USER → user sees consent screen
4. USER approves scopes → auth code issued
5. AGENT exchanges code → gets accessToken + refreshToken
6. AGENT calls your API with the token
7. YOUR API calls AgentGate /verify → allowed or denied
8. Everything is logged in the audit trail

Step-by-Step with curl

1. Register as a developer:

curl -X POST http://localhost:3001/api/v1/developers/register \
  -H "Content-Type: application/json" \
  -d '{"name":"Acme AI","email":"dev@acme.com","password":"securepass123"}'

2. Register an agent:

curl -X POST http://localhost:3001/api/v1/agents \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: ag_YOUR_API_KEY" \
  -d '{
    "name": "SmartMail",
    "description": "AI email assistant",
    "redirectUris": ["https://yourapp.com/callback"],
    "allowedScopes": ["email:read", "email:send"]
  }'

3. Request user consent:

curl -X POST http://localhost:3001/api/v1/consent/initiate \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "agc_YOUR_CLIENT_ID",
    "requestedScopes": ["email:read", "email:send"],
    "redirectUri": "https://yourapp.com/callback",
    "userId": "usr_USER_ID"
  }'

4. User approves → you get an auth code. Exchange it:

curl -X POST http://localhost:3001/api/v1/tokens/exchange \
  -H "Content-Type: application/json" \
  -d '{
    "code": "AUTH_CODE",
    "clientId": "agc_YOUR_CLIENT_ID",
    "clientSecret": "ags_YOUR_CLIENT_SECRET"
  }'

5. Verify the token before acting:

curl -X POST http://localhost:3001/api/v1/tokens/verify \
  -H "Content-Type: application/json" \
  -d '{
    "token": "eyJhbG...",
    "requiredScopes": ["email:send"]
  }'
# → { "allowed": true, "userId": "usr_...", "grantedScopes": [...] }

Using the SDK

Install the SDK in your agent:

npm install @agentgate/sdk

Agent Integration

import { AgentGateClient } from "@agentgate/sdk";

const gate = new AgentGateClient({
  baseUrl: "https://api.agentgate.dev",
  clientId: "agc_...",
  clientSecret: "ags_...",
});

// 1. Request consent
const consent = await gate.requestConsent({
  userId: "usr_...",
  scopes: ["email:read", "email:send"],
  redirectUri: "https://yourapp.com/callback",
});
// → redirect user to consent.consentUrl

// 2. After user approves, exchange code
const session = await gate.createSession(authCode);

// 3. Verify before acting (auto-refreshes token)
const result = await session.verify(["email:send"]);
if (result.allowed) {
  // safe to send email on behalf of user
  await sendEmail(/* ... */);
}

// 4. Revoke when done
await session.revoke();

Admin / Developer SDK

import { AgentGateAdmin } from "@agentgate/sdk";

const admin = new AgentGateAdmin({
  baseUrl: "https://api.agentgate.dev",
  apiKey: "ag_...",
});

// Register agents
const agent = await admin.createAgent({
  name: "My Agent",
  redirectUris: ["https://myapp.com/callback"],
  allowedScopes: ["email:read"],
});

// Set policies
await admin.createPolicy({
  agentId: agent.id,
  name: "Rate limit emails",
  rules: [{
    type: "rate_limit",
    config: { maxRequests: 10, windowSeconds: 3600, scope: "per_user" },
  }],
});

// View audit logs
const logs = await admin.getAuditLogs({ agentId: agent.id });

API Reference

Endpoints

Method Path Auth Description
POST /api/v1/developers/register None Register developer account
POST /api/v1/developers/login None Login
POST /api/v1/developers/api-keys/rotate API Key Rotate API key
GET /api/v1/agents API Key List your agents
POST /api/v1/agents API Key Register new agent
GET /api/v1/agents/:id API Key Get agent details
PATCH /api/v1/agents/:id API Key Update agent
POST /api/v1/agents/:id/rotate-secret API Key Rotate client secret
POST /api/v1/consent/initiate None Start consent flow
GET /api/v1/consent/:id None Get consent details
POST /api/v1/consent/:id/approve None Approve consent
POST /api/v1/consent/:id/deny None Deny consent
POST /api/v1/tokens/exchange None Exchange code for tokens
POST /api/v1/tokens/refresh None Refresh access token
POST /api/v1/tokens/revoke None Revoke a token
POST /api/v1/tokens/verify None Verify token + policies
POST /api/v1/users/register None Register user
POST /api/v1/users/login None Login user
GET /api/v1/users/:id/consents None List user's consents
POST /api/v1/users/:id/consents/:cid/revoke None Revoke consent
GET /api/v1/users/:id/audit-logs None User's audit log
GET /api/v1/policies API Key List policies
POST /api/v1/policies API Key Create policy
PATCH /api/v1/policies/:id API Key Update policy
DELETE /api/v1/policies/:id API Key Delete policy
GET /api/v1/scopes None List all scopes
GET /api/v1/scopes/:category None Scopes by category
GET /api/v1/audit API Key Query audit logs
GET /api/v1/health None Health check

Available Scopes

Scope Category Risk Level
email:read email standard
email:send email high
email:manage email high
calendar:read calendar low
calendar:write calendar standard
github:repo:read github standard
github:repo:write github high
github:pr:create github standard
github:pr:merge github critical
github:issues:write github standard
crm:contacts:read crm standard
crm:contacts:write crm standard
crm:deals:read crm standard
crm:deals:write crm high
messaging:read messaging standard
messaging:send messaging high
files:read files standard
files:write files high
files:delete files critical
db:read database standard
db:write database high
payments:read payments standard
payments:charge payments critical
profile:read profile low
profile:write profile standard

Policy Types

// Rate limit: max N requests per window
{ type: "rate_limit", config: { maxRequests: 100, windowSeconds: 3600, scope: "per_user" } }

// Time window: only allow during business hours
{ type: "time_window", config: { allowedDays: [1,2,3,4,5], startTimeUtc: "09:00", endTimeUtc: "17:00", timezone: "UTC" } }

// Action allowlist: only allow specific scopes
{ type: "action_allowlist", config: { actions: ["email:read"] } }

// Action blocklist: block specific scopes
{ type: "action_blocklist", config: { actions: ["payments:charge"] } }

// IP allowlist: restrict to specific IPs
{ type: "ip_allowlist", config: { cidrs: ["10.0.0.0/8"] } }

Security

  • Passwords hashed with Argon2id
  • API keys & client secrets stored as SHA-256 hashes; plaintext shown once on creation
  • Access tokens are JWTs (HS256), 15-minute expiry
  • Refresh tokens are opaque, 30-day expiry, rotated on every use
  • Replay detection: if a refresh token is used twice, the entire token family is revoked
  • Auth codes expire in 60 seconds, single-use
  • Rate limiting on all auth endpoints
  • Audit logs are append-only

Testing

# Make sure the API is running first
npm run dev -w @agentgate/api

# Run the test suite
npm test -w @agentgate/api

Deployment

Docker

# Build
docker build -f packages/api/Dockerfile -t agentgate-api .
docker build -f packages/web/Dockerfile -t agentgate-web .

# Run
docker run -p 3001:3001 \
  -e JWT_SECRET=your-production-secret-here \
  -e DATABASE_PATH=/data/agentgate.db \
  -v agentgate-data:/data \
  agentgate-api

Environment Variables

Variable Default Description
DATABASE_PATH ./agentgate.db SQLite database file path
JWT_SECRET (required) Secret for signing JWTs (min 32 chars)
JWT_ISSUER agentgate JWT issuer claim
API_PORT 3001 API server port
API_URL http://localhost:3001 Public API URL (for consent URLs)
NEXT_PUBLIC_API_URL http://localhost:3001 API URL for frontend

Contributing

Contributions are welcome! Check out CONTRIBUTING.md for guidelines.

Roadmap — Help Wanted

  • Session-based auth for dashboard (replace userId in URLs)
  • Webhook notifications on consent/revocation events
  • Multi-tenant organization support
  • PostgreSQL + Redis for production deployment
  • OpenAPI spec auto-generation
  • Agent-to-agent delegation chains
  • MCP server integration
  • More scope categories (Slack, Notion, Linear, etc.)
  • OAuth 2.1 full compliance
  • Admin analytics dashboard

Pick any of these and open a PR!


License

MIT — see LICENSE

About

OAuth for AI Agents - Auth & Permissions Platform

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors