AI News HubLIVE
In-site rewrite5 min read

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.

SourceHacker News AIAuthor: baris_erdem

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]