Loading repository data…
Loading repository data…
shizhigu / repository
Production-grade auth rail for AI agents. Sits next to your existing human auth — never replaces it.
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 infrastructure for AI agents. Drop it next to your existing human auth — never replaces it.
The open-source engine ships as @vouch/server on npm. Hosted Vouch Cloud is on the roadmap for v1.0.
Status · Why · Comparison · Quick start · How it works · Architecture · Roadmap
Server-side engine: feature-complete (v0.2). All 8 milestones shipped + DX completeness sweep (factory, Hono, monorepo, CLI, scaffolder, multi-provider, docs site, OTel, brand assets) — 393 unit · 94 integration · 14 chaos tests passing at HEAD. Spec audited across 13 rounds with codex / GPT-5; final grade A (production-ready paying-customer level).
What is NOT shipped yet — and why this matters for you:
| Status | Plan | |
|---|---|---|
Published on npm (@vouch/server) | No — names reserved (agent-auth was taken), publish pending user OK | next |
Agent-side SDK (@vouch/client) | Dev preview — lives in packages/client/ (not yet on npm) | v0.2 |
CLI scaffolder (npx create-vouch-app) | Yes — Express SaaS or Node agent in one command, ready to run | shipped |
| Reference end-to-end demo (SaaS + agent) | Yes — runnable in apps/demo/ (Postgres + Redis via docker compose, no AWS / GitHub OAuth needed) | v0.2 |
| Docs site | Yes — VitePress site under apps/docs/, 9 pages, npm run docs:dev to preview | shipped |
| Multi-provider identity | Yes — identity.github, identity.google, identity.oidc (auto-discovery), or any pre-built IdentityProvider via identity.custom | shipped |
Migration runner (vouch migrate up) | Yes — @vouch/cli ships forward + rollback + status; tracking table auto-created | shipped |
| Vouch Cloud (hosted + admin dashboard) | No — self-host only | v1.0 |
If you want to try it today, see Quick start. If you want to build production on top of it, the realistic ETA is v0.2 (~4 weeks) when DX completes — the server-side core is solid, but the rough edges are real.
Today's "agent signup" stories don't hold up:
Vouch solves this by giving the agent its own first-class identity — rooted in a human's existing GitHub login, scoped to a single tenant, with full audit trail and instant revocation. You drop the engine into your SaaS backend; your existing human auth keeps working unchanged.
// Existing human auth — UNTOUCHED
app.use('/api/v1', humanAuth.middleware); // sets req.user
// New agent auth — lives on req.agent (per SPEC §6.3 confused-deputy prevention)
app.use('/api/agent/v1', agentAuthMiddleware);
app.get('/api/agent/v1/data', (req, res) => {
req.agent.require_scope('read'); // throws 403 on miss
return queryDb({ tenant_id: req.agent.account_id }); // RT-9 tenant isolation
});
Vouch is complementary to existing auth tools, not a competitor. It plugs a gap none of them cover today.
- Better Auth · Auth0 · Clerk · Lucia → "humans log into your SaaS"
- Nango · Arcade · Auth0 for AI Agents → "your code calls third-party APIs (Slack, GDrive, …) on behalf of an authenticated human"
- Vouch (this) → "AI agents register accounts on YOUR SaaS and get their own scoped API keys"
If you're building Acme SaaS and want Claude Code / Cursor / Codex to autonomously sign up for an Acme account on a human's behalf and call the Acme API: Vouch fills that gap. None of the others do.
| Better Auth · Lucia | Auth0 · Clerk | Nango · Arcade · Auth0-for-AI-Agents | Vouch (this) | |
|---|---|---|---|---|
| Whose identity | the human | the human | the human (token forwarded to 3rd-party APIs) | the agent itself |
| You are the… | service humans log into | service humans log into | service that calls 3rd-party APIs | service the agent calls |
| Hosted option | Better Auth Cloud | Yes (default) | Yes | Vouch Cloud (v1.0); self-host only today |
| DB ownership | your DB | their DB | your DB | your DB |
| Headless agent flow | n/a | n/a | partial (token broker) | designed for it (PKCE + sealed-box) |
| API key issuance | session cookies primarily | sessions / JWT / API keys | n/a | API keys (scoped, rotatable, instantly revocable) |
| Audit chain (cryptographic) | basic logs | yes (paid) | basic logs | append-only hash chain + WORM mirror |
| Multi-tenant by default | yes | yes | yes | yes (req.agent.account_id enforced) |
| Self-hostable | yes | no | yes (some) | yes (only mode at v0.1) |
| Supply-chain hardening | varies | n/a | varies | OIDC publish + Sigstore + SBOM + Scorecard |
crypto_box_seal) — the agent's pubkey gates the one-shot key drop. Stolen poll tokens cannot extract the key.synchronous_commit=remote_apply + two-phase idempotency. Network blips during commit produce deterministic outcomes (completed / failed / unknown), never silent loss.prev_hash/row_hash; hourly verifier walks the chain; WORM mirror in S3 Object Lock for SOC 2 / GDPR.Heads up — packages aren't on npm yet. Until v0.2 publishes, scaffold from this repo by passing
--template-dirtocreate-vouch-appor install viafile:link.
npx create-vouch-app my-saas
cd my-saas
cp .env.example .env
docker compose up -d
npx vouch migrate up
npm install
npm run dev
That's it — create-vouch-app writes a working Express SaaS template, vouch migrate up applies the schema, npm run dev starts the server with hot reload. See packages/create-vouch-app for templates (saas-express, agent).
git clone https://github.com/shizhigu/agent-auth.git
cd agent-auth
npm install && npm run build
# Then in your SaaS project:
npm install /path/to/agent-auth
npm install -D @vouch/cli
DATABASE_URL=postgres://… npx vouch migrate up
vouch migrate status shows pending vs applied; vouch migrate down --steps 1 rolls back. Tracking lives in a vouch_migrations table the CLI creates automatically. See packages/cli/README.md for the full reference.
import express from 'express';
import { vouch } from 'agent-auth';
declare module 'express-serve-static-core' {
interface Request {
agent?: import('agent-auth').AgentContext; // NOT req.user — see SPEC §6.3
}
}
const auth = await vouch({
database: { url: process.env.DATABASE_URL! },
redis: { url: process.env.REDIS_URL! },
kms: {
provider: 'aws',
region: 'us-east-1',
pepper_alias: 'alias/vouch-pepper',
device_alias: 'alias/vouch-device-flow',
pepperFetcher: async (v) => /* read pepper bytes from KMS */ Buffer.alloc(32),
},
identity: {
github: {
client_id: process.env.GH_CLIENT_ID!,
client_secret: process.env.GH_CLIENT_SECRET!,
webhook_secret: process.env.GH_WEBHOOK_SECRET!,
app_private_key_pem: process.env.GH_APP_PRIVATE_KEY!,
},
},
internal_secret: process.env.AGENT_AUTH_INTERNAL_SECRET!, // base64
base_url: process.env.PUBLIC_BASE_URL!,
});
const app = express();
auth.express.mount(app); // /agent-auth/*
app.use('/api/agent/v1', auth.express.middleware()); // protect your API
app.get('/api/agent/v1/whoami', (req, res) => {
res.json({ account_id: req.agent!.account_id, scopes: req.agent!.scopes });
});
app.listen(8080);
That's it — vouch() builds Postgres / Redis / KMS adapters, wires the 12 lifecycle routes (begin-registration, callback, registration-status, rotate-key, revoke, recover-account*, webhooks/:provider, healthz, well-known, list-keys), handles raw-body parsing for webhook signature verification, and runs redis.loadScripts() + sealedBoxReady() for you.
Pick one or more — they're additive:
const auth = await vouch({
// ... database / redis / kms / internal_secret as above ...
identity: {
github: {
client_id: process.env.GH_CLIENT_ID!,
client_secret: process.env.GH_CLIENT_SECRET!,
webhook_secret: process.env.GH_WEBHOOK_SECRET!,
app_private_key_pem: process.env.GH_APP_PRIVATE_KEY!,
},
google: {
client_id: process.env.GOOGLE_CLIENT_ID!,
client_secret: process.env.GOOGLE_CLIENT_SECRET!,
hosted_domain: 'acme.com', // optional — restrict to one Workspace
},
oidc: {
// Generic OIDC — any standards-compliant IdP via discovery.
name: 'okta',
issuer_url: 'https://your-tenant.okta.com',
client_id: process.env.OKTA_CLIENT_ID!,
client_secret: process.env.OKTA_CLIENT_SECRET!,
},
},
});
Need a provider Vouch doesn't ship? Implement IdentityProvider and pass it via identity.custom: [yourProvider]. Each registration session picks one provider via request.body.provider (e.g. `'github_