Account Tokens
A sign-in returns an Account Token (the OAuth refresh_token). The personal
agent uses it only at the company's token and revocation endpoints, to sign a
Session in again after its short-lived Session Token expires. The paired
examples run the real AccountTokenClient against Manzanita Outfitters, the
reference company in personal_agent_protocol.demo, with real keys over HTTP
in one process.
The walkthrough:
- Refresh signs the same Session in again (
session_idunchanged) and the company rotates the token. The new one replaces the old in the token store before the call returns. - Two refreshes at once both succeed: the Reactor
pap.accountTokenLockserializes them, so the second presents the token the first rotated in, not the one the company already revoked. - Narrower scopes are granted; wider scopes come back as
re_consent_required, a decision for the user, never a retry. - An expired token draws
invalid_grant; the SDK deletes it and the Session continues signed out. - Revocation signs out every Session signed in with the token. The next
question to the company draws an
authorizationevent again.
The model sees statuses (signed_in, re_consent_required, signed_out),
whether a rotation happened, and scope names. The Account Token, Session
Tokens, client assertions, and DPoP proofs stay host-only, behind opaque
references in Reactor stores.
TypeScript has the same client: new AccountTokenClient({ reactor, fetch }),
with refresh(reference, { context, sessionId, scopes }) and revoke(), and
the lock contributed at AccountTokenLocks.
- Run the Pydantic AI example.
- Run the Agent Runtimes example.
- Read the Account Tokens guide.