You sign in to Latere once, and every latere command reaches its
product with your identity. This page explains what latere login
puts on disk, how each product gets the credential it needs, how the
CLI keeps you signed in, and what latere logout tears down.
The shape to keep in mind: one human login to auth mints a root
token; each product call derives the credential that product
accepts from that root. The owning identity (your org_id and sub)
is constant across every hop, but the token presented changes at each
product boundary, and a token minted for one product is never replayed
at another.
latere loginThis runs the OAuth 2.0 device authorization flow (RFC 8628) against
auth.latere.ai. The CLI prints a verification URL and a user code,
opens your browser, and waits while you approve. On approval, auth
returns your root token and the CLI writes two files under
~/.config/latere/.
latere login --org-id <org-uuid> # sign in scoped to an organization
latere login --personal # sign in in your personal context
latere login --no-browser # print the URL instead of opening a browser| File | What it is | Used for |
|---|---|---|
~/.config/latere/auth-token.json |
The auth root token: an auth.latere.ai-issued access token plus its refresh token. |
The source every per-product credential is derived from. Never presented to a product directly except by the Drive git helper (below). |
~/.config/latere/token.json |
The Cella bearer: a Cella-issued catalog token, labeled CLI on <hostname>. |
latere cella ... and latere whoami. |
The split is deliberate. The two tokens have different issuers
(auth.latere.ai for the root, Cella for the bearer) and different
lifetimes, so they live in separate files. The root token can mint
new per-product credentials long after any single product bearer has
expired.
Both files are written with 0600 permissions.
Every product call starts from the auth root token and derives what that product accepts. The derivation differs by product because the products validate differently.
latere cella presents the Cella bearer from token.json. That
bearer is minted through a two-step chain at login and whenever it
needs refreshing:
- Mint a short-lived actor token at auth (
POST /actor-tokens, audiencesandboxd, 60-second TTL), presenting the root token. - Exchange that actor token at Cella (
POST /v1/tokens/exchange) for a catalog bearer labeledCLI on <hostname>.
Cella replaces any previous row with the same label, so repeated exchanges rotate the bearer rather than piling up catalog entries.
For CLI-initiated model calls (latere lux invoke, models, usage,
access), the CLI mints a fresh actor token at auth with audience
lux.latere.ai and a 5-minute TTL, then presents it to Lux for that
one call. The call finishes in seconds, so the short lifetime bounds a
leaked value at no cost to you.
When you export your identity for a stock SDK, the default is your longer-lived identity token so an SDK session survives:
eval "$(latere lux env --compat openai)" # identity token (lasts the login session)
eval "$(latere lux env --compat openai --ttl 1h)" # a short-lived actor token instead (CI)lux env needs a surface: either --compat <dialect> or a passthrough
provider argument. See the "Models (Lux)" page for the full surface.
latere login also wires a git credential helper scoped to the Drive
host (drive.latere.ai) in your global git config, so
git clone https://drive.latere.ai/git/me/<repo>.git authenticates
with no token in the URL. When git asks the helper for a credential on
that host, it answers with your auth root identity token (refreshed if
expired), which Drive validates as an auth-issued JWT. The latere drive file commands present the same identity token.
latere git-credential setup # wire the helper manually
latere login --no-git # sign in without touching git configThe helper answers only for the Drive host. store and erase are
no-ops: your tokens live in ~/.config/latere, managed by latere login and latere logout, never in git's own credential store.
The CLI refreshes tokens near expiry so a long session keeps working without re-login.
- Auth root token. When the root token is within a minute of
expiry, the CLI refreshes it against auth using the stored refresh
token, requesting the exact same scope set it requested at login (so
a refresh can never silently drop a scope). The refreshed root and
its new refresh token are written back to
auth-token.json. - Cella bearer. When the bearer in
token.jsonis near expiry, or a Cella call comes back401, the CLI re-runs the mint-and-exchange chain from the root token (refreshing the root first if it too is near expiry) and writes the replacement bearer back. This happens at most once per command, transparently, before your call is retried.
Because every product credential derives from the root token, keeping
the root refreshed keeps every product reachable. The one exception is
a paste-mode login (latere login --token <token>): that supplies an
access token with no refresh token, so the CLI cannot refresh it. When
it expires, run latere login again.
latere logoutLogout revokes your session on the server, not just the local files:
- It revokes the Cella bearer at Cella (
DELETE /v1/tokens/current), so the catalog token dies immediately instead of lingering until its TTL. - It revokes the auth refresh token at auth (
POST /revoke, RFC 7009), so the root credential can mint no further tokens. - It deletes
token.jsonandauth-token.json.
Server-side revocation is best-effort. If a server cannot revoke (for example it is unreachable), the CLI prints a note, still clears your local files, and the affected token expires on its own. Local sign-out always completes.
The CLI is one consumer of the Latere identity fabric, and it holds the fabric's core rule:
Authority always derives from the owning user (
org_id,sub); the acting identity changes at each boundary but the owner is constant; a product's own tokens never cross into another product (cross-product hops carry auth-issued delegated tokens).
In CLI terms: you log in once to auth to obtain the root. Every product
call derives its credential from that root. The Cella bearer is only
ever presented to Cella; the lux.latere.ai actor token is only ever
presented to Lux. When a call crosses a product boundary, it carries an
auth-issued token (the root itself, or an actor token minted from it),
never a bearer minted for some other product. Whichever token is on the
wire, the owner it acts for is you.
Two commands hand a raw token to your own scripts. They are deliberate escape hatches, outside the managed refresh flow above:
latere print-token # print the Cella bearer from token.json
latere login --token <token> # save a pasted access token (no refresh)| Setting | Purpose |
|---|---|
--auth-url / AUTH_URL |
Override the auth base URL (default https://auth.latere.ai). |
--api-url / SANDBOX_API_URL |
Override the Cella API base URL, from which the auth URL is derived. |
DRIVE_HOST |
Override the Drive host the git credential helper answers for. |
- Auth: "Identity, delegation, and token exchange" covers the device-code flow, the root token, actor tokens, and revocation from the auth service's side.
- Cella: "Sandbox identity, egress, and agent grants" covers how the Cella bearer arrives through token exchange and what it grants inside a sandbox.
- This repo:
latere luxdetails in "Models (Lux)", and Drive git access in the main README. Start any of these withlatere login(see Sign in).