Loading repository data…
Loading repository data…
reaatech / repository
Identity-aware proxy for agent-to-service communication. OAuth2 token management, per-user credential isolation, scope enforcement, and audit logging. Agents act on behalf of users safely.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
Identity-aware reverse proxy for secure agent-to-service communication.
A stateful proxy layer that sits between AI agents and downstream APIs (Google, GitHub, etc.), managing OAuth2 tokens, API keys, and scope enforcement on behalf of users. Built with a zero-trust security model — every request is authenticated, authorized, and audited.
/health and /ready endpoints for orchestration probes┌─────────────┐ ┌──────────────────────┐ ┌─────────────────┐
│ AI Agent │─────▶│ Agent Auth Proxy │─────▶│ Downstream API │
│ (Client) │ │ (Identity Layer) │ │ (Google, etc) │
└─────────────┘ └──────────────────────┘ └─────────────────┘
│
▼
┌──────────────┐
│ PostgreSQL │
└──────────────┘
Request Pipeline:
See ARCHITECTURE.md for detailed component design, security model, scaling strategy, and monitoring setup.
| Layer | Technology |
|---|---|
| Runtime | Node.js 22+ |
| Framework | Fastify 5 |
| Language | TypeScript 5.8+ (strict mode) |
| Database | PostgreSQL 15+ |
| ORM | Drizzle ORM |
| Auth | @fastify/jwt, PKCE OAuth2 |
| Validation | Zod |
| Logging | Pino (structured JSON) |
| Metrics | prom-client |
| Package Manager | pnpm 10+ (workspaces) |
| Build orchestration | Turborepo |
| Build | tsup |
| Lint/format | Biome |
| Test | Vitest, Supertest |
| Versioning | Changesets |
| Container | Docker, Docker Compose |
| Orchestration | Kubernetes (manifests provided) |
# Clone the repository
git clone https://github.com/reaatech/agent-auth-proxy.git
cd agent-auth-proxy
# Configure environment
cp .env.example .env
# Edit .env with your secrets (see Configuration section)
# Start services
docker compose up -d
# Run database migrations
docker compose --profile setup run --rm migrate
# Verify
curl http://localhost:3000/health
# Install dependencies
pnpm install
# Configure environment
cp .env.example .env
# Edit .env — set DATABASE_URL and generate MASTER_KEY
# Start PostgreSQL (Docker convenience)
docker compose up -d db
# Run migrations
pnpm db:migrate
# Start development server with hot reload
pnpm dev
| Variable | Description |
|---|---|
DATABASE_URL | PostgreSQL connection string |
MASTER_KEY | Base64-encoded 32-byte encryption key for credential vault |
AGENT_JWT_SECRET | Secret key for signing agent JWTs (32+ chars recommended) |
ADMIN_API_KEY | Pre-shared key for management API endpoints |
| Variable | Required For |
|---|---|
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET | Google API proxy |
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET | GitHub API proxy |
OAUTH_REDIRECT_URI | OAuth2 callback URL (e.g., https://proxy.example.com) |
| Variable | Default | Description |
|---|---|---|
PORT | 3000 | Server listen port |
HOST | 0.0.0.0 | Server bind address |
NODE_ENV | development | Environment (development, production, test) |
AGENT_JWT_EXPIRY | 3600 | Agent JWT lifetime in seconds |
RATE_LIMIT_GLOBAL_MAX | 1000 | Max requests per IP per 15-minute window |
PROXY_STREAM_TIMEOUT_MS | 60000 | Upstream response timeout (ms) |
PROXY_BODY_LIMIT_BYTES | 10485760 | Max request body size (10 MB) |
AUDIT_RETENTION_DAYS | 90 | Days to retain audit logs |
AUDIT_BATCH_SIZE | 100 | Audit log batch size for DB writes |
AUDIT_FLUSH_INTERVAL_MS | 5000 | Audit log flush interval (ms) |
SIEM_ENDPOINT | — | SIEM forwarding URL |
SIEM_API_KEY | — | SIEM authentication key |
# Generate MASTER_KEY (base64-encoded 32-byte key)
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
# Generate ADMIN_API_KEY (base64url-encoded 32-byte key)
node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"
# Generate AGENT_JWT_SECRET
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
POST /auth/agent
Authorization: Bearer <agent_api_key>
Response: { "token": "<jwt>", "agent": { "id": "<uuid>", "name": "<string>" } }
Agents exchange their long-lived API key (prefix aap_) for a short-lived JWT (default 1 hour). The JWT is then used as a Bearer token for all proxied requests. Agent API keys are returned by POST /api/v1/agents at registration time — they are shown only once.
Proxied requests forward method, path, headers, and body to the target downstream API with the user's credentials attached.
METHOD /proxy/:provider/<path...>
Authorization: Bearer <agent_jwt>
X-User-ID: <user_id>
?_scope=<comma,separated,scopes> # Optional: enforce scopes
# Example: Read Google Calendar
curl -X GET "http://localhost:3000/proxy/google/calendar/v3/calendars/primary?_scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly" \
-H "Authorization: Bearer <agent_jwt>" \
-H "X-User-ID: <user_id>"
The proxy forwards status codes, headers, and body directly from the downstream API. No response envelope — compatible with standard HTTP clients and SDKs.
Supported providers: google, github
All management endpoints are mounted under /api/v1 and require the admin API key passed via the X-Admin-API-Key header.
Users:
| Method | Path | Description |
|---|---|---|
POST | /api/v1/users | Create a user |
GET | /api/v1/users/:id | Get user details |
DELETE | /api/v1/users/:id | Delete a user |
GET | /api/v1/users/:id/grants | List user's agent grants |
Agents:
| Method | Path | Description |
|---|---|---|
POST | /api/v1/agents | Register a new agent (response includes the one-time api_key) |
GET | /api/v1/agents/:id | Get agent details |
DELETE | /api/v1/agents/:id | Delete an agent |
Grants:
| Method | Path | Description |
|---|---|---|
POST | /api/v1/grants | Create user-agent grant with scopes |
GET | /api/v1/grants | List all grants |
DELETE | /api/v1/grants/:id | Revoke a grant |
Tokens:
| Method | Path | Description |
|---|---|---|
GET | /api/v1/tokens | List OAuth token metadata (no secrets) |
DELETE | /api/v1/tokens/:id | Revoke a token |
OAuth:
| Method | Path | Description |
|---|---|---|
GET | /oauth/authorize?user_id&provider&scopes | Initiate OAuth2 authorization flow (redirects to provider) |
GET | /oauth/:provider/callback | OAuth2 callback (handled by provider redirect) |
A typed TypeScript SDK is published as @reaatech/agent-auth-proxy-client. It wraps these endpoints with AgentClient (auth + proxy) and AdminClient (management). See packages/client/README.md.
# Install dependencies
pnpm install
# Start development server (hot reload)
pnpm dev
# Build for production
pnpm build
# Run all tests
pnpm test
# Run tests with coverage
pnpm test:coverage
# Run tests in watch mode
pnpm test:watch
# Run security-focused tests
pnpm test:security
# Type-check the project
pnpm typecheck
# Lint and format
pnpm lint
pnpm format
# Database operations
pnpm db:generate # Generate migration files from schema
pnpm db:migrate # Run pending migrations
pnpm db:seed # Seed database with test data
pnpm db:studio # Open Drizzle Studio (GUI)
# Security audit
pnpm audit
CI enforces:
pnpm lint, pnpm format:check)pnpm typecheck)pnpm audit at moderate level and above# Build the image
pnpm docker:build
# Run with Docker Compose
pnpm docker:up
# Tear down
pnpm docker:down
The Dockerfile uses multi-stage builds: a builder stage compiles TypeScript, and a slim runtime stage runs the application as a non-root nodejs user.
Kubernetes manifests are provided in k8s/:
| Manifest | Purpose |
|---|---|
deployment.yaml | 3-replica deployment with resource limits and health probes |
service.yaml | ClusterIP service on port 3000 |
ingress.yaml | Ingress configuration for external access |
hpa.yaml | HorizontalPodAutoscaler (3–20 replicas, CPU 70% / memory 80%) |
secrets.yaml | Secret template for DATABASE_URL, MASTER_KEY, etc. |
kubectl apply -f k8s/
NODE_ENV=productionMASTER_KEY, AGENT_JWT_SECRET, and ADMIN_API_KEY regularlyThis is a pnpm + Turborepo monorepo with three publishable packages.