Skip to content

Commit e1920d9

Browse files
mjunaidcaclaude
andcommitted
docs(ai-identity): frontier specs verified + add step-up-approval
The agent-credential and on-behalf-of frontier specs are upgraded from roadmap stubs to verified-buildable (a worked example now exists), keeping the SDD 'primitives over API' framing, and each gets a prompts.md. Adds the step-up-approval spec: least-privilege capabilities, value-level constraints, and the none->session->webauthn approval ladder. projects/README frontier tier now lists all three. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 98f03f2 commit e1920d9

7 files changed

Lines changed: 88 additions & 8 deletions

File tree

‎ai-identity/specs/projects/README.md‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ This is the **~50% milestone**. From here the course stops handing you fully spe
66

77
The projects come in three tiers, by how settled the ground is under them:
88

9-
| Tier | Project | Runs on | When |
10-
| ------------ | --------------------------------------------- | ------------------------------------------------------------------- | ----------------------------------------------------- |
11-
| **Stable** | `2fa`, `social-login` | Official, stable Better Auth | Do these now, at ~50% |
12-
| **Edge** | `06-client-identity-with-cimd` (on the spine) | `@better-auth/cimd`, the 1.7 pre-release channel + a draft standard | You just did it — that was the step onto the frontier |
13-
| **Frontier** | `agent-credential`, `on-behalf-of` | `@better-auth/agent-auth`, **beta** — the standard is still moving | Half 2, where agents get identity |
9+
| Tier | Project | Runs on | When |
10+
| ------------ | ------------------------------------------------------ | ------------------------------------------------------------------- | ----------------------------------------------------- |
11+
| **Stable** | `2fa`, `social-login` | Official, stable Better Auth | Do these now, at ~50% |
12+
| **Edge** | `06-client-identity-with-cimd` (on the spine) | `@better-auth/cimd`, the 1.7 pre-release channel + a draft standard | You just did it — that was the step onto the frontier |
13+
| **Frontier** | `agent-credential`, `on-behalf-of`, `step-up-approval` | `@better-auth/agent-auth`, **beta** — the standard is still moving | Half 2, where agents get identity |
1414

1515
**Stable** projects are the natural next move at the halfway mark. You built sign-in; now you raise the stakes on it without leaving solid ground:
1616

@@ -19,7 +19,7 @@ The projects come in three tiers, by how settled the ground is under them:
1919

2020
**Edge** is spec `06` itself, back on the core spine: it is where the course first stepped off stable ground onto a pre-release plugin (`@better-auth/cimd`) and an IETF draft. You confirm the live surface against the Better Auth docs MCP before building, because it moves.
2121

22-
**Frontier** is Half 2: an agent gets its **own** credential (`agent-credential`) and acts **on behalf of** a human under bounded, revocable, human-approved authority (`on-behalf-of`). These run on `@better-auth/agent-auth`, which is beta — you treat the specific API as one swappable instantiation of the durable primitives, and pin the version.
22+
**Frontier** is Half 2: an agent gets its **own** credential (`agent-credential`), acts **on behalf of** a human under bounded, revocable, human-approved authority (`on-behalf-of`), and has that authority **tightened** with least-privilege capabilities, value-level constraints, and step-up approval (`step-up-approval`). These run on `@better-auth/agent-auth`, which is beta — you treat the specific API as one swappable instantiation of the durable primitives, and pin the version. A verified worked example for all three lives in `worked-examples/ai-identity/`.
2323

2424
---
2525

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Project — Agent credential · uses `specs/projects/agent-credential/spec.md`
2+
3+
> A Half-2 frontier project on `@better-auth/agent-auth` (beta). Until now every token stood for a human; here the agent is the subject. It gets its OWN short-lived, scoped, revocable credential (autonomous mode), so its actions are attributable to it, not borrowed from a person's session. A verified answer key lives in `worked-examples/ai-identity/`.
4+
5+
**Build:**
6+
7+
> Read `specs/projects/agent-credential/spec.md` and `.agents/skills/agent-identity-issuer/`. Confirm the live agent-auth surface against the Better Auth docs MCP first — it's beta. Plan it, show me the plan, then build in small steps: enable autonomous agent identity, register an agent under a host, have it self-sign its own short-lived credential, and execute a granted capability. Run every acceptance check, including replay and revocation (AC-3, AC-4).
8+
9+
**Understand (no spec):**
10+
11+
> Register an autonomous agent and show me the credential it gets. Whose identity is the `sub` — a person's, or the agent's own? Explain in plain English why the agent having its own identity is different from it reusing my login.
12+
13+
> Take my agent's credential, replay the exact same signed token twice, and show me the second call being refused. Explain what the `jti` is doing and why a short-lived self-signed token is safer than a long-lived bearer.
14+
15+
> Revoke my agent, then have it try its next call. Show me it failing, and explain why revocation has to bite on the very next request rather than whenever a cached grant expires.

‎ai-identity/specs/projects/agent-credential/spec.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# spec.md — An agent gets its own credential
22

3-
> **Half 2 — roadmap.** A stub, lighter than specs 01-04. Built on `@better-auth/agent-auth`, which is **BETA, the standard is still moving**. Treat the specific API below as **one swappable instantiation** of the durable primitives (own credential, least-privilege scope, finite expiry, revocable), not the final word. When the standard settles, the primitives stay; only the calls change.
3+
> **Half 2 — frontier.** Built on `@better-auth/agent-auth`, which is **beta, the standard is still moving**. A **verified worked example exists** (`worked-examples/ai-identity/` — `src/lib/auth.ts`, `agent-consumer/`, `agent-verify.sh`), so this is buildable, not a sketch. Treat the specific API as **one swappable instantiation** of the durable primitives (own credential, least-privilege scope, finite expiry, revocable), not the final word. When the standard settles, the primitives stay; only the calls change.
44
55
## Goal
66

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Project — On-behalf-of · uses `specs/projects/on-behalf-of/spec.md`
2+
3+
> A Half-2 frontier project on `@better-auth/agent-auth` (beta). The credential most worth getting right: the agent acts FOR a person, but only with that person's explicit, bounded, revocable say-so — no impersonation, no standing key, no grant without a human in the loop. A verified answer key lives in `worked-examples/ai-identity/`.
4+
5+
**Build:**
6+
7+
> Read `specs/projects/on-behalf-of/spec.md` and `.agents/skills/agent-identity-issuer/`. Confirm the live agent-auth surface against the Better Auth docs MCP first — it's beta. Plan it, show me the plan, then build in small steps: enable delegated mode, have an agent request a scoped capability, gate it behind human device-code approval, and only then let it act. Run every acceptance check, including no-approval-no-grant and revocation (AC-1, AC-4).
8+
9+
**Understand (no spec):**
10+
11+
> Have my agent request the right to act for me, then stop before I approve. Show me that it has nothing yet — no token, no access. Explain why "human in the loop" means the approval is the thing that mints authority, not a formality after it.
12+
13+
> Approve a delegated grant, then show me the token. Point out where it says both the agent AND that it's acting on behalf of me. Explain why this is delegation, not impersonation, and why that distinction matters for an audit trail.
14+
15+
> Revoke the delegation I gave my agent, then have it try its next on-behalf-of call. Show me it failing. Explain why I, the human, must be able to pull authority back at any moment.

‎ai-identity/specs/projects/on-behalf-of/spec.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# spec.md — On-behalf-of (delegated authority)
22

3-
> **Half 2 — roadmap.** A stub, lighter than specs 01-04. Built on `@better-auth/agent-auth`, which is **BETA, the standard is still moving**. The specific API below is **one swappable instantiation** of the durable primitives (delegated on-behalf-of authority, least-privilege scope, finite/time-boxed expiry, human approval, revocable). Keep the primitives; expect the calls to change.
3+
> **Half 2 — frontier.** Built on `@better-auth/agent-auth`, which is **beta, the standard is still moving**. A **verified worked example exists** (`worked-examples/ai-identity/` — the delegated + device-code approval flow in `agent-consumer/`, proven by `agent-verify.sh`), so this is buildable, not a sketch. The specific API is **one swappable instantiation** of the durable primitives (delegated on-behalf-of authority, least-privilege scope, finite/time-boxed expiry, human approval, revocable). Keep the primitives; expect the calls to change.
44
55
## Goal
66

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Project — Step-up & constraints · uses `specs/projects/step-up-approval/spec.md`
2+
3+
> A Half-2 frontier project on `@better-auth/agent-auth` (beta). It takes the agent identity you built and makes its authority tight: least-privilege capabilities, value-level constraints, and a human gate that gets harder as the action gets more dangerous. A verified answer key lives in `worked-examples/ai-identity/`.
4+
5+
**Build:**
6+
7+
> Read `specs/projects/step-up-approval/spec.md` and `.agents/skills/agent-identity-issuer/`. Confirm the live agent-auth surface against the Better Auth docs MCP first — it's beta. Plan it, show me the plan, then build in small steps: three capabilities across the approval ladder (auto / session / physical-presence), one with a required value-constraint, and a single-use grant. Run every acceptance check, including the adversarial ones (AC-3, AC-4).
8+
9+
**Understand (no spec):**
10+
11+
> Give my agent a capability to share notes, but only with `@acme.com`. Then have it try to share with `@evil.com` and show me exactly where the server refuses it. Explain why a value-constraint is stronger than an on/off scope.
12+
13+
> Try to approve the "delete everything" capability for my agent using just my logged-in session. Show me the server demanding physical presence instead of granting it, and explain what that step-up is protecting against when the agent itself has a browser.
14+
15+
> Have my agent use a single-use grant once, then try the same action again. Show me the second call being refused, and explain why a payment-like action should consume its grant.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# spec.md — Scope and gate an agent: capabilities, value-constraints, step-up
2+
3+
> **Half 2 — frontier.** Built on `@better-auth/agent-auth`, which is **beta, the standard is still moving**. A **verified worked example exists** (`worked-examples/ai-identity/` — `src/lib/auth.ts`, `agent-consumer/`, `agent-verify.sh`), so this is buildable, not theoretical. Treat the specific API as **one swappable instantiation** of the durable primitives (least-privilege capability, value-level constraint, graded human approval, single-use). When the standard settles, the primitives stay; only the calls change.
4+
5+
## Goal
6+
7+
The two mode specs (`agent-credential`, `on-behalf-of`) answer _whose_ authority an agent holds. This one answers _how tightly_ it is bounded and _how hard it is to widen_. Three primitives, each stricter than what plain OAuth scopes can express:
8+
9+
1. **Capabilities** — named actions, not blanket access. An agent holds only the capabilities it was granted.
10+
2. **Value-level constraints** — a capability can be pinned to allowed _values_, not just turned on. "May share notes" is weaker than "may share notes only with `@acme.com`." OAuth scope strings cannot say that; a constraint can (`{ recipientDomain: { in: ["acme.com"] } }`), and it is checked at execution time.
11+
3. **Graded approval (step-up)** — the strength of the human check scales with the blast radius. A read auto-grants; a share needs a logged-in human; an irreversible action needs **physical presence** (a passkey / WebAuthn), so an AI agent with a browser cannot approve its own destruction.
12+
13+
The durable point: authority is least-privilege by default, narrowed by value where it matters, and the human gate gets harder as the action gets more dangerous.
14+
15+
## Functional Requirements
16+
17+
- FR-1 Define at least three capabilities spanning the **approval-strength ladder**: one that auto-grants (no human), one that needs a normal logged-in session, and one destructive capability that requires physical-presence (WebAuthn) approval.
18+
- FR-2 At least one capability carries a **required value-constraint** the agent must scope when it requests the capability (e.g. an allowed recipient domain, a maximum amount).
19+
- FR-3 The constraint is **enforced at execution time**: a call whose argument violates the constraint is refused, and the refusal does not consume the grant.
20+
- FR-4 The destructive capability **cannot be approved by a normal session** — approving it without a registered authenticator is refused with a step-up challenge, not granted.
21+
- FR-5 A sensitive grant is **single-use** where appropriate: after one successful execution it is consumed and the next call must be re-approved.
22+
23+
## Acceptance Criteria
24+
25+
- [ ] AC-1 **Least privilege:** an agent invokes a granted capability and is refused one it was not granted, with no way to widen its own grant.
26+
- [ ] AC-2 **Constraint holds in-bounds:** an in-scope value (recipient `@acme.com`) executes successfully.
27+
- [ ] AC-3 **Constraint bites out-of-bounds:** an out-of-scope value (recipient `@evil.com`) is refused with a constraint violation, and the grant survives (the rejected call did not consume it).
28+
- [ ] AC-4 **Step-up is enforced:** approving the destructive capability with only a logged-in session is refused with a physical-presence challenge; the capability stays ungranted and the agent still cannot execute it.
29+
- [ ] AC-5 **Single-use:** a sensitive grant works exactly once; the second call fails as not-granted rather than succeeding on a stale grant.
30+
31+
## Notes for the builder
32+
33+
- Read `.agents/skills/agent-identity-issuer/` and confirm the live surface against the Better Auth docs MCP — this is beta. The verified worked example shows one passing shape (capabilities with `approvalStrength: none|session|webauthn`, `requiredConstraints`, a `revokeGrant()` consume in the execute handler), but check the current API before you build.
34+
- Completing a WebAuthn approval needs a real or virtual authenticator. The **guardrail** (refusing a session-only approval for a destructive capability) is fully testable without one — that is what AC-4 checks. Note in your build where a real passkey would complete the step-up.
35+
- Keep the acceptance criteria even if the calls move: least-privilege capability, value-constraint enforced at execution, graded approval with physical-presence step-up, single-use consume.

0 commit comments

Comments
 (0)