Service account key creation in GCP using rest API - google-cloud-platform

Hello I am using below rest api commamd to create a service account key in GCP. Running the command from cloud shell though not sure doing it correctly.
curl POST https://iam.googleapis.com/v1/projects/project_iD/serviceAccounts/serviceaccountID.iam.gserviceaccount.com/keys?key=key generated by API Key credentials
I am a service account admin but when I run this command in cloud shell I get below error. Idealy I have all access for service account still says list permisssion is required. Can anybody help?
curl: (6) Could not resolve host: POST { "error": { "code": 403, "message": "Permission iam.serviceAccountKeys.list is required to perform this operation on service account projects/pserviceaccountID#dev.iam.gserviceaccount.com.", "status": "PERMISSION_DENIED" } }

There are two parts to your error. The first:
curl: (6) Could not resolve host: POST
Is telling you that the curl command cannot look up the hostname "POST" because you omitted the -X parameter, the first part of your command should read:
curl -X POST
Next, the URL you have is not quite the right format, as there should be no URL parameters (in this case the ?key=key portion), as it is a POST request -- the parameters from the API would be included in the body of the request.
However, I suspect even in that case you will have a permission denied error, as curl will not manage the oauth authentication and authorization that is necessary for this request to work -- you're effectively appearing to the API as unauthenticated. I'd recommend in this case that you use one of the client libraries to do the request, or use the gcloud command directly instead of curl. These will both greatly simplify the management of the authentication.
There are examples in C#, Go, Node, Python and others in the documentation for the API itself, take a look here: https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts.keys/create
The documentation for using gcloud to accomplish this is here: https://cloud.google.com/iam/docs/creating-managing-service-account-keys#iam-service-account-keys-create-gcloud
That said, if you really want to do this with curl from cloud shell (where you have an authenticated gcloud session) this is the sequence of commands you need:
ACCESS_TOKEN="$(gcloud auth print-access-token)"
curl -X POST --header "Authorization: Bearer ${ACCESS_TOKEN}" \
https://iam.googleapis.com/v1/projects/PROJECTID/serviceAccounts/SERVICEACCOUNTNAME#PROJECTID.iam.gserviceaccount.com/keys
If you aren't on a cloud shell machine, you need to make sure you have gcloud auth first:
gcloud auth login

It looks like your service account that's making the request doesn’t have the required permissions. You should either give the SA the required IAM roles described in [1], or you can use your own user by doing gcloud auth login user#email.com to make the call.
You’ll also need the Service Account Key Admin, as SA Admin doesn’t have iam.serviceAccountKeys.list [2].
[1] https://cloud.google.com/iam/docs/creating-managing-service-account-keys#required_permissions
[2] https://cloud.google.com/iam/docs/permissions-reference

Related

Google Cloud Storage API: can't generate access token, access denied

I'm new to Google APIs and I've been trying for days to use a service account to upload content to a Google Cloud Storage bucket. I'm able to accomplish this, but only with a temporary access token obtained from the Google API playground, and I need to be able to get new access tokens so the service account can always upload content.
I've been experimenting with the following, but I keep getting access denied, even though the account in question has 'owner' permissions.
curl -X POST / -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d #Documents/request.json \ https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/content-uploader#kol-hatorah-kulah.iam.gserviceaccount.com:generateAccessToken
response:
{ "error": { "code": 403, "message": "The caller does not have permission", "status": "PERMISSION_DENIED" } }
When I run gcloud config list I get the correct project, and the account is my work email, which is also in Google Cloud as an owner.
Thanks in advance!
DISCLAIMER - my solution works for Workload Identity Federation
related problems.
I've had hard time with this error, but finally found it!
For me it was wrong attribute mapping.
I was following some tutorial (which probably went outdated) and mapping was different than from official github action task documentation (here)
I had repository_owner and aud. Changed it for repository and...
It works!
To sum up my mapping looks like this:
"google.subject" = "assertion.sub"
"attribute.actor" = "assertion.actor"
"attribute.repository" = "assertion.repository"
So if you got here because of same tutorial... you've been served!
Your curl command is attempting to use a service account identity to generate an Access Token. The command is failing because you do not have permission.
Add the role roles/iam.serviceAccountTokenCreator to the identity running the command.

cURL to GoogleCloud Vision API: Caller does not have required permission to use project foo

I'm following https://cloud.google.com/vision/docs/quickstart-cli
I've created a Google Cloud account, created a project, enabled Vision API, setup billing.
I now execute the cURL:
curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-H "X-Goog-User-Project: dragon-ocr-324006" \
https://vision.googleapis.com/v1/images:annotate -d #request.json
I get the response:
{
"error": {
"code": 403,
"message": "Caller does not have required permission to use project dragon-ocr-324006. Grant the caller the Owner or Editor role, or a custom role with the serviceusage.services.use permission, by visiting https://console.developers.google.com/iam-admin/iam/project?project=dragon-ocr-324006 and then retry (propagation of new permission may take a few minutes).",
"status": "PERMISSION_DENIED",
"details": [
{
"#type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Google developer console IAM admin",
"url": "https://console.developers.google.com/iam-admin/iam/project?project=dragon-ocr-324006"
}
]
},
{
"#type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "USER_PROJECT_DENIED",
"domain": "googleapis.com",
"metadata": {
"consumer": "projects/dragon-ocr-324006",
"service": "vision.googleapis.com"
}
}
]
}
}
What does this mean? Who is the 'caller'?
When I do gcloud auth application-default login it lets me log in as, I guess, root user for my gcloud. And that must be the caller...?
So, I click that link, and get:
Permissions error... great! And now other pages give the same perms-error. So I have to repoint my browser to https://console.cloud.google.com/ and go in manually.
So, both root-user and project-user (if I got that right) have Owner permission.
So what is the problem.
Maybe my local machine doesn't have the updated profile for the project-user?
ok, so rm -rf ~/.config/gcloud and gcloud auth application-default login
Quick test: gcloud auth application-default print-access-token gives me an access token, great!
I rerun my crl.sh script and get the same problem.
Now here's the kicker. I've got another gcloud account I just created today, and if I run it on that one, it completes fine!
So what am I doing wrong on the first account?
Bear with me because you asked different questions :)
First:
Who is the 'caller'? When I do gcloud auth application-default login it lets me log in as, I guess, root user for my gcloud. And that must be the caller...?
It's normal that the error message is not referring a specific caller / identity. In fact, you are using an access token in your curl through gcloud auth application-default print-access-token. Access tokens are used to inform an API that the bearer of the token has been authorised to access the API. It doesn't hold any identity information.
Second:
That access token has been generated for you based on the credentials, you already setup as default credentials. You get these credentials in 2 ways
you run export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account-file.json" But I think you didn't use this since you didn't evoke any key file.
you run gcloud auth application-default login, you had to go through a web flow, and the creadentials are generated and stored under ~/.config/gcloud/application_default_credentials.json
Third:
So, both root-user and project-user (if I got that right) have Owner permission.
ok, so rm -rf ~/.config/gcloud and gcloud auth application-default login
Here I understand that you changed the roles. So the initial role (set of permissions) given to the identity for which you generated the default credentials, was not enough.
Fourth:
You gave both users a large set of permissions (the Owner role has almost all permissions) Then you regenerated the default credentials.
But it did not work: because as stated in error message : (propagation of new permission may take a few minutes)
Finally:
When you came back with a new account it did work because he was already set with proper permissions. But if you retry with the old one it will work also, of course if you did not change his Owner role.
I had almost similar kind of issue when I was working on a Cloud Function in VS Code local development.In my case Application Default Credentials (ADC) was pointing to different service account which didn't had enough permission.
I followed the below steps to resolve this issue:
Executed these commands (locally) in Google Cloud SDK Shell
First list the current configuration to verify the config values
gcloud config list
This will output:
[accessibility]
screen_reader = False
[core]
account = <service_account>#appspot.gserviceaccount.com
disable_usage_reporting = True
project = ProjectId
Then I had to run a command to list all Credentialed Accounts
gcloud auth list
This will output the service accounts and an asterisk (*) at the beginning of an account which is active.
If this active service account is different than what is expected then must
activate the respective service account by running the following command.
gcloud auth activate-service-account <different_service_account>#appspot.gserviceaccount.com --key-file=PATH_TO_SERVICE_ACCOUNT_KEY_FILE
More details can be found here
Then restart the application resolved my issue.
Though this is not exactly the solution for this question, but definitely may help anyone who got into this error.

Insuffcient permission of google signin id_token for GCP functions

Now I'm using google cloud functions under our company network policy(on GCP). The policy is to prevent from the external IP.
If I need to execute the function, I should get help from google scheduler or run my code on my local PC which SDK and auth login were installed on.
However, I want other users to use it on the web I'll develop.
So, I found a way by signing in Google end-user singin(?) as this LINK
I was able to get the id_token.But when I sent
curl https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME  -H "Authorization: bearer {ID_TOKEN_FROM_SIGNIN}" on CLI, the result was 
Your client does not have permission to the requested URL {MY-FUNCTIONS_URL}
However, when I tried it with curl https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME -H "Authorization: bearer $(gcloud auth print-identity-token)", the success result arrived.
The difference between two codes was that I used id_token from Google end-user singing or SDK configured the service account key.
Of course, I set the OAuth by inputting the login url on Google IAM.I'm not able to call the functions.
Is there any idea to help me?

Google Device Access - Get and Access Token - Unauthorized

I am trying to get setup so that I can view my Nest equipment on my home automation system. Now with the Google Device Access, I have multiple steps that must be completed. I have created the project in Device Access. I setup the OAuth2 credentials. I enabled the api in the Google Cloud Portal. I "linked" the account / OAuth2 cred to my project to get the "authorization-code".
Now I am failing to "Get an Access Token".
When I try to use Google's Template and fill in the OAuth2-Client-ID, OAuth-Client-Secret and Authorization Code, the copy/paste it into a terminal session, I get: "curl: (3) URL using bad/illegal format or missing URL".
If instead I create my curl statement myself, using the data, I get '{
"error": "invalid_client",
"error_description": "Unauthorized"
}'
How do I get to the next step to get an Access Token?
I just had the same problem. The curl command automatically generated on the Google instruction page https://developers.google.com/nest/device-access/authorize did not work.
From Google (and not working) :-
curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?
client_id=oauth2-client-id&
client_secret=oauth2-client-secret&
code=authorization-code&
grant_type=authorization_code&
redirect_uri=https://www.google.com'
This did work:-
curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?' -d 'client_id=oauth2-client-id' -d 'client_secret=oauth2-client-secret' -d 'code=authorization-code' -d 'grant_type=authorization_code' -d 'redirect_uri=https://www.google.com'
Just replace oauth2-client-id, oauth2-client-secret, authorization-code with your values.
If the requested access token is not passed back to you and you get this response instead :-
{
"error": "invalid_grant",
"error_description": "Bad Request"
}
This means the authorisation code has been used or has been passed in a request that failed and you need to regenerate the device authorisation code - the authorisation_code in the curl request - using the same process you followed to get it the first time.

Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential automl

I am a novice developer who wants to learn how to use artificial intelligence.
So I created model and it responds correctly according to the inputs.
So I want to test using postman a call to the API to verify that everything works and I have an error in my call:
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
I don't know how to authenticate myself to retrieve the access token. Could you help me find a solution please?
You have 2 solutions:
As John commented,
Install the gcloud SDK on your computer.
Authenticate yourselves with the command gcloud auth login or gcloud init (proposed at the end of the installation)
Generate an access token gcloud auth print-access-token and copy it
Tips: you can skip the 2 first steps if you use Cloud Shell
Add the access token to the header to your Postman request like this:
Key is "Authrorization"
Value is "Bearer "
The access token is valid 1H, then you have to generate a new one.
(Not recommended) Make your model public (i.e. unauthenticated) like this (only in command line, it doesn't work on the GUI)
gcloud ai-platform models add-iam-policy-binding --member="allUsers" \
--role="roles/ml.modelOwner" <Model Name>
replace Model Name by your deployed model. However, it's only for test purpose. You have any filter and anyone can use it and you will pay for the processing incurs.