Insuffcient permission of google signin id_token for GCP functions - google-cloud-platform

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?

Related

Spotify — Get access token (for my own user) via Postman

How can I obtain a Spotify access token for my own user, but from Postman ?
I want to use Postman to fetch the access token from Spotify (without a preceeding manual log in).
If that's complicated, I would accept to manually log in first,
before fetching the token from Postman.
 
Details:
To get an access token (to be used further in my own Postman requests),
I manually have to get one, while logged in on the Spotify Developer website.
Therefore, I would like to obtain it directy from Postman,
where I could immediately use it further in other requests/tests.
How could this be achieved ?
I did define an app on Spotify (so I have the client_id and client_secret).
I also have tried sending the cURL suggested in this Client Credentials Flow (one of the Authorization flows). Unsuccessfully:
curl -X "POST"
-H "Authorization: Basic ZjM4ZjAw...WY0MzE="
-d grant_type=client_credentials
https://accounts.spotify.com/api/token
Postman actually has all the various types of Spotify auth requests nicely packaged up in an exportable set of requests.
Came across it while researching the same issue and came across their blog post on using PKCE instead of implicit OAuth2 flows.

AWS VPN using federated login with Google IdP - app_not_configured_for_user

I'm trying to setup a VPN connection using a federated login with Google IdP following these instructions.
Previously, I had configured a saml-provider with Google and it worked fine to authenticate users to the AWS console through Google using ARN roles
WHen I setup the VPN connection, it successfully opens the browser and asks me to select my google account, but after selecting the account I'm getting an error message from Google
According to this help section
Verify that the value in the saml:Issuer tag in the SAMLRequest matches the Entity ID value configured in the SAML Service Provider Details section in the Admin console. This value is case-sensitive.
So this is a problem coming from AWS and not from me ? Is Google IdP compatible at all with VPN authentication ? (I found this doc that mentions compatibility with okta)
Edit
Thanks to some of the answers below, I managed to make it work with Google IdP. Here is a screenshot of relevant SAML Google app screens (note that for groups I ended up adding the employees department, but I guess anything else would have worked)
To be able to save an ACS URL starting with http:// in the G Suite interface, use the trick given by teknowlogist: open the inspector > network tab, perform the request to save an URL with https, then right-click copy it as cURL, replace https by http, paste in regular console, and you're good.
I found a workaround to not being able to input http://127.0.0.1:35001 as the ACS URL on the GSuite SAML app page. The Google admin console only does client-side validation for the https requirement, so you can use the Chrome console to monitor the network call made when modifying the ACS URL.
Then, you can copy this as a curl command and change https to http
#Ted Schroeder —
Previous approach (or, plain Google doesn't work)
I just used a reverse proxy:
mitmproxy \
--listen-port 35000 \
--mode 'reverse:http://127.0.0.1:35001' \
--set keep_host_header=true
If you change Google SAML's ACS URL to be https://127.0.0.1:35000 and click "Test SAML Login", Google will take you to https://127.0.0.1:35000, whose traffic will be redirected to http://127.0.0.1:35001. In the browser I get:
Authentication details received, processing details. You may close this window at any time.
However, using the SAML-tracer extension, I found that there was a URL mismatch (https://127.0.0.1:35000 vs. http://127.0.0.1:35001). Seems like the AWS VPN Client is broadcasting its expected URL as being http://127.0.0.1:35001. So this doesn't seem viable.
Current approach (or, Auth0+Google works)
I tried using Auth0 instead, and got it to work! There's a few hoops — for instance, create a new Auth0 application, go to Addons and enable SAML2 Web App, set Application Callback URL to http://127.0.0.1:35001, and then in Settings use the following:
{
"audience": "urn:amazon:webservices:clientvpn",
"mappings": {
"user_id": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
"email": "NameID",
"name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
"given_name": "FirstName",
"family_name": "LastName",
"upn": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
"groups": "memberOf"
},
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
"signResponse": true
}
Then users, if they download the VPN config from AWS and use the AWS VPN Client app, will be taken to an Auth0 login screen where they can login via Google. Voila! (And then for security, you need to add Auth0 Rules to grant only certain users/groups authorization.)
I don't have a full answer yet, but I have the beginnings of one and I actually got past the 403 error above. The key to all this can be found in the AWS Client VPN information here: https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/client-authentication.html
Look for the section entitled "Service provider information for creating an app".
The key is that these are the ACS URL and the Entity ID that need to be used. Unfortunately, G Suite won't let you set the ACS URL to a non-https URL and apparently the AWS Client VPN app won't provide a secure URL for the ACS URL (where the SAML Authenticate response goes).
So, if you set the Entity ID to "urn:amazon:webservices:clientvpn" and have the G Suite SAML app in place according to the instructions, you'll get past the 403. However, since the ACS URL can't be specified you get whatever error message you're likely to get from the ACS URL that the authentication response goes to.
Example scenario
If you set it to https://signon.aws.amazon.com/saml" like you would for AWS Console SSO, you get an error from the AWS sign in that the SAML response was invalid.
And if you set it to https://127.0.0.1:35001 then you get a message from the browser that the "site can't provide a secure connection".
If anybody gets any further with this, I'd love to hear about it. In the meanwhile, I'm going to be looking into non-AWS OpenVPN clients that might actually support G Suite as a SAML IdP.
#alexandergunnarson
Since I don't have the ability to comment (thanks so much for making this easy stackOverflow) I had to edit my answer to get it past the censors.
Unfortunately, we don't have, and probably won't have for some time, G Suite Enterprise because it's too expensive for our startup environment. So OIDP is not a viable option for us now. I figured this would work. Good to know that it does.
I was too having the same issue. In my case, I needed to turn on the two-factor authentication for the account that I was trying to log in with.

How to integrate a Google Natural Language API with Chatfuel?

My coding skills and familiarity with Google Cloud solutions are limited and I'm trying to consume a Machine Learning model from a chatbot build using the platform Chatfuel.
I've trained a Natural Language Machine learning model using Google NL and I wanted to use this code snippet provided in my model page:
curl -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
https://automl.googleapis.com/v1/projects/123456/locations/us-central1/models/ABC123:predict \
-d #request.json
I've then tried to pass this information in Chatbot like this:
The problem is it looks like I need to pass a token (API key seems not possible for this API) and I don't see how from the Chatfuel interface I could obtain a token for each request and pass it in my post request.
Edit: I've seen this post and created a service account but I don't see how to pass the credentials to Chatfuel.
How can I pass Google API service account credential to Chatfuel?
You should make a service account with Google Cloud.
It should give you a JSON with an API key, which is used to generate a new token every hour or so. Using the Google API for whatever server side language you are using (or just using the native http requests), you use the service key (which in general is loaded into your server as a .json file) to fetch a new token every hour; OR you can use Google Apps Script, if they have Chatfuel available (which I'm not sure if they do) and get the token there, and send it to your own app every 30 minutes or so via a trigger.
But the main thing is: using your service API key, you make an HTTP request to a certain api URL (available on with instructions from another page from that link above) every hour or so to generate a new token.
From the docs, that URL appears to be:
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA-4#PROJECT-ID.iam.gserviceaccount.com:generateAccessToken
just replace, "`
SA-4#PROJECT-ID.iam.gserviceaccount.com
`"
with your own service account name
That's about it, its how it works for all Google Cloud APIs

Using nested authentication with Google IAP

I deployed a 3rd party webapp which uses basic authentication for access on Google Cloud Run. I additionally wanted to protect the endpoint by allowing only Google-authenticated users of the organization access. Both these methods use the Authorization header of the request and I cannot get it to work.
I tried following this post, providing both credentials in one field. My reasoning was, that GCP should select the strongest credential mechanism it supports - bearer - and leave the basic credentials for the webap. I have no idea if the webapp could have dealt with it because Google's reverse proxy already barred my access.
curl "-HAuthorization: bearer ${bearer_token}, basic ${base64_userpw}" https://my-google-endpoint.com
-> 401 Unauthorized
I also tried Proxy-Authorization with no different result.
curl "-HProxy-Authorization: bearer ${bearer_token}" "-HAuthorization: basic ${base64_userpw}" https://my-google-endpoint.com
Is there a way to get nested authentication to work with Google's reverse proxy? I was able to get past the reversed proxy by only supplying the bearer but naturally hit the wall at the service. With deactivated authentication on proxy side I was able to authenticate with the service using the basic credentials.
P.S.:
I am not using a browser to access the webapp but command line tools.
You cannot mix Authorization mechanisms with IAP. Everything after the bearer keyword is considered the token string.
One solution is to change your Basic Authorization HTTP header from using Authorization to a custom HTTP header. Something like X-MyApp-Authorization. Then your app processes the custom header to handle the Basic Authorization mechanism.
[Update 2021-08-17]
My original answer is partially wrong. Google's solution is currently broken.
Cloud Run is behind Google Cloud IAP. The client making a request can use two HTTP Authorization headers:
Authorization: <application authorization token>
Proxy-Authorization: Bearer <IDENTITY_TOKEN>
If a valid ID token is found in a Proxy-Authorization header, IAP authorizes the request with it. After authorizing the request, IAP passes the Authorization header to your application without processing the content.
Authenticating from Proxy-Authorization Header
This means the OP was on the right track using the Proxy-Authorization header. However, this feature does not work.
Create an Identity Token:
Use curl to verify that the token works with a Cloud Run endpoint that requires the Invoker role:
curl -H "Authorization: Bearer $TOKEN" $endpoint
That works. Now try the Proxy-Authorization header:
curl -H "Proxy-Authorization: Bearer $TOKEN" $endpoint
That fails with a 403.
Now try both headers:
curl -H "Proxy-Authorization: Bearer $TOKEN" -H "Authorization: Bearer $ANOTHER_TOKEN" $endpoint
That fails with 401 "The access token could not be verified"
gcloud auth print-identity-token
I am using documented methods to use two authorization headers, but this feature does not work.
The PHP SDK did not have the proxy-authorization header support added until June 25, 2021. I created a test application from Google's example. That also failed with the same errors.
June 25, 2021 Patch
Does it happen to work if you send two Authorization headers, like curl -H "Authorization: bearer foo" -H "Authorization: basic bar" ?
--Matthew, Google Cloud IAP engineering

Service account key creation in GCP using rest API

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