Skip to Content
ConceptsPer-person tokens

Per-person tokens

A connection normally holds one token: the organisation’s. Every call an agent makes on that platform runs as that one account, and the platform’s own audit log says the organisation did it. That is fine for a bot with one job. It is wrong for an agent that acts for many people, a support assistant answering as each staffer, a scheduling agent booking each consultant’s calendar, an agency’s assistant working inside each client’s mailbox.

Per-person tokens let that agent hold one upstream token per person on a shared connection. The agent says who the call is for; the person authorizes the platform once, on a hosted page, choosing their own account; from then on every call the agent makes for them runs as them.

Available on the Team plan and above. Set it under Connection mode in the dashboard, per platform.

How the agent says who it is for

Every governed call may carry a caller, as a header or in the body:

X-AV-Caller: jwt <token> # verified: a JWT from an identity provider the organisation registered X-AV-Caller: id <source>:<id> # asserted: an opaque id the agent holds, e.g. id slack:U0123

or on POST /v1/actions and the MCP use_platform / read_platform / write_platform / delete_platform tools:

{ "caller": { "assertion": "<jwt>" } } { "caller": { "source": "crm", "id": "42" } }

A verified caller is a JWT whose issuer the organisation has registered (Clerk is trusted for every organisation without setup; any other issuer is added with its JWKS URL under Connection mode). The proxy checks the signature and takes iss + sub as the identity. An asserted caller is whatever the agent says. By default a platform honours verified callers only; an admin can tick accept ids the agent asserts for platforms where the agent is the system of record for who is who.

The proxy never stores the id. It is turned into a salted, keyed hash per organisation the moment it arrives, and only the hash reaches the vault, the audit log and the dashboard. The same person at two organisations is two unrelated hashes. Deleting the organisation’s salt de-identifies every per-person row at once.

The three modes, per platform

ModeA call with a consented personA call with a person who has not consentedA call with no caller
Off (default)organisation tokenorganisation tokenorganisation token
Preferredthe person’s tokenorganisation tokenorganisation token
Requiredthe person’s token412 consent_required, with the consent link412 consent_required

Start with Preferred while people authorize, then switch to Required for platforms where sending as the organisation would be a mistake.

When a person has no token yet on a Required platform (or the agent asks ahead with POST /v1/consent/caller/start), the response carries a consent_url: a hosted page at app.agentvalet.ai/consent/person?token=... that needs no AgentValet account. The person opens it, presses Authorize, signs in to the platform with their account, and the token is vaulted under their hash. The agent polls poll_url or simply retries.

The link is single use, lasts 30 minutes, and can only ever produce a token stored under the hash it was minted for: a forwarded link cannot make Bob’s token appear as Alice’s.

What the audit shows

Every governed row the call writes carries caller_hash and caller_verified, the signed receipt carries the same, and an approval held for a person is replayed on that person’s token, never the organisation’s. The dashboard shows how many people hold a token per platform, never who. An admin revokes a person by entering the id once (it is hashed on the server and not kept) or revokes everyone on a platform when offboarding.

Honest limits

  • Only platforms connected through the OAuth connect flow support per-person tokens. API-key platforms and remote MCP servers do not, yet.
  • Per-person platforms use platform-wide grants: a person’s token is never a grant target, and per-connection grants on such a platform fall back to the organisation token.
  • The person is only as real as the caller assertion. Verified means a signed login from an issuer the organisation trusts; asserted means the agent said so.
  • Names are not stored unless an admin turns on identity storage for the organisation; by default the dashboard cannot tell you which person a hash is.
Last updated on