Authenticating an installed CLI with OIDC and a Third Party Client

The google cloud SDK provides a convenient mechanism for authenticating their CLI by opening a browser and doing an OAuth2 token exchange which redirects back to a temporary web server running on localhost. You can find the meat of the implementation here: oauth2client/ at master · googleapis/oauth2client · GitHub

Digging into the source code of the google cloud SDK I found that they actually just hard coded a client_id and client_secret into the application. They call this method out here: GitHub - googleapis/google-api-python-client: 🐍 The official Python client library for Google's discovery based APIs.

The above documentation states: “The client ID and client secret obtained from the API Console are embedded in the source code of your application. In this context, the client secret is obviously not treated as a secret.”.

Is it safe / possible / appropriate to use the new OIDC compliant Third-Party Clients to safely embed a client id and secret to enable CLI based web flow token generation?

You should be using PKCE which removes the requirement of having to store secrets on the client. You can read more about that at Call Your API Using the Authorization Code Flow with PKCE

Digging deeper, it looks like Call Your API Using the Authorization Code Flow with PKCE is likely they way to go in this scenario. This way I don’t need to embed a secret in the CLI. I assume I should still be setting the is_first_party option to false. In situations where the user can’t complete a web flow, I can allow them to generate their own third party client, download the id and secret, and use the Client Credentials Grant for non-interactive situations.

Man, this is complicated… Makes me just want to use good old “insecure” API keys.

I have a very similar question.
We have a series of SDKs that clients use to interact with our application. Most of these SDKs are just libraries used to run reporting scripts. Most of the time these are expected to be backend processes - ones that can’t have the user interact with a browser to authenticate every 24 hours. What’s the best practice here?

Do we:

  1. Encourage users to save their username/password in environment variables, and ‘hack’ the authorization code process to not use a browser?
  2. Encourage all API clients to get their own Client ID/Secret, or use one Client ID/Secret+PKCE for all downloads of the SDK?

I should add that we can’t use client credentials grants because they’ll be performing actions as a user - not a service.

1 Like