1. Provision the session — make login
Provisioning opens a browser, a human signs in once, and the session’s auth-essential subset
(~200 KB: cookies, local/session storage, login data, preferences — never cache or history) is
uploaded to your deployment’s userdata storage.
:6080), waits for you to finish signing in, confirms the
session (it only succeeds after a logged-in validation passes), then uploads. Aborting without
signing in exits non-zero with the login verdict and leaves the storage prefix untouched.
Prerequisite on the machine running it: the aws CLI (the bot image ships it; a desktop needs it
installed).
Use a dedicated account for the bot (a Workspace user like [email protected]), never a
personal one.
2. Configure the deployment to spawn signed-in
Authenticated mode is a deployment property: set it once onmeeting-api and every stock
POST /bots spawns signed-in — no per-request field, no hand-crafted bot config.
POST /bots refuses
with a 503 naming what’s missing — a half-configured deployment never silently spawns anonymous
bots. If the session store is unreachable at spawn time, the bot fails loud with a typed
session-restore error naming the step and endpoint — it never joins signed-out on a failed
restore.
One session, one bot at a time. A second concurrent spawn against the same stored session is
refused with a 409 naming the meeting that holds it. One live cookie jar used from N containers
and IPs at once is a textbook account-risk signal to Google, and concurrent runs would race the
write-back below. Need N concurrent authenticated bots? Provision N accounts under N
BOT_USERDATA_S3_PATH prefixes (today that means N deployments of the spawn knob, one identity
each).
3. Session lifetime — the session stays alive because it is used
Google rotates session cookies continuously during use and re-challenges state that looks stale. A stored session that is only ever read decays with every restore. Vexa therefore closes the round trip: restore freshest → use → write back. On every clean bot teardown, the rotated session is uploaded back to the userdata prefix, so the next spawn restores the freshest state instead of a decaying snapshot. The boundary, stated honestly: write-back runs on clean teardown only. A hard-killed bot (SIGKILL, node crash) never reaches it — the durable copy simply stays at the last successful write-back, and the next clean meeting refreshes it. A write-back failure is an attributed warning in the bot log, never a hang on exit. The levers that make session lifetime a configured property instead of luck:- Workspace session-duration policy — the biggest lever, pure configuration. In Google Workspace Admin, set the bot account’s OU session duration to the maximum (or “never expire”).
- Stable egress and browser — keep each identity on a stable egress IP and a stable bot image version. An identity that hops IPs and browser fingerprints looks cloned.
- Keep-warm — an idle identity decays on Google’s clock. If the account doesn’t meet regularly,
run a periodic authenticated meeting (or simply schedule the bot into a recurring internal
meeting) so rotation keeps happening. There is no packaged keep-warm job today; a cron’d
POST /botsinto a standing meeting is the recipe. - N accounts for N concurrent bots — follows from the one-session-one-bot rule above.
When the session dies anyway — the recovery loop
Eventually a session can decay past recovery (a Workspace policy change, a security challenge, a long idle gap). A bot restoring a signed-out session is reported as a failed meeting (the typedauth_session_missing verdict is landing with the signed-out detection change — until it merges,
the failure surfaces as the join failing to proceed as the signed-in account; see
Troubleshooting). The fix is
always the same one command:
Storage layout and security
- The stored session IS a credential. Anyone who can read the prefix can be the account.
Create dedicated S3 credentials scoped to the userdata prefix for
BOT_S3_ACCESS_KEY/BOT_S3_SECRET_KEY— never reuse the deployment’s admin S3 credentials. - The boundary, stated honestly: the S3 credentials ride the bot’s invocation into the bot
container’s environment (that is how the bot restores and writes back). Anyone with
docker inspecton the bot host, or read access to the runtime API, can see them — which is exactly why they must be scoped to the userdata prefix and nothing else. Secret values are never printed in bot logs. - The session subset is not otherwise encrypted at rest beyond what your S3/MinIO deployment provides.
Availability by deployment surface
- Compose — supported as above; MinIO is in the stack.
- Kubernetes/Helm — set the same
BOT_AUTHENTICATED/BOT_*env on the meeting-api deployment (values → env); point the S3 vars at storage the bot pods can reach. - Lite — the single-container build does not package a userdata store or the provisioning flow; authenticated mode is not available on Lite today.