Service accounts vs OAuth for agents: choosing the right identity
When you wire an AI agent to an API, the first question is identity: what does the agent present to prove it is allowed to call? Two answers dominate. Service accounts hand you a key that belongs to a machine. OAuth hands you tokens that belong to a user’s consent. Both work, and both fail quietly in different ways — the choice you make at setup determines which failure you get.
What service accounts are good at
A service account is a non-human identity with its own key. It is the right tool when the workload is unattended and the data is not tied to a person. CI pipelines, batch jobs, and backend services that read from a shared bucket are classic fits. The key is long-lived by design, which is a feature: nothing needs to refresh it, and a failed run can be re-run hours later with the same credential.
The problems appear when you stretch the model. Service account keys end up copied into agent configs, mounted into containers, and pasted into .env files. There is no consent step, so nothing stops a key scoped for read-only storage from being reused for something broader. And because the key is long-lived, a leak is standing access until someone notices and rotates it — across every file that copied it.
What OAuth gives you
OAuth ties access to a user and a consent screen. An agent that calls Gmail or Google Drive on your behalf gets scoped, short-lived access tokens, while the refresh token lives at the credential layer rather than inside the agent. The RFC 8628 device flow fits CLI agents well: the user approves in a browser, the tokens never pass through the agent, and refresh happens automatically.
The cost is operational. Tokens expire, refresh tokens rotate, and revoked consent means a human must re-approve. If the agent itself holds the refresh token, you have recreated the service-account problem with extra moving parts: a standing credential the agent can read, plus a rotation cycle it must manage.
A decision rule
Pick service accounts when the identity is the machine and the scope is fixed: build pipelines, batch syncs, infrastructure. Pick OAuth when the identity is a person and the scope is their data: mail, calendars, drives, SaaS APIs.
The harder case is a hybrid — an agent that runs unattended but acts on a user’s behalf. Treat it as OAuth with a refresh loop, and keep the refresh token where the agent cannot read it. A credential broker handles this cleanly: it resolves OAuth entries to fresh access tokens at use time, injects the token into a subprocess environment, and never writes the token to disk where the agent could find it. Its oauth status reports valid, expired, or reauth_required, so a revoked refresh token surfaces as a re-login request instead of a silent failure, and refresh tokens are rotated as single-use on every refresh.
Don’t blur the boundary
The expensive mistake is choosing by convenience: handing a service account key to a personal agent because setup is one API call. You get standing access with no consent boundary, and rotation becomes a manual chore spread across every config that copied the key. OAuth looks like more moving parts, but each part — expiry, refresh, reauth — is a checkpoint where abuse becomes visible.
Service accounts and OAuth are not competitors; they are two ends of a spectrum, and agents increasingly sit at the user-data end. This trade-off is exactly what trustless is built around: a credential broker CLI that keeps both kinds of credentials in the same store and resolves them to short-lived values at use time.
Which identity does your agent use today — and who rotates the credential when it leaks?