Cross project service account impersonation for cloud build - google-cloud-platform

We have a use case where project A has some secrets and databases which cannot be moved to another project. We have a project B that uses the secrets and databases from project A.
Project A has a service account X that accesses the secrets and databases.
Project B has a service account Y with no permissions to the secrets and databases. The goal is for service account Y to impersonate service account X during a build trigger connected to pushes to github. Project B has a cloud build pipeline that needs to temporarily access the secrets and database in Project A during the CICD process.
According to this :https://cloud.google.com/build/docs/cloud-build-service-account, section User-specified service account...You can create a custom IAM role with an impersonation permission or use pre-defined roles that allow principals to impersonate a service account.
I create a service account X and gave service account Y permissions to impersonate it (as checked in policy analyzer) however, when I try to use service account X in project B 's cloud run trigger I get (as expected):
Failed to update trigger: generic::permission_denied: user does not have impersonation permission on the trigger service account specified: projects/redacted/serviceAccounts/service#project-A.com
What "user" is this referring to? The one using the console? the build service agent?
Is it possible to get a service account Y in Project B to impersonate service account X in Project A during the build step process?
According to this https://cloud.google.com/build/docs/securing-builds/configure-user-specified-service-accounts ...To use the Triggers page in the Google Cloud console, the user-specified service account and the build trigger must be in the same project.
Is there a workaround for this e.g is it necessary to use gcloud to impersonate the account? Or is there a way to perform cross project account impersonation (for triggers) using the cloudbuild.yaml or somehow tell the trigger that the service account being used must impersonate another?

you have 2 solutions:
Use the service account X from the project A as Cloud Build user managed service account. You have to grant the Cloud Build Service Agent service account the permission to impersonate the service account X in project A. In addition, this service account X must have access to your project B resource also to interact with them. This solution is convenient because you can use the built-in connection with secret manager
Use the current configuration, but perform manual impersonation in the Cloud Build pipeline when you want to get the secrets (with code, not with the Cloud Build built-in integration with secret manager).

Related

CloudScheduler 403 Permission denied while creating

I am trying to create a Cron job programmatically in the CloudScheduler Google Cloud Platform using the following API explorer.
Reference: Cloud Scheduler Documentation
Even though I have given the user Owner permission and verified it in Policy Troubleshooter that it has cloudscheduler.jobs.create, I am still getting the following error.
{
"error": {
"code": 403,
"message": "The principal (user or service account) lacks IAM permission \"cloudscheduler.jobs.create\" for the resource \"projects/cloud-monitoring-saurav/locations/us-central\" (or the resource may not exist).",
"status": "PERMISSION_DENIED"
}
}
I had the same issue. The problem was that the region i specified did not support the cloud scheduler. You seem to have the same issue: "us-central" is not suppported. Try "us-central1"
The error is caused by using a service account that does not have an IAM role that includes the permission cloudscheduler.jobs.create. An example role is roles/cloudscheduler.admin aka Cloud Scheduler Admin. I have the feeling that you have mixed the permission of the service account that you use with Cloud Scheduler (at runtime, when a job triggers something) and the permission of the account currently creating the job (aka your account for example).
You actually need two service accounts for the job to get created. You need one that you set up yourself (can be whatever name you like and doesn't require any special permissions) and you also need the one for the default Cloud Scheduler itself ( which is managed by Google)
Use an existing service account to be used for the call from Cloud Scheduler to your HTTP target or you can create a new service account for this purpose. The service account must belong to the same project as the one in which the Cloud Scheduler jobs are created. This is the client service account. Use this one when specifying the service account to generate the OAuth / OICD tokens.
If your target is part of Google Cloud, like Cloud Functions/Cloud Run update your client service account by granting it the necessary IAM role (Cloud function invoker for cloud functions and Cloud Run Invoker for Cloud Run).The receiving service automatically verifies the generated token. If your target is outside of Google Cloud, the receiving service must manually verify the token.
The other service account is the default Cloud Scheduler service account which must also be present in your project and have the Cloud Scheduler Service Agent role granted to it. This is so it can generate header tokens on behalf of your client service account to authenticate to your target. The Cloud Scheduler service account with this role granted is automatically set up when you enable the Cloud Scheduler API, unless you enabled it prior to March 19, 2019, in which case you must add the role manually.
Note : Do not remove the service-YOUR_PROJECT_NUMBER#gcp-sa-cloudscheduler.iam.gserviceaccount.com service account from your project, or its Cloud Scheduler Service Agent role. Doing so will result in 403 responses to endpoints requiring authentication, even if your job's service account has the appropriate role.
In my case it required the permission: cloudscheduler.jobs.delete.
I found the role the by permission name: https://cloud.google.com/iam/docs/permissions-reference
It was Cloud Scheduler Admin (roles/cloudscheduler.admin)
Then I added it to my service account roles.

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 do I give a Gsuite group or user access to impersonate all Google service accounts

This is frustrating because impersonation of a service account is much less flexible than AWS.
I want users of a Gsuite group to be able to impersonate ALL service accounts in a specific google project or project folder
But I'm only seeing example where you assign the serviceAccountTokenCreator role directly to the specific service account.
This is a pain to manage. If I have X number of service accounts in my dev gcp project I want to be able to just say "users in group X can impersonate all service accounts in project Y". Is this at all possible? Or do I need to create a binding for EVERY service account with a list of groups/users that can impersonate it.
To allow a member to impersonate all service accounts created in a project, folder, or organization, grant the necessary role on the project, folder, or organization.
Reference: https://cloud.google.com/iam/docs/impersonating-service-accounts#impersonate-parent-level

How to create a GCP service account which has permissions for multiple projects? [duplicate]

I need a service account that can access multiple projects, but I have not been able to find a way to do this at all. It seems that a service account is always bound to a project.
Another option is to create a service account on the separate projects and then authenticate them using gcloud auth activate-service-account --key-file SOME_FILE.json, but the problem here is that it does not seem possible to automate the creation of service accounts.
So the question is then: Is it possible to create a cross project service account or to automate the creation of a service accounts? Even better would be if I could do both
You should be able to add a service account to another project:
Create the first service account in project A in the Cloud Console. Activate it using gcloud auth activate-service-account.
In the Cloud Console, navigate to project B. Find the "IAM & admin" > "IAM" page. Click the "Add" button. In the "New members" field paste the name of the service account (it should look like a strange email address) and give it the appropriate role.
Run gcloud commands with --project set to project B. They should succeed (I just manually verified that this will work).
Automatic creation of service accounts is something that we're hesitant to do until we can work through all of the security ramifications.
I know its a bit old, but if anyone is still looking for this,To add to #Zachary Newman answer, To make things clear, After you created a service account in project A you should go to project B to "IAM" (not "Service Accounts"), There you will be able to add the email you just created with proper roles.
I have confirmed that custom token signing worked with #Zachary Newman's procedure.
My concrete procedure of how I created a custom token in a GAE app in project A which can be used to connect to Firestore of project B is as follows:
In "IAM" page of project B, add service account {project-a}#appspot.gserviceaccount.com which is a GAE default service account of project A.
In "IAM" page of project B, assign "Service Account Token Creator" role to {project-a}#appspot.gserviceaccount.com.
Call the Firebase Admin SDK initializeApp method in a GAE app in project A with specifying firebase-adminsdk-xxxxx#{project-b}.iam.gserviceaccount.com, which is a service account with "Firebase Admin SDK Administrator Service Agent" in project B, as serviceAccountId and https://{project-b}.firebaseio.com as databaseURL and then create a custom token.

Cross project management using service account

I need a service account that can access multiple projects, but I have not been able to find a way to do this at all. It seems that a service account is always bound to a project.
Another option is to create a service account on the separate projects and then authenticate them using gcloud auth activate-service-account --key-file SOME_FILE.json, but the problem here is that it does not seem possible to automate the creation of service accounts.
So the question is then: Is it possible to create a cross project service account or to automate the creation of a service accounts? Even better would be if I could do both
You should be able to add a service account to another project:
Create the first service account in project A in the Cloud Console. Activate it using gcloud auth activate-service-account.
In the Cloud Console, navigate to project B. Find the "IAM & admin" > "IAM" page. Click the "Add" button. In the "New members" field paste the name of the service account (it should look like a strange email address) and give it the appropriate role.
Run gcloud commands with --project set to project B. They should succeed (I just manually verified that this will work).
Automatic creation of service accounts is something that we're hesitant to do until we can work through all of the security ramifications.
I know its a bit old, but if anyone is still looking for this,To add to #Zachary Newman answer, To make things clear, After you created a service account in project A you should go to project B to "IAM" (not "Service Accounts"), There you will be able to add the email you just created with proper roles.
I have confirmed that custom token signing worked with #Zachary Newman's procedure.
My concrete procedure of how I created a custom token in a GAE app in project A which can be used to connect to Firestore of project B is as follows:
In "IAM" page of project B, add service account {project-a}#appspot.gserviceaccount.com which is a GAE default service account of project A.
In "IAM" page of project B, assign "Service Account Token Creator" role to {project-a}#appspot.gserviceaccount.com.
Call the Firebase Admin SDK initializeApp method in a GAE app in project A with specifying firebase-adminsdk-xxxxx#{project-b}.iam.gserviceaccount.com, which is a service account with "Firebase Admin SDK Administrator Service Agent" in project B, as serviceAccountId and https://{project-b}.firebaseio.com as databaseURL and then create a custom token.