1

I can obtain an access token for a service account using

gcloud auth print-access-token --impersonate-service-account=<my-service-account>

Assuming I have such a token from somewhere (e.g. in an environment variable), how do I use it to authenticate with e.g. the Google Cloud Storage Client SDK?

I've looked through documentation of various packages in the Google Auth package, but I've found none that seem to accept a token as an authorization method.

Tomas Aschan
  • 58,548
  • 56
  • 243
  • 402

2 Answers2

0

I'm not sure access token is enough for the Python SDK if you take a look at the code you need to supply more config data such as project-id and more... (also possible to set via environment but needs to be done). Generally if you are setting all the correct env vars auth should work using the token.

What is the error you are getting maybe you are missing some other config?

CloudBalancing
  • 1,461
  • 2
  • 11
  • 22
  • I've had trouble even finding a `Credentials` subclass that can accept the token as a parameter. Now I've tried with `google.oauth2.credentials.Credentials(token)`, which seems to work fine when I try it locally, but in the Docker container it says `Could not automatically determine credentials. Please set GOOGLE_APPLICATION_CREDENTIALS or explicitly create credentials and re-run the application.` – Tomas Aschan Oct 21 '20 at 11:19
  • Hmmm, as suspected it seems that it requires the full JSON configuration file... Try run on your local machine after you remove the env var of - GOOGLE_APPLICATION_CREDENTIALS... It should fail as well... you need to authenticate your docker - does it have cloud sdk on it or anything besides the env var of the token? Did you run the `gcloud auth print-access-token --impersonate-service-account=` from within the docker? – CloudBalancing Oct 21 '20 at 11:26
  • No; `gcloud auth print-access-token ...` is run outside of Docker. The container has `gcloud` installed (or, I can add it if I need to) but it does not have a full JSON key file. The problem I'm trying to solve is to authenticate inside the container by giving it only a token (which expires) instead of a key file (which does not). The main reason for this is that the execution environment (Flyte) does not let me mount anything or set environment variables, so I have to embed the auth stuff in the container. – Tomas Aschan Oct 21 '20 at 11:57
  • I'm a bit confused, if the command is being run outside of Docker and you cannot mount/set env vars - what do you do? I see, I'm not too experience with this kind of environment... What I'm going to suggest as last resort is very bad practice, but I can guess you build the docker from within some repository and you can have an encrypted JSON there with the relevant data - the when building the docker make sure to include the relevant file and make sure make a Docker command to decrypt and set the `GOOGLE_APPLICATION_CREDENTIALS` location... – CloudBalancing Oct 21 '20 at 12:34
  • If you are using some CI/CD build system it is even better to set it from there...but Generally you have to authenticate in some way from within the Docker... – CloudBalancing Oct 21 '20 at 12:41
  • I'm building a Docker container that will run Flyte tasks - and Flyte has no way to mount extra things or set environment variables in task containers. In other words, I'm not the one starting the container, and I don't have any power over how the container is started. – Tomas Aschan Oct 21 '20 at 13:34
0

I've been able to get and use a GCloud Access Token in python as follows (process owner needs the Service Account Token Creator permission for that service):

from google.cloud.iam_credentials_v1 import IAMCredentialsClient
from google.oauth2.credentials import Credentials
import googleapiclient.discovery

response = IAMCredentialsClient().generate_access_token(
    name=f'projects/-/serviceAccounts/{service_id}',
    scope=['https://www.googleapis.com/auth/gmail.insert'],
)
service = googleapiclient.discovery.build(
    'gmail',
    'v1',
    credentials=Credentials(response.access_token), <= use your token here
)

Unfortunately, I'm having trouble setting up Domain-wide delegation with this syntax.

Arnaud P
  • 12,022
  • 7
  • 56
  • 67