Show HN: Legant gives AI agents bounded authority to act on your behalf
Legant is an open-source delegated authorization system that lets AI agents act on behalf of users with scoped, time-boxed, revocable, and auditable authority. Built on RFC 8693 token exchange, it generates composite sub/act tokens with offline-enforceable constraint policies, monotonic attenuation, and full delegation provenance. Includes a complete OAuth 2.1/OIDC provider, multi-tenancy, SSO, and numerous demos.
Notifications You must be signed in to change notification settings
Fork 0
Star 0
BranchesTags
Open more actions menu
Folders and files
NameName
Last commit message
Last commit date
Latest commit
History
13 Commits
13 Commits
.github
.github
clients
clients
cmd/legant
cmd/legant
deployments
deployments
docs
docs
examples
examples
internal
internal
migrations
migrations
sdk
sdk
site
site
web/templates
web/templates
.gitignore
.gitignore
.goreleaser.yaml
.goreleaser.yaml
CHANGELOG.md
CHANGELOG.md
CODE_OF_CONDUCT.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
CONTRIBUTING.md
LICENSE
LICENSE
Makefile
Makefile
README.md
README.md
SECURITY.md
SECURITY.md
embed.go
embed.go
go.mod
go.mod
go.sum
go.sum
install.sh
install.sh
Repository files navigation
Open-source delegated authorization for AI agents. Legant lets an AI agent act on behalf of a user with authority you can scope, time-box, revoke, and audit. It's written in Go and ships as a single self-hostable binary.
make demo-driftstop — the same stolen-token replay that hit ~700 orgs, against a Legant token: no bulk export, no secret-bearing records, no audience pivot, minutes of life, and a one-entry offline kill. The theft still happens; the blast radius is what changes.
Website and live demos: https://legant-dev.github.io/legant/ · Releases: https://github.com/legant-dev/legant/releases
New here? Bound your first agent in a few minutes (no database), or jump to: what it is · try a demo · quick start · documentation.
What makes Legant different
A plain OIDC/OAuth server (Keycloak, Ory, Zitadel) can authenticate an agent and hand it a token. It cannot express "this agent may act for Alice, but only to submit travel/meal expenses under $500 for the next hour, and any sub-agent it spawns can only ever do less." Legant's core is exactly that:
RFC 8693 token exchange → composite sub/act tokens. The agent acts on behalf of the user (sub = user, act = the agent chain), never as the user. The full delegation provenance (user → agent → sub-agent) is recorded in the token.
Constraint policy enforced offline. Fine-grained limits (max amount, categories, tools, resource audiences, and time-of-day/weekday windows) ride inside the signed token, so a resource server enforces them from the token alone — no callback to Legant. A rolling-hour rate cap is enforced by Legant at mint time (it needs shared state a resource server lacks).
Monotonic attenuation. Authority can only ever narrow as it is re-delegated down a chain: a child that asks for a broader scope is rejected, and a looser constraint (a bigger amount, an extra category) is clamped down to the parent's.
The canonical engine for this lives in internal/delegation (pure, unit-tested) and there's a runnable, no-database demo in examples/agent-obo (make demo) that shows the whole flow end to end. On top of this, Legant is a full OAuth 2.1 / OpenID Connect provider (authorization code + PKCE, client credentials, refresh, discovery, JWKS, introspection, revocation) with multi-tenancy, SSO, and SCIM as the substrate.
Try it — the demo gallery
The fastest way to understand Legant is to run a demo. Each is a narrated, self-contained walkthrough; the ones below need only Go (no database, no Docker) unless noted. Clone the repo and:
make demo # agent-on-behalf-of: the whole delegation flow, end to end make demo-twoasks # confused deputy closed — one shared agent, two humans, audit names the human make demo-splice # multi-hop attenuation: a sub-agent can only ever do LESS than its parent make demo-driftstop # replays the Salesloft–Drift / UNC6395 OAuth theft on a survivable token make demo-foureyes # segregation of duties: "execute" needs a second distinct human make demo-blastdoor # k8s MCP gateway: filtered tools/list, change-freeze, mid-loop kill make demo-conductor # one agent across an MCP fleet + a tamper-evident flight recorder make demo-leash · demo-charter · demo-honeytool · demo-helpdesk · demo-cloudops · demo-gateway
Enterprise, production-integrated demos (real infrastructure — under examples/enterprise/):
make demo-aisre # AI-SRE on a REAL kind cluster + REAL mcp-server-kubernetes, guarded by Legant make demo-breach # the Salesloft–Drift OAuth theft replayed on the shipped RS middleware make demo-copilot # entitlement-preserving analytics copilot over a REAL Postgres warehouse
Landing page & visual demos: site/ is a build-free static site (open site/index.html or deploy to any static host) with a landing page, a revocation deep-dive, and live in-browser replays of conductor, leash, charter, and honeytool.
Status
Built and tested against Postgres (go test -race ./...).
Capability State
OAuth 2.1 / OIDC provider, multi-tenancy, SSO, SCIM, passkeys/TOTP Built
Delegation core — attenuation, constraints, composite sub/act tokens Built (internal/delegation)
Persistent multi-key signing keystore with rotation (legant keys …) Built
AuthZ backbone — Principal, RBAC, org-scoping (closed the admin API; killed X-User-ID) Built
RFC 8693 token-exchange endpoint — consent → composite token → revocation → audit Built
Multi-hop delegation — agent re-delegates an attenuated slice; full chain provenance Built
MCP / OAuth 2.1 compliance — RFC 8707 resource indicators, 7591 DCR, CIMD, SSRF-hardened fetch Built
MCP auth-gateway (legant gateway) — full MCP method surface (initialize/ping/notifications + tools), per-tool delegation on tools/call, tools/list filtered to the delegated tools, SSE streaming, confused-deputy protection Built
Resource-server SDKs — verify + authorize delegation tokens + Tier-B revocation offline, in Go (sdk), TypeScript (clients/typescript), and Python (clients/python); cross-language conformance vectors Built
Drop-in RS middleware — framework-native middleware in all three SDKs (net/http+chi · Express+Fastify · FastAPI+Flask), a self-hosted MCP-server guard, and a legant snippet / legant init resource-server generator Built
Declarative grants — a reviewable legant.grants.yaml with legant lint / legant apply (idempotent reconcile + diff) / legant who-can, plus top-level legant mint/show/revoke Built (internal/grants)
Helm chart — deployments/charts/legant (migrate pre-install hook, gateway/HPA/CronJobs/ServiceMonitor toggles, bundled Grafana dashboard) Built
Observability — Prometheus /metrics (request + delegation-activity counters), Go-runtime metrics Built
Deploy — hardened Dockerfile, Kubernetes manifests, data-retention job (legant maintenance prune) Built
Constraint PDP dimensions — time_window (offline) + rate (at mint), monotonic on re-delegation Built
Tamper-evident audit — hash-chained audit_events + legant audit verify Built
Self-service delegation UI — users view and revoke granted delegations (and their sub-agent chains) Built
Real-time console (/admin/live) — superadmin SSE dashboard: the living authority graph + a live mint/revoke/tool-call decision stream, fed across processes via Postgres NOTIFY Built
Tiered revocation — per-call store (gateway/introspection) + signed /.well-known/revoked feed for offline RSes + short-TTL backstop (5m default) Built
Coding-agent guard (legant guard install) — one command wires a pre-tool hook into Claude Code, OpenAI Codex CLI, and opencode that authorizes every tool call (read/write/edit/bash/apply_patch/MCP) offline from a delegation token: roles + allow/deny rules ("allow everything except"), catastrophic-command tripwires, sub-agent attenuation, mid-session revocation, audit. Denies via the hook layer, so it survives bypass / --yolo / full-auto Built (docs/CLAUDE_CODE.md)
Endpoints: /oauth2/{authorize,token,revoke,introspect,userinfo,register}, /consent/delegate, /delegations/redelegate, /account/delegations, /admin/audit, /admin/live{,/snapshot,/events,/ingest}, /.well-known/{openid-configuration,oauth-authorization-server,jwks.json,revoked}, /metrics, /healthz, /readyz, and (gateway mode) /mcp/{slug}.
CLI: legant serve | gateway | init grants|resource-server | lint | apply | mint | show | revoke | who-can | snippet | guard install|uninstall|check|demo|mint|revoke|show|deny|allow|rules|ui | migrate up|down|version | keys list|rotate|prune|reencrypt | maintenance prune | audit verify|anchor | admin grant-superadmin | dcr issue-token.
Deployment & roles — who runs what
Legant is an authorization server (like Keycloak, Ory, or Auth0), so it's deployed the same way: one component is stateful infrastructure, and the rest just talk to it. There isn't a single "integration" — there are roles, and only one of them runs a server:
Role What they do What they run
Operator Stands up the issuer for an organization legant serve + Postgres, in their own cloud
Agent author Builds an AI agent that acts for a user App code that does an RFC 8693 token exchange against the issuer
Resource-server developer Builds an API/MCP server that accepts agent tokens Just the sdk — verifies tokens offline, no DB, no callback
User Delegates scoped authority to an agent Nothing — uses the consent flow in a browser
To integrate with Legant you need only the Go SDK (verify a token against the issuer's published JWKS — no Postgres, no server). Postgres is only for the issuer — the one component that holds signing keys, sessions, the revocation state, and the audit chain — and even then the bundled docker compose brings its own, so there's no manual install.
user ──delegates──▶ ISSUER (legant serve + Postgres) ──JWKS──▶ RESOURCE SERVER (your API) ▲ mints short-lived verifies OFFLINE with the SDK AI agent ──exchange──┘ "acting-for-Alice" token (no callback to the issuer)
Self-hosted. You run the issuer in your own infrastructure (Docker, Kubernetes — see deployments/); nothing leaves your environment.
Quick Start
Three ways in, by what you want to do. The first two need only Go: no database, no Docker. The full, end-to-end walkthrough is docs/GETTING_STARTED.md.
Install the CLI
macOS / Linux — download the latest release binary
curl -fsSL https://raw.githubusercontent.com/legant-dev/legant/main/install.sh | sh
or with Go
go install github.com/legant-dev/legant/cmd/legant@latest
A. Define and inspect authority (no database)
Declare what an agent may do in a reviewable legant.grants.yaml, mint the signed tokens locally, and ask who can do what. All offline.
legant init grants # writes a commented starter legant lint -f legant.grants.yaml # validate (CI-gateable) legant apply -f legant.grants.yaml # mints signed tokens into .legant/ (no Postgres) legant who-can -f legant.grants.yaml --scope warehouse:query --resource finance
Every field is documented in docs/GRANTS.md.
B. Protect your own API (no database)
Verify and authorize those tokens at your own resource server, offline, with the SDK. The whole loop (define, mint, enforce, revoke) runs in one command:
make demo-protect # see examples/protect-your-endpoint
Walk it step by step in docs/GETTING_STARTED.md, or generate a starter for your framework: legant init resource-server --framework go-chi (also express, fastify, fastapi, flask, go-nethttp, mcp-go).
C. Govern a coding agent
legant guard install wires a PreToolUse hook into Claude Code, Codex, or opencode that authorizes every tool call against a delegation token, offline. This is one adapter on top of the same engine, not the whole product.
legant guard install # see docs/CLAUDE_CODE.md legant guard demo # see it work, no setup
Run the issuer (only for live token exchange)
Lanes A and B need no server. To have agents fetch tokens from a running issuer via RFC 8693 (see docs/AGENT_AUTHOR.md), run legant serve. It needs Go 1.26+ and PostgreSQL 16+; the bundled compose brings its own:
docker compose -f deployments/docker-compose.yml up -d # issuer at http://l
[truncated for AI cost control]