I have mistakenly deleted the default "app engine service account" for my project - {id}#appspot.gserviceaccount.com
Is there a way to recover it without resetting/recreating my project on Google Cloud Platform?
Unfortunately at this time, there is no way to recover the default App Engine service account. The solution is as you say creating a new project and redeploying your code there.
Should you wish to see this deletion prevented or default service account recreation made possible in the future, I strongly urge you to file a feature request on the App Engine public issue tracker while providing this example as a business case.
UPDATE: As filed by the OP, a feature request now exists on the App Engine public issue tracker as Issue 13085. Please star this issue to receive updates on its progress.
UPDATE 2: As part of the App Engine Admin API, one can now use the apps.repair API to attempt to address issues of default Cloud Storage buckets and App Engine service accounts. I would recommend trying this API before creating a new project and redeploying. I'm leaving this as an addendum and not the primary solution as it's not guaranteed to solve the issue.
UPDATE 3 It is now possible to undelete service accounts. As per the Undeleting a service account documentation, a service account may be restored if:
The service account was deleted less than 30 days ago
and
There is no existing service account with the same name as the deleted service account.
You can now recover the deleted service accounts from https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/undelete
you have to get the UniqueID of the service account from https://console.cloud.google.com/home/activity
Recover
You can undelete service accounts. You will need the service account's unique ID. If you don't have it, you can find it on Google Cloud Logging.
You can find Logging service here on the side menu:
Then you will need to filter by date and type service account to find the exact moment the service was deleted.
Then you can either
Option 1: Use Google Cloud Command Line
You can run the command line by installing it on your computer (https://cloud.google.com/sdk/docs/install). Or you can run it online using the Active Shell offered by Google Cloud Platform.
The command you want to run is the following.
gcloud beta iam service-accounts undelete 12345678901234567890
Option 2: Use Google Cloud API
Using curl, call the API with the following command.
You will need to change API_KEY, PROJECT_ID and SERVICE_ACCOUNT_UID for real values.
curl -X POST \
-H "Authorization: Bearer API_KEY \
-H "Content-Type: application/json; charset=utf-8" \
-d "" \
"https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SERVICE_ACCOUNT_UID:undelete"
You can get the API_KEY from Google Cloud Command Line:
gcloud auth application-default print-access-token
Again you can either have gcloud installed on your local machine or you can use it online with the Active Shell.
If you don't know the default service account UniqueID, there is another solution.
Simply disable the App Engine Admin API and enable the same after some time. This will create a new default service account. Please note that this will delete all the associated resources.
(To enable/disable an API: Menu -> API & Services -> Dashboard -> Enable APIs and Services -> Search for that API -> Enable/Disable)
Your Account is deleted less than 30 days you can recover it via cloud console
Go to Cloud Console Open Terminal :
Write :
gcloud beta iam service-accounts undelete 100214681451516381413
100214681451516381413 this is the Deleted Account UID .
If You Don't know the Deleted Account ID then GO IAM and Search With Your Deleted Email Address you will find-out the UID there .
Thanks .
Related
I've been following the steps in the Google tutorial, Using Pub/Sub with Cloud Run tutorial.
All ok until allowing Google's service account to create auth tokens (Integrating with Pub/Sub 2.b.)
Here I run the command:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:service-PROJECT_NUMBER#gcp-sa-pubsub.iam.gserviceaccount.com \
--role=roles/iam.serviceAccountTokenCreator
PROJECT_ID and PROJECT_NUMBER are replaced by their actual values of course.
However I get the error:
ERROR: (gcloud.projects.add-iam-policy-binding) INVALID_ARGUMENT: Service account service-PROJECT_NUMBER#gcp-sa-pubsub.iam.gserviceaccount.com does not exist.
(I've replaced my actual project number by PROJECT_NUMBER here for privacy, believe me I've double-checked that it's the correct ID and number.)
There's a note in this guide about IAM changes taking several minutes to propagate but I'm seeing the same error hours after the previous command completed successfully.
I've also tried adding this through the Cloud Console IAM UI but I get a consistent error:
using IAM UI.
I'm already using Pub/Sub in this project and it's still working with a Pull subscription.
Update
I've finished setting this up in another project following the same instructions and that's working fine, so I'm certain this isn't a misunderstanding of the tutorial, there's something wrong with this project (or rather, the Google-managed service account for this project).
I was able to force the account to be created with the command (docs):
gcloud beta services identity create --project PROJECT_ID --service pubsub
After this the add-iam-policy-binding command completed without error.
I have this app that's been running on Google App Engine for a good couple of years. Today I needed to modify its app.yaml file, but when I ran "gcloud app deploy" I got this error:
Updating service [default]...failed.
ERROR: (gcloud.app.deploy) Error Response: [7] Failed to create cloud build: service account "redacted#cloudbuild.gserviceaccount.com" has insufficient permission to execute the build on project "redacted"
It appears that the default service account no longer has the necessary permissions. In fact, it may have been deleted completely, because I don't see it listed under gcloud projects get-iam-policy xxxx. What I see instead is this:
serviceAccount:service-redacted#gcp-sa-cloudbuild.iam.gserviceaccount.com
with a correct-looking role cloudbuild.serviceAgent.
I tried googling any changes related to GAE service accounts but didn't find any useful references. I followed the solution to this question, but it didn't help.
The question is, how do I change the permissions of the service account mentioned in the original error message, or, how do I tell GAE to use another (correct) service account when deploying my app?
According to [this][1] documentation
...To deploy new versions, a member must have the Service Account User (roles/iam.serviceAccountUser) role on the App Engine default service account, and the Cloud Build Editor (roles/cloudbuild.builds.editor) and Cloud Storage Object Admin (roles/storage.objectAdmin) roles on the project.....
Using the IAM page you can add the email address of the person deploying (the one you have authenticated via gcloud) and add the above roles to that email
[1]: https://cloud.google.com/iam/docs/understanding-roles?hl=en#app-engine-roles
I have a Python app on Google App Engine Standard which is secured using Google Cloud Identity Aware Proxy (IAP).
I would like to trigger a part of my app every day by using Cloud Scheduler. (It is calling an API, doing calculations, and stores results in Google Cloud Storage.)
To do so, I tried triggering a POST request on an "App Engine HTTP". example URL: "/refresh_data"
When running the job, I get the following error:
jsonPayload: {
status: "FAILED_PRECONDITION"
relativeUrl: "/refresh_data"
jobName: "..."
#type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"
targetType: "APP_ENGINE_HTTP"
}
I can't find any documentation relative to the "FAILED_PRECONDITION" error so I'm feeling kind of stuck here.
As an alternative, I tried to trigger a POST request to a simple "HTTP" and by granting the Owner access level in IAP to the service account I am using for Cloud Scheduler. This time, the error message I get is the following :
jsonPayload: {
status: "UNAUTHENTICATED"
#type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"
jobName: "..."
targetType: "HTTP"
url: "https:.../refresh_data"
}
I really don't understand how to make this work... The Cloud Scheduler documentation barely documents the "App Engine HTTP" option, and nothing is documented relative to te use of IAP...
Any help would be much appreciated :)
It's the dark side of IAP. I sent this feedback to Google months ago. Same thing with Pubsub, you can't trigger and App Engine IAP protected from these serverless product, even if you use a service account with the correct authorization.
You can check this relevant documentation from IAP on how to authenticate with a Service Account.
Whenever you are using Cloud Scheduler, the requests will be done with its Service Account, therefore the guide to follow should be the one linked above as you are basically trying to authenticate programmatically rather than with the Google sign-in.
That being said, you would need to generate the OIDC token prior to making a request to an IAP-secured endpoint. Once you have the OIDC token, it needs to be included in the Authorization: Bearer header.
I had a similar problem when upgrading my GAE app from python 2.7 to python3 (standard).
I got the same error message as you (status: "FAILED_PRECONDITION") when running my previous cron.yaml jobs set up as cloud scheduler jobs.
And the upload of previous cron.yaml files did not work to run either.
Then I found out that just adding an ending '/' on the url fixed it.
So a cron like:
cron:
- description: competition participants pilot list update
url: /daily1/
schedule: every 8 hours from 05:00 to 21:00
worked after being uploaded with cloud SDK:
gcloud app deploy cron.yaml --project my-gae-project
(and I forgot that) I also had to:
gcloud services enable cloudscheduler.googleapis.com --project my-gae-project
I got this working recently for HTTP endpoints behind an IAP (we use cloud run, but it should be similar for any IAP protected HTTP endpoint). This is the Cloud Scheduler configuration that worked for me:
Auth Header: "Add OIDC Token"
Service account: Select a service account with the role "IAP-secured Web App User" (if you recently added this permission, it can take a few minutes to propagate)
Audience: Your IAP's Client ID (from here: https://console.cloud.google.com/apis/credentials)
I have a nodejs app deployed on Google App Engine, which trigger http cloud functions, thought simple http call (using axios) to get data from Google Cloud Sql.
Everyone that will use the site will be able to see the http request and to replicate it.
What is the best way to secure my google cloud functions to be called only from google app engine?
The best way is to deploy a private function.
When you deploy your function with the cli use the --no-allow-unauthenticated param. This feature is in Beta
On the console, you can't you when you deploy your function. However, you can delete the access to all user in the functions list page
Click on the function line (not the name of the function, the line)
Show the info panel in the upper right corner
Delete allUsers from the cloud function invoker.
Now authorize only AppEngine to access to your function
In the console, at the same place (Function Invoker), add the AppEngine default service account : #appspot.gserviceaccount.com
With the cli, use this command
gcloud beta functions add-iam-policy-binding <Your Function Name> \
--member='serviceAccount:<your project id>#appspot.gserviceaccount.com' \
--role='roles/cloudfunctions.invoker'
Now only the user/service account with the role cloudfunctions.invoker could invoke your function.
I feel the post mentioned by #Denis T does mention options for your scenario. Since you commented it does not work for your scenario, did you consider restricting access to Cloud Function to only the App Engine default service account? How to do this is mentioned in the answer quoted by Denis.
I am trying to use Jenkins for CI/CD.
I've developed a Python flask application. I am deploying this application into Google App Engine. So far I am using gcloud app deploy app.yaml command to deploy application to Google App Engine.
Code for this application is present in Google Cloud Source Repository.
Since the authentication to git(Google Cloud Source Repository) requires Google OAuth, I've installed Google OAuth Credentials Plugin
Now I am facing two issues
When I use "Google Service Account from metadata" Credential Kind, I am not seeing the credentials listed in "Source Code Management".
when I use "Google Service Account from private key", I am able to see credentials. But when I run my jenkins job I am getting below error
FATAL: Could not call
com.google.jenkins.plugins.source.GoogleRobotUsernamePassword.writeObject()
: Failed to serialize
com.google.jenkins.plugins.source.GoogleRobotUsernamePasswordModule$ForRemote#credentials
for class
com.google.jenkins.plugins.source.GoogleRobotUsernamePasswordModule$ForRemote
---- Debugging information ---- message : Could not call com.google.jenkins.plugins.source.GoogleRobotUsernamePassword.writeObject()
cause-exception : java.lang.RuntimeException cause-message :
Failed to serialize
com.google.jenkins.plugins.source.GoogleRobotUsernamePasswordModule$ForRemote#credentials
for class
com.google.jenkins.plugins.source.GoogleRobotUsernamePasswordModule$ForRemote
------------------------------- java.lang.UnsupportedOperationException: Refusing to marshal
org.joda.time.DateTime for security reasons; see
https://jenkins.io/redirect/class-filter/ at
hudson.util.XStream2$BlacklistedTypesConverter.marshal(XStream2.java:543)
at
com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at
com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at
com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
Question: How can I authenticate Google Cloud Source repository in Jenkins? What are the steps|plugins required to use Google Cloud Source repository in Jenkins?
Solution
You probably need to add a missing scope to the Compute Engine VM Instance running Jenkins that would give it access to Cloud Source Repository. You can follow the documentation or this steps, which ever you find convenient.
Go to Cloud Deployment Manager
Click on the name of the Jenkins deployment in question
Click on the instance name in the left info pane and it will redirect you to VM instance details
Stop the instance
Press Edit and set the right access scope for Cloud Source Repository
After your start the VM instance, try adding your git repository again and once you select the credentials, either "Google Service Account from metadata" or from service account, everything should work properly.
Elaboration
I stumbled upon the "Invalid authentication credentials." issue while trying to add a Cloud Source Repository after deploying Jenkins from Launcher.
In my case the reason why it happened was that during the process of deployment the Cloud API access scope for Cloud Source Repositories on the Compute Engine VM instance was set to Disabled, which prevented any interaction from that instance even if a service account had all the necessary roles/permissions.
Here are the scopes that are reconfigured by Launcher:
scopes:
- 'https://www.googleapis.com/auth/cloud.useraccounts.readonly'
- 'https://www.googleapis.com/auth/devstorage.read_only'
- 'https://www.googleapis.com/auth/logging.write'
- 'https://www.googleapis.com/auth/monitoring.write'
{% if enableComputeApi %}
- 'https://www.googleapis.com/auth/compute'
{% endif %}
- 'https://www.googleapis.com/auth/cloudruntimeconfig'
Adding the following scope to the VM instance running Jenkins was enough to fix the error:
https://www.googleapis.com/auth/source.read_only
Extra:
List of scopes for Google APIs.
I updated the plugin to 0.6 version.
In 0.6 version, I have the same problem in Jenkins "Free-style" project.
Bit I can success to checkout in Jenkins "pipeline" project.
I just copy the "checkout syntax" in others project and replace 2 parts of the syntax to the right:
credentialsid -> replace to your right credentials id that you created Google Service Account from private key in jenkins.
url ->replace to your google source repository url