Automating agent logins: from OAuth to ssh-agent
Your agent needs to call the Google API, push to GitHub, or pull from a private registry — and nobody is going to type a password for it. Automating logins for agents means solving two problems at once: obtaining the credential without a human in the loop, and keeping it out of the agent’s hands once you have it. The solutions that work borrow from two older designs: OAuth device flow and ssh-agent.
OAuth device flow: login without a keyboard
RFC 8628 device flow exists for exactly this scenario. The client — your agent, running headless — asks the authorization server for a device code and a user code, then polls a verification endpoint while a human approves the login on another device. No password ever reaches the machine running the agent. This is how CLIs for Google and Lark-style services log in, and it maps directly onto agent authentication.
The operational details separate a working flow from a flaky one. Tokens should be stored compactly as single-line JSON entries, refreshed automatically before expiry, and rotated: a refresh token that is single-use and replaced on every refresh means a stolen token is only useful until the next refresh. A failed refresh with invalid_grant should never be retried — retrying a dead grant wastes time and obscures the real problem, which is that the user revoked access or the session expired. A status field that distinguishes valid, expired, and reauth_required tells your automation whether to continue, refresh, or alert a human.
ssh-agent: the credential broker pattern
ssh-agent solved this decades ago. Your private key never lives in the process that needs it; the agent process holds the key in memory, and SSH clients ask it to perform operations on their behalf. The machine can be compromised and the key material still is not extracted. That is the credential broker pattern, and it generalizes far beyond SSH.
The lessons transfer directly. Credentials should be resolvable on demand rather than stored where agents can read them. Sessions should be scoped: an agent gets access to specific keys for the duration of a task, not a lifetime of credentials. And failure should be loud — if a session key is invalid, the tool should refuse rather than fall back to a weaker path.
What this looks like for agents
Concretely: a broker CLI that holds the credentials, plus commands that hand the agent a scoped, time-limited access token. For SSH-style access, the broker behaves like an agent itself — keys stay in the store and operations happen through the broker. For OAuth, the broker implements the device flow, persists the tokens, and refreshes them on a schedule, so your cron job or agent loop never thinks about logins at all.
The trustless CLI implements exactly this pairing. trustless oauth login drives the device flow end to end, trustless oauth refresh and status manage the token lifecycle, and the underlying store is a standard password store rather than a new vault format. Session keys are passed through the BW_SESSION environment variable, never as a command-line argument, and invalid sessions fail closed. If you want to read the implementation, the repository is at https://github.com/ikkun1222/trustless.
The pattern is proven: a ticket, not a password; a broker, not a keyring inside the agent’s memory. Next time your agent fails to authenticate at 3 a.m., ask yourself — was the flow at fault, or was it the token lifecycle?