How to invoke gcloud with service account impersonation - google-cloud-platform

I have a service running in GCE with default service account A. This service uses gcloud to talk to various GCP services. Currently, it uses service account B to talk to some of the GCP services (using private key). However, we want to get rid of using private key and use account impersonation. To do that, I have added account A to the service account B's role and given token creator role.
I wrote a test program in go and was able to verify the impersonation works. However, our service is in PHP, and uses gcloud SDK. I couldn't find a way to configure gcloud to impersonate a service account or provide custom token.
One option is that I rewrite all the gcloud code to use google SDK, but that is lots of work, and I'd rather avoid that. My question is, how do I invoke gcloud using service account B in this scenario?. Is there a way to pass access token to gcloud or specify impersonation user?

gcloud has a --impersonate-service-account flag for this.

Run gcloud auth login and login using your gcp email address.
Run export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token --impersonate-service-account=<sa-name>.iam.gserviceaccount.com) command to generate temporary credentials from the service account and store as the current OAUTH token. (this OAUTH token only lasts for 1 hour so make sure the operation using this token can complete within that time frame.

Related

Google cloud gcloud enabling API services for service account email

How do I enable API services specifically for a service account and not a user account?
Context: I'm using a Python script to locally test a cloud function (query BQ, convert results to json, drop in GCS bucket). I can do this fine with my own test account where I'm able to enable services, but not sure how I would do it (or how a client would go about doing it) for a client's service account. This is how I do it for my own service account:
Get service account credentials as json
Follow installations for gcloud cloud sdk
Issue: gcloud auth activate-service-account --key-file="/path/to/json-todd-credentials.json" --project="json-todd"
Enable API services like so: gcloud enable --account="json-todd#json-todd.iam.gserviceaccount.com" cloudfunctions.googleapis.com pubsub.googleapis.com etc.
I have the client's service account json and I can auth activate-service-account the service account but I can't enable because I don't have permissions - but how would the client enable APIs it specifically for a service account on GCP without having to install/initialise/auth the service account in the way above?
There is a misunderstanding I think. The API are enabled for a project, not for a service account (or a user account). Then, you have permissions to access to the API that you have activated.
If you have a service account, on a new project, without the API enable, there is no issue to grant this service account with the roles/serviceusage.serviceUsageAdmin. Like this, the service account will be able to activate the API on the project, possibly, ALL the API. BUT if the service account has only the permission to access to BigQuery (for example) and the service account activate the compute engine API, it won't be able to access to VM, even if, the API is enabled.
At the opposite, if the API are already enabled on the project, the service account doesn't need to have the roles/serviceusage.serviceUsageAdmin role granted, only the permission to use the activated API.

How to set Google Cloud application credentials for a Service Account

The following command allows you to set your default credentials:
gcloud auth application-default login
It opens up a window (unless you use --no-launch-browser) and allows you to connect your account. It creates a local json file that contains your credentials, which will be picked up when an application uses the Google Cloud SDK.
However, if I'd like to set my application credentials to a service account as follows:
gcloud auth application-default login \
--impersonate-service-account=saname#project.iam.gserviceaccount.com
This still allows me to authenticate in the browser, but it seems to load the credentials for my user account, not for the service account.
Is there anyway to achieve this? I.e., service account set as application default, without the need for a service account file.
Note: I do have the rights to impersonate the Service Account
gcloud auth application-default login uses the active|specified user account to create a local JSON file that behaves like a service account.
I assume -- correct? -- that, even though your user account is permitted to impersonate the ServiceAccount, using your user account as ADC does not work. I don't know why that is.
The alternative is to use gcloud auth activate-service-account but, as you know, you will need to have the service account's credentials as these will be used instead of the credentials created by application-default login.

Authenticate to GCP using a Google Account, without launching a browser

TL;DR
Can anyone suggest a way that I can run tests as a named user that isn't a service account within a CI pipeline?
Detail:
We provide an application running on GCP, the stakeholders of which are all users internal to our organisation. Those users' identities are mastered in our on-premises ADFS implementation and are synced to GCP so that they can be used for authentication.
We authorize access to various parts of the application using ADFS groups that those identities can be added to and again, we sync those group memberships to GCP. The groups are available as Google Groups (https://groups.google.com). At runtime we check whether the authenticated user is a member of a given group. This all works fine.
I would like to run tests in our CI pipeline that ensure that an authenticated user can do the things they're allowed to do and can't do the things that they're not allowed to do. Here are some of the tests I would like to run:
* Ensure gsutil ls allowed-bucket returns an expected list of blobs
* Ensure gsutil ls non-allowed-bucket cannot access the named bucket
* Ensure a cloud function can be called via gcloud functions call function-name
Thus I need to programatically (i.e. without human intervention) authenticate as a user that is a member of a given Google group. I came up with two possibilities:
Using a service account and authenticating using gcloud auth activate-service-account --key-file /path/to/keyfile.json but I cannot find a way to add a service account to the appropriate Google Group - so that option won't work
Preparing a non-privileged user in our on-premises ADFS that we then add to the appropriate Google Group. Unfortunately I don't think there's a way to authenticate as that user without human intervention because gcloud auth login uses a web-based authorization workflow. If it requires human intervention then I can't use it in a CI pipeline.

is there a way to use your current credentials to assume a service account instead of having to use the json key?

My personal account is an admin in my gcp project.
If I want to use one of the service accounts I have created (from my local laptop) I do this:
gcloud auth activate-service-account --key-file=some-service-account.json
But I wonder, if I already have my own admin account active, is there a way to just assume a service account without the key? Can GCP use my current creds to give me access to assume that service account?
If so this also makes me wonder if I can use service accounts applied to GCE instances the same way. So I can attach a service account to a GCE instance that gives it access to assume other service accounts.
I think what you're looking for is "impersonation". You need roles like iam.serviceAccountUser to do this. Refer to these docs and articles:
https://cloud.google.com/iam/docs/service-accounts#the_service_account_user_role
https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed
https://medium.com/google-cloud/impersonating-users-with-google-cloud-platform-service-accounts-ba762db09092

I am using a GCP service account, but when calling Dialog Flow API I get an error

Here is the error:
Your application has authenticated using end user credentials from the
Google Cloud SDK or Google Cloud Shell which are not supported by the
dialogflow.googleapis.com. We recommend that most server applications
use service accounts instead. For more information about service
accounts and how to use them in your application, see
https://cloud.google.com/docs/authentication/.
Many of the Client Libraries pull from the Application Default Credentials, a summary of how they're checked is provided on that link. Essentially it will check environmental variables for a path and pull credentials from that location. This error message means you're using a User account, and not a service account.
Most commonly you logged in once using gcloud auth login, and even though you provided your service account it's still pulling from the Application Default location.
As you did, the method to associate a specific service account is gcloud auth activate-service-account --key-file <path>
Alternatively to use the true application default you can use gcloud auth application-default login