oauth2l: printing Google OAuth tokens for shell scripts
oauth2l ("oauth tool") is a simple CLI for interacting with Google API authentication.
At a glance
- What is it?
- oauth2l is an Apache 2.0 licensed Go command line tool from Google that fetches and prints OAuth 2.0 access tokens for user accounts and service accounts, resolving credentials from the environment, from gcloud, from a key file or from an external single sign-on command. The judgement is that the tool is small on purpose, with three libraries behind it, and that the removal of its web command in version 1.3.6 tells you the maintainers are trimming it to a shell-oriented scope.
- Who is it for?
- oauth2l fits a script or a CI job that has to call a Google API with a token it should not be handling itself, because the credential resolution works through the environments where the tool usually runs, the GCE and GKE metadata server, an active gcloud session, or a key file, and the output is designed to be piped into curl rather than parsed.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 20 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A token printer rather than a client library
oauth2l, pronounced as the oauth tool, is a simple command line tool for working with Google OAuth 2.0, written in Go. The readme states its primary use plainly: to fetch and print OAuth 2.0 access tokens, which can then be used with other command line tools and shell scripts.
That framing is the design decision. This is not an SDK and not a client library, it is a program whose entire job is to produce a token string on standard output and get out of the way. Everything else in the readme follows from that, the header command that emits an HTTP header, the curl command that does the request for you, the test command that turns a token into an exit code.
The tool is published under the Apache 2.0 licence and lives in the Google GitHub organisation, and the repository is a small Go project with a main.go, a util directory, a vendor directory, an integration directory, a python directory, a Dockerfile, a Makefile and a cloudbuild.yaml.
The release history shows the trimming. Version 1.3.4 was published on 2026-07-27, 1.3.5 on 2026-08-20 and 1.3.6 on 2026-10-02, and the last of those is titled Removing support for web command. A command that fetched a token for a browser session has been taken out, which narrows the tool to the case it is good at.
The credential chain is the interesting part
The tool supports all the Google OAuth 2.0 authentication flows, for both user accounts and service accounts, in different environments, and the readme lists the resolution rules.
When running inside Google Compute Engine or Google Kubernetes Engine, it uses the credentials of the current service account if one is available. When running in a user context that has an active Google Cloud SDK session, it uses the current gcloud credentials. Those two are the invisible cases, and they are the reason the tool earns its place in a script, because the caller does not have to know which of them applies.
The explicit cases follow. With the command option --credentials pointing at a JSON credential file downloaded from the Cloud Console, the file can be either a service account key or an OAuth client ID, and the tool uses it to start an OAuth session. With --type jwt --audience and a service account key, a JWT token signed by that key is generated instead of an access token, which is the self-signed token a service calls another service with. And with --type sso --email, the tool invokes an external sso command to retrieve a single sign-on access token, so the SSO handshake is delegated to whatever your organisation already uses.
Caching is on by default. Retrieved tokens are stored in ~/.oauth2l, the location can be overridden with --cache, and setting the cache location to the empty string disables caching entirely.
fetch, header and curl are the three that matter
The command set is small, and the three that do the work are variations on one idea.
fetch prints an access token for the requested scopes and nothing else:
$ oauth2l fetch --scope userinfo.email,cloud-platform
ya29.zyxwvutsrqpnmolkjihgfedcbaheader does the same thing but in HTTP header format, which is the form the readme says it is designed for use with the curl command line tool:
$ oauth2l header --scope cloud-platform
Authorization: Bearer ya29.zyxwvutsrqpnmolkjihgfedcbaThe pattern that makes it useful is the command substitution into a curl invocation, where the header command is evaluated inside the quoting of the curl flag:
$ curl -H "$(oauth2l header --scope pubsub)" https://pubsub.googleapis.com/v1/projects/my-project-id/topicscurl is a shortcut that fetches a token and then uses it to make a request, through /usr/bin/curl by default, with any flags after a double dash treated as curl flags:
$ oauth2l curl --scope cloud-platform,pubsub --url https://pubsub.googleapis.com/v1/projects/my-project-id/topics -- -iBoth header and curl support domain-wide delegation, where you pass the email of the user to impersonate and a service account credential file, which is the mechanism for a service to act on a user's Gmail data. The readme gives a Gmail labels listing as the worked example.
info, test and reset exist for the pipeline around the token
The remaining commands are about handling a token you already have, and they are the ones that make the tool usable in a script rather than only at a prompt.
info prints information about a valid token, and it always includes the list of scopes and the expiration time. If the token carries either the userinfo.email scope or the plus.me scope, it also prints the email address of the authenticated identity, so you can assert that a token belongs to the account you expected:
$ oauth2l info --token $(oauth2l fetch --scope pubsub)
{
"expires_in": 3599,
"scope": "https://www.googleapis.com/auth/pubsub",
"email": "[email protected]"
...
}test is the one to put in a conditional. It sets the exit code to 0 for a valid token and 1 otherwise, and it prints that exit code as well, so a shell script can branch on it:
$ oauth2l test --token ya29.zyxwvutsrqpnmolkjihgfedcba
0
$ oauth2l test --token ya29.justkiddingmadethisoneup
1reset clears the local cache, which is where previously retrieved tokens live in the file ~/.oauth2l by default. It is the command you want after a permission change, when the cached token still carries the old scopes and the new call keeps failing in a way that looks like a network problem.
Four installation paths and one documented mismatch
The distribution story is thorough, which is what you expect from a tool meant to be dropped into scripts.
There are pre-compiled binaries for Darwin on amd64 and arm64, for Linux on amd64 and arm64, and for Windows on amd64, published under a storage.googleapis.com path. To get an older version you substitute latest with any tag you like, omitting the v prefix, with 1.3.1 given as the example.
Homebrew is supported with brew install oauth2l, with a caveat that new releases may not be immediately available because of propagation delay, which is a real operational detail for a tool whose releases are the trigger for automation.
There is an official Docker image at gcr.io/oauth2l/oauth2l, and the readme shows both running it directly and copying the binary out of it into another image with a COPY --from line. The image tags match the repository tags without the leading v, and master builds use latest.
For everywhere else, the minimum requirements are Linux or Mac and Go 1.10.3 or higher, with the nice to have of adding the GOPATH bin directory to your PATH. The build is a clone, a cd and a make dev, and then oauth2l fetch with your credentials file and a scope.
That Go version deserves a second look, because the go.mod in the repository asks for Go 1.26 with a toolchain line of go1.26.6. The readme's 1.10.3 floor is a leftover, and the module file is the one that describes the current requirement.
Three libraries, one of them for flags
The go.mod is a good indicator of how little this tool does.
The module is github.com/google/oauth2l, and the direct requirements are three: golang.org/x/oauth2 at version 0.28.0, which is the actual OAuth 2.0 implementation, jessevdk/go-flags, which is a struct-tag driven flag parser and explains the style of the command options in the readme, and github.com/google/uuid, which is there for the token identifiers. There are indirect requirements as well, the compute metadata package for the GCE and GKE detection, go-cmp and the system package, none of which the tool uses directly.
A single OAuth library and a flag parser is the whole design. There is no HTTP framework, no database, no configuration format and no plugin system, which is the right shape for a program that is meant to be a dependency-free line in a shell script.
The repository also vendors its dependencies, with a vendor directory in the tree, which is a common choice for a binary that has to build in a sealed environment, and the presence of a cloudbuild.yaml tells you the release binaries are built by Google Cloud Build. There is an integration directory and a python directory alongside the Go code, which is where the end-to-end tests and the helper scripts for driving the tool live.
Editorial conclusion
oauth2l fits a script or a CI job that has to call a Google API with a token it should not be handling itself, because the credential resolution works through the environments where the tool usually runs, the GCE and GKE metadata server, an active gcloud session, or a key file, and the output is designed to be piped into curl rather than parsed. It is the wrong choice if you need a long-running service that holds a token and refreshes it, since the tool prints a token and exits, and it is the wrong choice if you need a non-Google provider. Before you adopt it, read the credential resolution order in the readme, because the difference between picking up the gcloud session and picking up a key file is the difference between a token scoped to your user and one scoped to a service, and check the caching behaviour, because tokens are written to a file in your home directory by default.
Frequently asked questions
What is oauth2l?
It is a Go command line tool from Google for working with Google OAuth 2.0, whose primary use is to fetch and print access tokens that can be used with other command line tools and shell scripts. It is published under the Apache 2.0 licence.
Where does oauth2l get its credentials?
In order, from the current service account when running inside Compute Engine or Kubernetes Engine, from the active gcloud session in a user context, from a JSON credential file given with --credentials, from a service account key with --type jwt --audience, or from an external sso command with --type sso --email.
Does oauth2l cache tokens?
Yes, by default retrieved tokens are cached in ~/.oauth2l. The location can be overridden with the --cache option, and setting the cache location to an empty string disables caching. The reset command clears the cached tokens.
How do I use oauth2l with curl?
Either substitute the header command into the curl flags, with curl -H "$(oauth2l header --scope pubsub)" followed by the URL, or use the curl shortcut, which fetches the token and makes the request itself and treats any flags after a double dash as curl flags.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/google-oauth2l)Was this useful?