AI Identity: Human Sign-In and Agent Access
AI Identity: Human Sign-In and Agent Access | Agentic Engineer
AI Identity: Human Sign-In and Agent Access
You stop borrowing identity and start issuing it · built by directing an agent, one spec at a time
Picture your Digital FTE working at 2 a.m. while you are asleep. It files an expense, books a vendor, sends a reply. One question decides whether that is safe or a disaster waiting to happen: whose identity did it use?
In the Connector-Native Apps and Plugins for AI Agents courses, your app simply borrowed the identity of whoever was running the host. That is fine while a human is in the chair. But a worker that runs when no human is in the chair cannot borrow a human's login, because if it logs in as you, it is you: it can do everything you can do, forever, and every log says you did it. There is no way to scope it, time-box it, or take it back.
This course is where identity stops being borrowed. You build it in two halves. First you own your sign-in: instead of renting a third-party login, you stand up your own production-grade authentication and an OAuth/OIDC server that issues real tokens. Then you give an agent identity of its own: a credential that is scoped, time-boxed, revocable, and human-approved, so a worker can do real work on a person's behalf without ever impersonating one.
By the end you will have shipped one running app (a real Next.js project on your own machine) that is, in order:
- your own email-and-password sign-in, with real sessions and a protected dashboard;
- an OAuth/OIDC issuer that mints signed tokens and publishes its keys (JWKS) for anyone to verify;
- a second, separate app that signs people in through your issuer while holding none of your secrets;
- a resource server that verifies those tokens offline, accepting only bands minted for it;
- and a beta agent credential: a scoped, time-boxed, revocable, human-approved band an AI worker carries in its own name.
:::note Prerequisite: Spec-Driven Development This is a build course, and it assumes you already own the spec-driven loop: agree on the _what_, then direct an agent to produce the _how_. Unlike the SDD course, the main tool here is **not claude.ai**. This course is **repo-based**: you work in **Claude Code or OpenCode** on a real Next.js app. You will not hand-write TypeScript; you direct a general agent and it writes the code, the same move as every build course on the Manufacturing track. But this is a security course, so the code is only half the job: what stays yours is to **specify** what gets built, then **inspect, test, and prove** each security property holds. That is what the spec-less _understand_ prompts throughout this course drill, decoding a token, tampering with its audience, replaying it, watching the server refuse. :::
📚 Teaching Aid
:::tip Open Full Slideshow **[View Full Presentation](https://docs.google.com/presentation/d/1bjM3WsHiCyFtmy4P5s1KuF6BJp\_5svpFEJVIQE8Pulg/edit?usp=sharing)\*\* — AI Identity: Human Sign-In and Agent Access :::
The one question this course answers
Every system you build after this, you can hold up to one test:
Whose identity is this, and how does authority pass from a human to an agent?
That question is the spine. The specific tools will keep changing as the agent-identity standards settle. The question does not.
One picture: the venue and the wristband
Identity sounds abstract until you map it to a night out. Hold this single picture in your head and every piece of the course snaps into place.
You arrive at a venue. At the door, someone checks your ID once: that is signing in, proving who you are. They do not make you show your ID again at every bar inside. Instead a booth prints you a wristband. The band is proof you are allowed in; it expires when the venue closes, and a bouncer can cut it off if you misbehave. Inside, the bartender just glances at your band and serves you. The band has a seal only the booth can make, so the bartender trusts it on sight, without phoning the booth to ask.
That is the whole identity stack, with one term for each part of the scene:
The venue and the wristbandThe doorshow ID, once= Sign-inown your sign-in (01)The boothprints the bands= The issuer (you)become the issuer (02)the wristband= The tokenlets you in · expires · cuttableThe bartenderglances at the band= The validatorthe gateway (04–05)The seal is one only the booth can make, so the bartender trusts the band on sight, without phoning the booth.That is the real trick of tokens: anyone can verify your signature with your published keys, but nobody can forge it.The frontier: the agent gets a band of its ownThe agent's OWN bandagent #7= agent credentialin the agent's name, not yours.the logs say the agent did it,so it is not pretending to be you.A stamped bandfor Alice · drinks only · void at midnight · over $50 needs Alice= on-behalf-of authorityscope (drinks only) · expiry (midnight)human approval (Alice signs off)revocable (a bouncer can cut it)
One model, used everywhere: the door is sign-in, the booth is the issuer, the band is the token, the bartender is the validator. On the frontier, the agent stops borrowing your band and gets one of its own, sometimes stamped to act for a person under tight limits.
Notice the part that makes tokens work: the bartender never calls the booth. The band's seal is enough. In real systems that seal is a cryptographic signature, and the booth publishes the key anyone needs to check a signature, while keeping the key needed to make one. That is why a stranger app can trust your tokens without ever touching your database or your secrets.
Tokens and sessions, from zero
Three words run through the rest of this course. Here is each, in plain terms, on the picture you already hold.
A session is how the server remembers you are signed in. After the door checks your ID, it sets a small marker in your browser, a cookie, and reads it on every later request, so you do not sign in again on each page. The session is the venue knowing you walked in tonight.
A token is the wristband itself: a signed claim of who you are and what you may do. The common kind is a JWT (JSON Web Token), three parts joined by dots, header.payload.signature. The payload carries the claims; the signature is the booth's seal.
Here is the image to hold for the rest of the course. The booth signs a band by pressing its own wax seal into it. The stamp that makes that seal, the booth's private key, stays locked inside the booth and never leaves, so no one else can copy the mark. To let the world check the seal, the booth tapes a clear photo of it on the wall by the door, the published (public) key. Anyone can hold a band up to the photo and confirm the seal is genuine, but you cannot carve a working stamp from a photo. That is the whole trick: the photo lets a stranger verify a band without ever being able to forge one, which is exactly what the bartender trusts on sight.
OAuth (with OIDC layered on top to carry who the person is) is the agreed protocol for the handshake where the booth prints a band for another app: one app sends a person over to sign in, your server hands back a token, and the other app reads it.
:::tip Try it Grab any JWT (your own app will mint one in a few minutes, or paste an example) and ask your agent: _"Decode this JWT. Show me the header and payload as plain JSON, explain what each claim means, and tell me which part anyone can verify with a public key and which part proves it was not tampered with."_ Reading its answer is a faster gut-check than re-reading this section. :::
Set up your environment (once)
Everything you build happens inside one small folder: the course base. It is deliberately lean: it ships the constitution, the specs, the prompts, and one skill, and there is no app yet. Your first move is to direct the agent to build one, which is itself the first rep of the loop you will use the whole way through.
Download it once; the same folder serves the whole course.
Or clone the agentfactory-manufacturing repo and open its ai-identity folder. Either way, open the folder in your agent:
Claude CodeOpenCode
codecd ai-identityclaude
codecd ai-identityopencode
You will also need a free Neon Postgres database for the sign-in data (no credit card; the base wires it for you). Set it up before the second prompt below.
Lesson 0 comes in two prompts, so you watch the ground get proven before anything is built on it.
Step 1, prove the environment. Paste:
Read
specs/00-set-up-the-base/spec.md(Phase 1) and the "Set up the base" section ofAGENTS.md. Check my prerequisites (Node, pnpm), install the skills it lists (Better Auth, shadcn, Neon), and confirm the MCP servers in.mcp.jsonandopencode.jsonare present and reachable. Don't scaffold anything yet. Just prove the ground and run the Phase 1 acceptance checks.
Watch for: npx skills add can silently drop a skill name, so the agent confirms each one actually landed. Done when: Node and pnpm report versions, the better-auth, shadcn, and neon-postgres skills are present, and the three MCP servers answer.
What just happened: you hired the trained staff and wired the phones, and built nothing yet. The skills are the booth operator's manuals (how to issue a band, how to build the UI); the MCP servers are the agent's direct lines to Neon's control room and to live docs. The ground is proven; nothing is standing on it.
Step 2, scaffold the app. Provision your Neon database first, then paste:
Now do Phase 2 of
specs/00-set-up-the-base/spec.md: scaffold the Next.js + Tailwind + shadcn app here, pin the Better Auth 1.7 stack with the kysely override, add the Neon driver, and create.envfrom the template. Don't build any auth. Start the dev server and show me the landing page is up, then run the Phase 2 acceptance checks.
Watch for: create-next-app refuses to scaffold into a non-empty directory, so the base's recipe scaffolds into a temp dir and merges the result back (base files win any conflict). Done when: pnpm dev serves a plain landing page at http://localhost:3000, and pnpm build and tsc both run clean.
What just happened: now the building exists. The dev server shows an empty venue with the lights on, a real app booting on your machine, but with no door, no booth, and no bands yet. You have somewhere to put the identity system, which is exactly what Lesson 1 starts building.
Quick Win: be signed in to your own app
With the base ready, you are one prompt away from a sign-in screen that you own, backed by a real database. Succeed first, understand second.
Before you paste, name the four pieces this builds, all on the same picture. Email and password sign-in is the door checking an ID you set up the first time you arrive. A session is the venue remembering you walked in tonight, kept by that cookie from earlier, so you do not show ID again on every page. A protected route is a back room only signed-in members may enter. And a password hash is the one-way fingerprint the door keeps instead of your actual password, so even the venue cannot read it back.
Lesson 1, own your sign-in. Paste:
Read
specs/01-own-your-sign-in/spec.mdand thebetter-auth-best-practicesandemail-and-password-best-practicesskills. Plan the approach against our constitution, show me the plan, then build it in small steps. Run the spec's acceptance checks, including the security ones, before you call it done.
You review the plan, the agent builds, and you create an account and land on a dashboard that proves who you are. That is your win: sign-up, sign-in, sessions, and a protected page, all running on your own server.
Watch for: Better Auth's POST endpoints reject any request whose Origin header is not trusted, so the base's config lists your dev origin up front. Done when: you create an account and land on a dashboard showing your name and email, and your password is stored only as a one-way hash, which the understand prompt below proves.
Now make it real to yourself with an understand prompt, which has no spec, it just makes you see what you built:
I just signed up. Show me exactly what got stored in the database for my account, and point out what is NOT there. Where is my password, and why can't you show it to me?
The answer (your password is stored only as a one-way hash, so even your own server cannot read it back) is the first piece of identity literacy this course builds. You did not read it in a paragraph. You watched it on your own data.
The build path: from renting login to issuing it
The course is a spine of seven steps that map one-to-one onto the specs in the base. You build each by pasting a short prompt; the spec carries the detail and the skill carries the exact API, so the prose stays about the idea. Here is the whole arc, and where it stops being settled ground.
The build path: stable spine → edge → frontierSTABLE SPINE · production-grade0 · set up the base1 · own your sign-in2 · become the issuer (the marquee)3 · scopes & consent4 · connect a real app5 · connect a resource serverEDGE6 · clientidentity(CIMD)pre-releaseFRONTIERagent credentialon-behalf-ofscope & step-upbeta~50% milestone, after the spine: harden your sign-in by adding two-factor and a social login (still on stable ground).
The seven-step spine, then the milestone, then the frontier. The further right you go, the younger the standards; the mental model stays the same the whole way.
0–1. Set up the base, then own your sign-in
You met these in the Quick Win. Step 0 scaffolds the toolchain (Next.js, shadcn, the Better Auth 1.7 stack, Neon). Step 1 stands up email and password sign-in with real server-side sessions and a protected dashboard. This is the door: your users prove who they are, once.
2. Become the issuer (the marquee)
This is the step the whole track has been pointing at. In Connector-Native Apps you were the bartender: your gateway validated tokens that someone else had signed. Here you walk behind the counter and become the booth. When another app sends a person to you to sign in, your server hands back a signed token that the other app can verify entirely on its own by checking it against the photo of your seal you post publicly, without ever seeing a password or calling your database.
That is the loop closing: the course where you only checked wristbands now teaches you to print them.
Before you paste this, meet the handshake your booth is about to run. When an OAuth client (another venue that agrees to honor your wristbands) sends a person over to sign in, you do not pass the band back through their browser. You run the authorization-code flow: the person signs in at your booth, you hand the app a short-lived code (a claim-check stub), and the app quietly swaps that stub for the real token out of sight, so the band itself never travels through the browser. PKCE is the one-line proof that the same app which started the handshake is the one finishing it, so a stolen stub is useless to anyone else. And before any band is printed, the person approves what the app may see on a consent screen. (The photo of your seal that you post on the wall, from earlier, is what lets that app verify the band once it holds it.)
This is the same plan, build in small steps, then check loop from the Quick Win, only now aimed at a far bigger target. Nothing new about how you work; just a heftier thing to build. When you are ready, paste:
Read
specs/02-become-the-issuer/spec.mdand theagent-identity-issuerskill. Plan it, show me the plan, then build it in small steps. Build the token verifier as a separate script so the checks are real, and run all the acceptance criteria, especially the adversarial ones.
You will not hand-write the OAuth configuration. The shipped agent-identity-issuer skill carries the verified config, and the spec carries the acceptance checks. Your job is to direct the build and confirm it passes, including the security gates a working-but-insecure version would fail.
You built it; now watch it actually be safe. None of the prompts below have a spec. Each one just makes a single security property visible on your own issuer, one at a time.
First, look at the photo on the wall. Your JWKS endpoint is exactly that wall: the public photo of your booth's seal, posted for anyone to check a band against. The stamp that presses the seal, your private signing key, stays locked in the booth and is never in that photo.
Fetch my JWKS endpoint and show me what's there. Is my private signing key in it? Prove it, and explain why a stranger can verify my tokens but can't forge one.
That gap is the whole point: post only the photo, never the stamp, and the world can verify your bands while no one can forge one.
Next, read a band you just printed, then break it by a single character:
Take an ID token you just issued, decode it, and walk me through every claim,
iss,aud,sub,exp, in plain English. Then change theaudby one character and show me the verifier rejecting it.
Finally, push a band past closing time:
Issue a token, then move the clock past its expiry and try to use it. Show me the exact rejection.
What just happened: you walked behind the counter. The course that taught you to glance at wristbands now teaches you to print them, sealed so a stranger app can trust each one on sight without ever phoning your booth, and you watched the seal, the audience stamp, and the expiry each hold.
3. Scopes and consent
A token should say exactly what it may do, no more. Step 3 adds a scope (what a band is allowed to do, like a colored band stamped drinks only versus drinks and kitchen) and a consent screen where the person sees the exact list before they approve. Least privilege made real: the band carries the narrowest authority that does the job, and a bartender checks it on every order, not just once at the door.
You have run this loop twice now. Here it is again, with exactly one new idea, scope, layered on top of the issuer you already built. Paste:
Read
specs/03-scopes-and-consent/spec.mdand theagent-identity-issuerskill. Plan the approach against our constitution, show me the plan, then build it in small steps. Run the spec's acceptance checks, especially the adversarial ones, before you call it done.
Now prove the limit is real, not decoration. Each prompt below makes you watch the scope hold:
First, hand yourself a narrow band and try to overreach with it:
Issue me a token that has only
notes.read. Now use it to try the write action and show me the exact refusal. Then explain in plain English why a token that signs fine can still be turned away here.
Then look at the approval screen the person actually sees:
Walk me through the
/consentscreen for a client asking fornotes.readandnotes.write. Where do those two lines come from? Prove the screen can only show what the signed request actually asks for, not whatever it likes.
Last, try to grab more authority than you registered for:
Register a client for
notes.readonly, then have it ask fornotes.writeanyway. Show me the granted scope in the token it gets back and point out what is missing, and why.
What just happened: your bands now come in colors. Each one carries the narrowest authority that does the job, and the person saw the exact list before a single band was printed.
4. Connect a real app
Now prove the booth works for someone other than you. A client app is a separate venue that signs people in through you while sharing none of your secrets. Call your issuer AuthCo and the new app Notes. When someone signs into Notes, it sends them to AuthCo's booth, gets a band back, and checks the band's seal entirely on its own against the photo AuthCo posts on the wall. Notes never sees a password and never touches your database.
Same rhythm, new actor. Take a breath: you are not building anything foreign here, just pointing a second, separate app at the booth you already own. Paste:
Read
specs/04-connect-a-real-app/spec.mdand theagent-identity-issuerskill (the register-a-client and verify-a-token sections). Plan the approach against our constitution, show me the plan, then build it in small steps. Keep Notes a fully separate process. Run the spec's acceptance checks, especially the adversarial ones, before you call it done.
Now convince yourself the separation is genuine. Each prompt makes one part of it visible:
First, prove Notes is holding none of your secrets:
Show me everything Notes knows about AuthCo. Prove it has no copy of
BETTER_AUTH_SECRETand no path into AuthCo's database, then explain how it can still verify my tokens.
The answer is the photo again: Notes needs only the public photo of AuthCo's seal to check a band, never the stamp, so it can verify every token while holding none of AuthCo's secrets.
Then break the audience stamp by one character:
Take a token Notes just verified and change its
audby one character. Show me Notes's verifier rejecting it, and explain why that one character is the whole point.
Finally, cut the band off from the booth and watch the next call fail:
Sign me in through Notes, then revoke the client at AuthCo. Make Notes's next call and show me it fails. Explain what "revocable" actually buys me here.
What just happened: a venue you do not control just signed someone in through your booth and trusted the band on its own, holding none of your secrets. The booth works for strangers, not only for you.
5. Connect a resource server
A resource server is a bar that only checks bands and never signs anyone in. That is exactly the bartender you played in Connector-Native Apps, now standing on your own ground. It takes a bearer token, meaning whoever holds the band just presents it and shows no other ID, and it reads the band's audience stamp, good at THIS bar, so a band minted for another bar is refused on sight. The seal here is made with a specific signing algorithm (RS256), and a band sealed any other way is turned away too. It checks each seal against AuthCo's posted photo and never phones the booth, which is exactly what verifying offline via JWKS means in the build prompt below.
By now the loop should feel familiar. One more actor, the bar that only checks bands and serves the person named inside. Paste:
Read
specs/05-connect-a-resource-server/spec.mdand theagent-identity-issuerskill (sections 1 and 3). Plan it, show me the plan, then build it in small steps. Configure AuthCo to sign RS256 tokens audience-bound to my API, stand up a tiny protected resource that verifies offline via JWKS, and run all the acceptance checks including the adversarial ones.
Prove the band only works where it is meant to. Each prompt below turns one rule into something you can see:
First, close the loop with the real connector you built in that course:
Bring back the connector from the Connector-Native Apps Crash Course (or clone its worked example if it is not on my machine). Point its issuer and JWKS settings at AuthCo, sign in, and show me it accept a token my issuer just minted: it should check the
audagainst its own API URL and the seal against my public JWKS, without ever calling me. Explain why the bartender I once played for someone else's tokens now trusts the bands I print.
Now turn back to the small resource server you built here and try to fool it. First, present a band sealed the wrong way:
Sign a token with EdDSA and present it to my RS256-only verifier. Show me the exact rejection, then explain why the issuer's signing algorithm has to match what the consumer expects.
Last, point a valid band at the wrong bar:
Change the audience on a valid token to a different API's URL and show my resource server refusing it, even though AuthCo's signature is genuine.
What just happened: you stood up the bartender from Connector-Native Apps on your own ground. It checks every band, serves only the person named inside, and turns away any band minted for a different bar or sealed the wrong way.
6. Client identity with CIMD (the edge)
Steps 0 through 5 are settled, production-grade ground. Step 6 steps off it. Until now an app proved who it was through client registration: it earned a spot on your pre-approved partner list, vouched for ahead of time. With CIMD (Client ID Metadata Document), the app skips the list. It hangs a public sign at a URL that describes itself, and your booth reads that sign on demand the first time the app shows up, with no pre-registration. This is where the MCP world is heading, but it runs on a Better Auth pre-release plugin and an IETF draft standard, so the course has you confirm the live API before you build.
This is the one place you look things up before you build, because the ground is newer. Take it slow; the prompt itself asks the agent to check the live docs first, which is exactly the right instinct on a moving standard. Paste:
Read
specs/06-client-identity-with-cimd/spec.mdand section 2 of theagent-identity-issuerskill. Before writing anything, query the live Better Auth docs MCP athttps://mcp.better-auth.com/mcpand show me the current@better-auth/cimdAPI, whether I addcimd()or passcimdClientDiscovery()tooauthProvider, and the exact discovery key. Then plan it, show me the plan, move us to the Better Auth 1.7 pre-release channel, and build it in small steps. Run the acceptance checks including the adversarial ones.
Then see what that one change actually switched on. Each prompt makes the new behavior visible:
First, see the new line appear on your public sign:
Show me my discovery document before and after this change, and point at the one new line that tells a client "you can identify yourself by URL." Explain in plain English what that flips on.
Then watch the booth read a sign instead of a list:
Walk me through what happens when a client hands you an HTTPS URL as its
client_id: what do you fetch, what do you read in that document, and how is that different from looking up a row in my database?
Finally, hand it a bad sign and watch it refuse:
Hand my issuer a
client_idthat is a plainhttp://URL, and one with a#fragmenton the end. Show me each one being refused, and explain why the draft insists on a clean HTTPS URL.
What just happened: an app introduced itself by hanging a public sign instead of waiting on your guest list. That is where the agent world is heading, and you built it on ground you can watch moving.
The ~50% milestone: your first project you drive
After the spine, the course stops handing you fully specified, live-verified steps and starts handing you projects you drive yourself. The first one is the halfway mark, and it stays on solid ground.
🔐Project 12-3 hoursHarden your sign-inThe login works. Now make it hard to steal and easy to enter.
You already own a working sign-in. A working sign-in is also a target: one leaked password and someone is in. So you raise the stakes from both sides, with the stable 2fa and social-login specs in the base.
Two new ideas carry this. A second factor is a second proof beyond the password: your doorman also checks a code that only your phone can show, so a copied ID alone no longer gets anyone in. A social login is just a second door, a Continue with Google entrance that lands on the very same membership inside.
Read
specs/projects/2fa/spec.mdandspecs/projects/social-login/spec.md. Plan both, show me the plan, then build them in small steps. Harden the sign-in you already own with a second factor, and add a "Continue with Google" door. Run every acceptance check, including the adversarial security ones.
Done when a correct password with a wrong second factor is refused, a backup code works exactly once, "Continue with Google" lands on the same dashboard as an email-and-password user, and no secret ever shows up in a response body or a log.
What just happened: your door now asks for two proofs and opens from two sides, and a stolen password alone no longer walks anyone in.
The frontier: identity for agents
Now the second half, and the reason the course exists. Every token so far has stood for a human: you signed in, you got a band, apps and gateways trusted it. But the Manufacturing path is about agents that act on their own. So the question turns: when an agent does something, whose band is it wearing? If it just reuses your login, the logs say you did it, it can do anything you can do, and you cannot revoke the agent without locking yourself out. That is the wrong answer, and fixing it is the whole frontier.
Here is the same picture, told as the problem and the fix:
Why an agent needs a band of its ownToday: one master band, photocopiedmaster band · token s_123every agent wears a copyAgent 1s_123 (copy)Agent 2s_123 (copy)Agent 3s_123 (copy)Serversees one shared band.Which agent? Cannot tell.Revoke one? Cannot.Agent Auth: each its own bandHost · a runtime it trustseach agent registers under itagt_1read onlyagt_2transfer, up to $500agt_350 reads / hrServersees the exact agent,its exact limits,and can cut one alone.
Same picture, problem and fix: today every agent wears a copy of your one master band, so the bouncer cannot tell them apart or cut just one. With agent auth, each agent runs under a trusted host and wears its own band, and the server reads exactly who is acting and snips one without touching the rest.
That is the why. The how is one short flow that every agent runs to get its band and use it:
How an agent gets and uses a band1Discoverfind the boothand its house rulesGET /.well-known/agent-configuration2Registerthe host vouchesthe agent in: sendsits key + thecapabilities it wantsunder a trusted host3Approvea human says yes,or house policydecidesdevice code (delegated)/ policy (autonomous)4Signthe agent stampsits own band,fresh each callshort-lived Ed25519 JWT5Verify + runthe bartender checksband, grant, limits,then servesexecute the capabilityDiscover the rules, register under a host, get approved, then sign a fresh short-lived band for every call the server verifies. Steps 1, 4, and 5 are the same for every agent; step 3 is the only fork: a human in the loop, or standing policy.
These three steps run on Better Auth's @better-auth/agent-auth plugin, which is beta, an implementation of the Agent Auth Protocol. The honest framing, kept front and center: treat the specific API as one swappable instantiation of the durable primitives, and pin the version you land on. What does not move is the picture, so keep holding it: the agent is about to get a band of its own.
You do not start from nothing. The base ships a verified worked example for all three steps below (the answer key in worked-examples/ai-identity/), and each step is a spec you drive, the same loop you have run six times.
The agent gets a band of its own
Until now you have been the guest. Here a new guest walks in: an AI agent. The first instinct is to clip it onto your band, but that is exactly the impersonation problem. Instead the agent gets its own band, in its own name, the kind you saw on the right of the picture above where each agent wears a band of its own.
Three things make this different from a human sign-in, and they are the whole idea. First, the agent does not arrive alone; it runs inside a host, a runtime or device the venue already trusts, and the host vouches the agent in. Second, the band is self-sealed and short-lived: the agent signs its own band with its own key, and the band is good for about a minute, so a copied band is stale almost the moment it leaks (very different from a long-lived bearer token sitting in a config file). Third, what the band lets the agent do is a list of named capabilities, the agent's version of scope. You have run this loop before; here it is again, aimed at a new kind of guest:
Read
specs/projects/agent-credential/spec.mdand.agents/skills/agent-identity-issuer/. Confirm the live agent-auth surface against the Better Auth docs MCP first, it is 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.
Now make the new idea visible. First, look at whose name is on the band:
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 band is different from it reusing my login.
Then prove the short-lived, self-sealed band resists theft:
Take my agent's credential and replay the exact same signed band twice. Show me the second call being refused. Explain what the one-time marker is doing and why a band good for only a minute is safer than a long-lived token.
What just happened: the agent stopped borrowing your band and got one of its own. The logs now say the agent did it, the band is in the agent's name, and it carries only the capabilities it was granted.
On-behalf-of: a stamped band
This is the credential most worth getting right. An agent rarely acts purely for itself; usually it acts for a person, and the dangerous shortcut is to let it become that person. On-behalf-of is the honest version: the band names both parties, the agent and the person it acts for, so the action is always attributable to the agent-for-Alice pair, never to Alice alone. That is the stamped band from the opening picture: acting for Alice, drinks only, void at midnight.
The part that makes it safe is human approval in the loop. The agent cannot mint this band for itself. It asks, and Alice gets a prompt (a device-code flow, the same pattern as logging a TV into your streaming account) and says yes before any authority exists. No approval, no band. And because Alice is the source of the authority, she can pull it back: revoke, and the agent's next call fails. Paste:
Read
specs/projects/on-behalf-of/spec.mdand.agents/skills/agent-identity-issuer/. Confirm the live agent-auth surface against the Better Auth docs MCP first, it is 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.
Then watch the human gate actually hold. First, stop before approving:
Have my agent request the right to act for me, then stop before I approve. Show me that it has nothing yet, no band, no access. Explain why "human in the loop" means the approval is the thing that mints the authority, not a formality after it.
Then prove it is delegation, not impersonation:
Approve the grant, then show me the band. Point out where it says both the agent and that it is acting on behalf of me. Explain why that pairing matters for an audit trail.
What just happened: the agent can now act for you, but only after you said yes, only within what you approved, and only until you revoke it. It wears a stamped band, never your band.
Tighten the band: scope, value, and a fingerprint for the dangerous stuff
The stamped band already says drinks only. This step makes the limits as tight as the action deserves, with three ideas that go beyond what a plain scope string can say.
A capability is the named action (the agent may share a note). A value-constraint narrows it to allowed values, not just on or off: not "may share notes" but "may share notes only with @acme.com." A scope string cannot express that; a constraint can, and the server checks it the moment the agent acts, so a share to @evil.com is refused even though the capability is on. And step-up approval scales the human gate to the blast radius: a read auto-grants, a share needs a logged-in human, and an irreversible action (delete everything) needs physical presence, a fingerprint or passkey, so an AI agent that happens to have a browser cannot click approve on its own destruction. That is over $50 needs Alice in the picture, except the truly dangerous action needs Alice's fingerprint, not just her say-so. Paste:
Read
specs/projects/step-up-approval/spec.mdand.agents/skills/agent-identity-issuer/. Confirm the live agent-auth surface against the Better Auth docs MCP first, it is 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.
Now prove each limit bites. First, the value-constraint:
Give my agent the right to share notes, but only with
@acme.com. Then have it try to share with@evil.comand show me exactly where the server refuses it. Explain why a value-constraint is stronger than an on-or-off scope.
Then the step-up gate on the dangerous action:
Try to approve the "delete everything" capability for my agent with just my logged-in session. Show me the server demanding physical presence instead of granting it, and explain what that step-up protects against when the agent itself has a browser.
What just happened: the agent's band is now as narrow as the job: scoped to a capability, pinned to allowed values, and gated harder the more dangerous the action, with the irreversible ones locked behind a human's fingerprint.
A note on maturity (why this is honest, not hype)
The course teaches you to anchor on the durable primitives, the parts that stay true while the tooling churns: a verified sign-in, an agent's own credential, on-behalf-of delegation, least-privilege scope, and human approval. Then it is plain about how settled each layer is:
- The stable spine is production-grade today. Sign-in, the issuer, scopes and consent, connecting a real app, and the resource server all run on the mature, open-source Better Auth stack. The whole spine, plus CIMD, was verified live on the 1.7 line, and the Connector-Native Apps gateway accepted tokens this very issuer signed. The first half is something you can ship.
- CIMD is the edge. It works, and it is pinned and proven, but it lives on a Better Auth pre-release and an IETF draft standard. Expect it to move; re-confirm the API before you build.
- Agent identity is the frontier. Giving an agent its own bounded, revocable, on-behalf-of authority is the direction the industry is moving. Anthropic signalled it with human-agent teams, and Better Auth has an early Agent Auth plugin, but the standards are young and still settling.
That split is the point of anchoring on primitives. When the standards land, the mental model already fits them: a credential is still a band, scope is still what the band lets you do, expiry is still closing time, and human approval is still the person at the booth saying yes.
Where this leads
You now have the through-line for the whole identity layer. Hold any system up to the one question, whose identity is this, and how does authority pass from a human to an agent, and you can read it: find the door, the booth, the band, and the bartender, then ask whether the agent is borrowing a human's band or carrying one of its own.
This is the credential layer under the rest of the Manufacturing path. Next, Build AI Agents gives that agent its loop, the reasoning and tools that decide what to do with the authority you just learned to grant. And in Human-Agent Teams you put this identity to work, running a roster of agents alongside people, each with a band of its own and only the authority it was given.
You stopped borrowing identity. From here on, you issue it.
Flashcards Study Aid
Test Your Understanding
Checking access...