0

I'm running simple function in Google Cloud Functions to update DNS records (see code here). Currently I create service account with roles/dns.admin privileges and assign that to the function. I'm then relying for Functions' beta support for client authentication & authorization.

Alternative approach could be NOT to provision the service account credentials (with roles/dns.admin) for the function, but instead pass credential in each request.

How can I do this with Go runtime - How can I use the bearer token from the request with the Google API Go client?

Pros/cons in these two approaches?

Grokify
  • 15,092
  • 6
  • 60
  • 81
tsaarni
  • 818
  • 1
  • 8
  • 18
  • I guess one "pro" in the current implementation: client can be provisioned with service account with lesser privileges and with no direct access to CloudDNS, while function has full dns.admin privileges. – tsaarni Jul 10 '19 at 10:34

3 Answers3

1

In GCF, you could request this to grab the token.

curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google"

Ref: https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#applications

northtree
  • 8,569
  • 11
  • 61
  • 80
  • This is the token of service account that I have assigned to the function? The Google API Go client "DefaultClient" seems to get this automatically, but can I use the token from the client request instead? How to feed that to the Google API Go client? – tsaarni Jul 10 '19 at 10:18
  • I had used this method in Python to generate the HTTP request to Google API. You could change the request `header` with specified token. I suppose the Go Client should provide the method to update token, if not then you may try this approach. – northtree Jul 10 '19 at 10:26
0

The Cloud Function should be able to use its credentials to authorize the request by getting the default credentials and passing it in the DNS client.

Find more info here: Setting Up Authentication for Server to Server Production Applications

Averi Kitsch
  • 876
  • 5
  • 16
  • Thanks! I was actually looking on how to use alternative credentials stored at the external client, and I found a way now (I posted it as a separate answer to myself). Though I have now decided to go back to the documented way since it gives more alternatives to secure the Function, such as the new [ESP with Cloud Run](https://cloud.google.com/endpoints/docs/openapi/get-started-cloud-functions) – tsaarni Jul 16 '19 at 16:24
0

I found a way to feed an access token originating from the request to the Google API Go client. Here is how I construct the client (r is the incoming http.Request):

ctx := context.Background()

auth := r.Header.Get("Authorization")
token := strings.TrimPrefix(auth, "Bearer ")
ts := oauth2.StaticTokenSource(
    &oauth2.Token{AccessToken: token},
)
c := oauth2.NewClient(ctx, ts)

dnsService, err := dns.New(c)

But after thinking a bit, I do not think this is good approach in my case: the access token is unnecessarily powerful to give to the requester. So I chose the first approach in my original question.

tsaarni
  • 818
  • 1
  • 8
  • 18