Sessions and credentials
Tokens, passphrases and authorized sessions: which one a person, a script and an MCP server should hold, how each is renewed, and how each is taken back.
The service admits three kinds of credential, and each fits one kind of caller.
| Credential | Who holds it | Lasts |
|---|---|---|
| Machine token | a script, a service | until revoked |
| Passphrase | a person | until an administrator sets another |
| Authorized session | an MCP server, a long-running agent | renews itself |
A token is a login, and a login ends
A login lasts eight hours and nothing extends one, so an MCP server started with a token alone stops working within the day and says only that the token does not admit anyone. Give a long-running server a session instead and it keeps itself alive.
Authorize a session
Authorizing is a person's act and takes a browser:
tessari-am authorize # or --at http://<the HTTP surface>
It prints a URL and opens it; a page asks who you are and what you are approving,
and what comes back is kept at ~/.tessaridb/session, created 0600. A server
started afterwards needs nothing else. A server that holds nothing says exactly
that, so an agent knows what to ask a person for.
Claude Code and Codex connected over HTTP (see Getting started) do this through the client's own sign-in and need no command.
Unattended installations
Where nobody can click anything, an operator issues a refresh credential once:
tessari-am admin credential.refresh --user u-… --at <identity>
export TESSARI_AM_REFRESH=tam_… # in the server's environment
The credential is spent the first time the service renews and replaced with
a new one, which is what makes presenting an old one detectable as a replay. The
live one is written to TESSARI_AM_SESSION (or ~/.tessaridb/session), and that
file is what the next start reads.
- Delete the file and the service needs authorizing again.
- Restore an old copy and it is a replay: the whole chain is withdrawn, on purpose.
A renewal that is refused — expired, withdrawn, narrowed or already spent — ends the session and is never retried. A plane that cannot be reached is not a refusal: a login already in hand keeps working until it expires.
Signing in with a passphrase
A person exchanges a name and a passphrase for an eight-hour login. The
passphrase is read from standard input and is never an argument — --passphrase
is refused by name, because another user's ps and the shell history both see
arguments:
printf '%s' "$passphrase" | tessari-am sign-in --name ada > credentials
export TESSARI_AM_TOKEN=$(head -1 credentials)
Standard output carries two lines: the login to present, and the credential to
hand to renew when the login runs out. An unknown name and a wrong passphrase
give the same answer, at the same cost.
Taking a credential back
tessari-am admin credential.revoke kills one credential and every login it
minted, and leaves everything else the same person holds alone. It takes the
identifier — the part of the token between tam_ and the last underscore — so a
live secret never reaches a shell history.
Setting a new passphrase revokes the old one and every login minted from it in the same statement; the user's machine tokens are untouched.
Prompt, not instant. A call already in flight was authorized a moment before and finishes; what is refused is the next call.
Not there yet
- Nobody can change their own passphrase: an administrator sets it. There is no reset by email.
- There is no way to mint a replacement token for an existing user, so the sequence after a leak is revoke, then add a user.
- Nothing lists issued credentials.