From 6eac99e029f882c6934503ca5335a543c1ead55c Mon Sep 17 00:00:00 2001 From: Divine Date: Mon, 13 Apr 2026 17:22:51 -0400 Subject: [PATCH 1/3] docs: add markdown pages for token lifecycle and security topology diagrams Raw SVG links render poorly on GitHub. Each diagram now has its own markdown page with the embedded SVG plus context tables explaining the phases, zones, and security properties shown in the diagram. Architecture doc links updated to point to the markdown pages. --- docs/architecture.md | 2 +- docs/security-topology.md | 35 +++++++++++++++++++++++++++++++++++ docs/token-lifecycle.md | 29 +++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 docs/security-topology.md create mode 100644 docs/token-lifecycle.md diff --git a/docs/architecture.md b/docs/architecture.md index 2ca72cc..e4c76da 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -14,7 +14,7 @@ AgentWrit sits between AI agents and the resources they need to access, providin AgentWrit Architecture Overview

-> **More diagrams:** [Token Lifecycle](diagrams/token-lifecycle.svg) · [Security Topology](diagrams/security-topology.svg) +> **More diagrams:** [Token Lifecycle](token-lifecycle.md) · [Security Topology](security-topology.md) **Broker** (`cmd/broker`) -- The central authority. Loads or generates a persistent Ed25519 signing key (`internal/keystore`), issues EdDSA-signed JWTs, validates challenge-response registrations, manages scope attenuation, delegation, revocation, and maintains a hash-chained audit trail. All endpoints use `application/json` with RFC 7807 error responses. diff --git a/docs/security-topology.md b/docs/security-topology.md new file mode 100644 index 0000000..464da68 --- /dev/null +++ b/docs/security-topology.md @@ -0,0 +1,35 @@ +# Security Topology & Trust Boundaries + +How AgentWrit's three trust zones — Operator, App, and Agent — enforce the principle of least privilege through nested scope boundaries. + +

+ Security Topology +

+ +## The three zones + +| Zone | Actor | Trust level | What they control | +|------|-------|------------|-------------------| +| **Zone 1 — Operator** | Human operator using `awrit` CLI | Highest | Admin secret, app registration with scope ceilings, 4-level revocation, audit trail inspection, token TTL configuration | +| **Zone 2 — App** | Automated software (SDK or HTTP client) | Medium | Client credential auth, launch token creation bounded by scope ceiling, agent provisioning | +| **Zone 3 — Agent** | AI agent doing work | Lowest | Ed25519 keypair (no shared secret), scoped JWT bounded by launch token, renewal, delegation (narrower only), release | + +## How scope narrows through the zones + +1. **Operator** registers an app with a scope ceiling — the maximum permissions any agent under this app can ever hold. +2. **App** authenticates and creates a launch token. The launch token's `allowed_scope` must be a subset of the app's ceiling. +3. **Agent** registers with the launch token and requests a scope. The requested scope must be a subset of the launch token's `allowed_scope`. +4. **Delegation** narrows further — Agent A can delegate to Agent B, but only with the same or narrower scope. Never wider. + +Scopes only move in one direction: down. Every boundary is enforced at issuance time, not at validation time. + +## Security properties + +- **Challenge-response** — Ed25519 keypair per agent instance. No shared secrets at the agent level. +- **Hash-chain audit** — tamper-evident trail with 24 event types. Each record hashes the previous. +- **Scope attenuation** — scopes can only narrow, never escalate. Delegation preserves the original principal. +- **Token TTL** — default 5 minutes, max 24 hours (configurable). Per-app override available. Revocable at 4 levels. + +--- + +*Back to [Architecture](architecture.md) · [Concepts](concepts.md)* diff --git a/docs/token-lifecycle.md b/docs/token-lifecycle.md new file mode 100644 index 0000000..2d2148a --- /dev/null +++ b/docs/token-lifecycle.md @@ -0,0 +1,29 @@ +# Token Lifecycle + +How an AgentWrit token moves from issuance through renewal, delegation, revocation, release, and expiration. + +

+ Token Lifecycle +

+ +## The five phases + +| Phase | What happens | API | +|-------|-------------|-----| +| **Setup** | Operator registers an app with a scope ceiling. App authenticates with client credentials. | `awrit app register`, `POST /v1/app/auth` | +| **Launch Token** | App (or admin) creates a launch token bounded by the scope ceiling. | `POST /v1/app/launch-tokens`, `POST /v1/admin/launch-tokens` | +| **Agent Registration** | Agent gets a challenge nonce, signs it with Ed25519, registers with the launch token. Receives a scoped JWT and SPIFFE identity. | `GET /v1/challenge`, `POST /v1/register` | +| **Lifecycle** | Active token can be renewed (old revoked, new issued), delegated (narrower scope only), released (voluntary teardown), or left to expire on TTL. | `POST /v1/token/renew`, `POST /v1/delegate`, `POST /v1/token/release` | +| **Revocation** | Operator or admin revokes at four levels: single token (JTI), all tokens for an agent, all tokens for a task, or an entire delegation chain. | `POST /v1/revoke` | + +## Token states + +- **Active** — issued, within TTL, not revoked +- **Renewed** — new token issued, old token immediately revoked +- **Revoked** — explicitly killed via `/v1/revoke` (4 levels) +- **Released** — agent voluntarily surrendered the token via `/v1/token/release` +- **Expired** — TTL elapsed, no longer valid + +--- + +*Back to [Architecture](architecture.md) · [API Reference](api.md)* From 8804bfb6fb254e83f1689671d9c6385f4fc56ee3 Mon Sep 17 00:00:00 2001 From: Divine Date: Mon, 13 Apr 2026 17:34:25 -0400 Subject: [PATCH 2/3] docs: diagram markdown pages + README comparison table accuracy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Token lifecycle and security topology diagrams get dedicated markdown pages with context tables instead of raw SVG links. - README comparison table corrected to be fair against industry IAM: "Key works for everything, forever" → "Key is over-permissioned and long-lived"; revocation and audit rows reframed against real IAM capabilities rather than strawman claims. --- CHANGELOG.md | 5 +++++ README.md | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd0972b..4f8665c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added — Diagram documentation pages + README fix (2026-04-13) + +- Token lifecycle and security topology diagrams now have dedicated markdown pages (`docs/token-lifecycle.md`, `docs/security-topology.md`) with context tables and navigation. Architecture doc links updated. +- README: fixed "Key works for everything, forever" — IAM keys don't work like that. Changed to "Key is over-permissioned and long-lived." + ### Added — AgentWrit logo (2026-04-13) - README hero image added — centered logo at `docs/diagrams/agentwrit-logo.png`. diff --git a/README.md b/README.md index b0e053f..3802911 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,10 @@ Think of it as an issuer of legal **writs** for software: narrow authority, time | Without AgentWrit | With AgentWrit | |---|---| | Agent gets a long-lived API key | Agent requests a token per task | -| Key works for everything, forever | Token works for one task, expires in minutes | +| Key is over-permissioned and long-lived | Token is scoped to one task, expires in minutes | | Leaked key = full blast radius | Leaked token = one task, already expiring | -| Revocation is slow and manual | Revocation is instant at 4 levels | -| No record of what was issued | Every credential event is audited in a tamper-evident hash chain | +| Revoking a static key means rotating it everywhere | Revocation is instant at 4 levels — token, agent, task, or chain | +| No per-agent, per-task credential audit trail | Every credential event is audited in a tamper-evident hash chain | > **What the audit trail covers:** The broker logs credential lifecycle events — issue, renew, revoke, delegate, release, auth failures, and scope violations. It does not see what the agent does with the token at the resource server. From 2cf39038edbb23c259098774a9db5dbc182d3c91 Mon Sep 17 00:00:00 2001 From: Divine Date: Mon, 13 Apr 2026 17:35:42 -0400 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20reframe=20README=20comparison=20?= =?UTF-8?q?=E2=80=94=20traditional=20IAM=20vs=20agent-native?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Traditional IAM was built for humans and long-running services, not ephemeral AI agents. Reframed the comparison table to lead with that distinction and added delegation row. Honest about what IAM does — the gap is agent-specific lifecycle, not IAM being broken. --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3802911..77dff07 100644 --- a/README.md +++ b/README.md @@ -31,13 +31,16 @@ Think of it as an issuer of legal **writs** for software: narrow authority, time ### Why this matters -| Without AgentWrit | With AgentWrit | +Traditional IAM was built for humans and long-running services — not for AI agents that spin up, do one task, and disappear. Agents are ephemeral, task-scoped, and delegate to other agents. They need credentials that match that lifecycle. AgentWrit was purpose-built for it. + +| Traditional IAM for agents | AgentWrit | |---|---| -| Agent gets a long-lived API key | Agent requests a token per task | -| Key is over-permissioned and long-lived | Token is scoped to one task, expires in minutes | -| Leaked key = full blast radius | Leaked token = one task, already expiring | -| Revoking a static key means rotating it everywhere | Revocation is instant at 4 levels — token, agent, task, or chain | -| No per-agent, per-task credential audit trail | Every credential event is audited in a tamper-evident hash chain | +| Agents get static API keys or service account credentials designed for long-running services | Each agent requests a token scoped to one task | +| Credentials are over-permissioned because scoping per-task is manual and fragile | Scope attenuation is automatic — permissions only narrow, never expand | +| Leaked credential exposes everything the service account can access | Leaked token exposes one task, already expiring in minutes | +| Revoking a static key means rotating it everywhere it's used | Revocation is instant at 4 levels — token, agent, task, or delegation chain | +| No visibility into which agent used which credential for which task | Every credential event is audited per-agent, per-task in a tamper-evident hash chain | +| No native concept of agent-to-agent delegation | Delegation is built in — Agent A can delegate narrower-scoped tokens to Agent B with full chain tracking | > **What the audit trail covers:** The broker logs credential lifecycle events — issue, renew, revoke, delegate, release, auth failures, and scope violations. It does not see what the agent does with the token at the resource server.