0
votes

We use Cloud Endpoints in the Google Cloud for service-to-service authentication in applications deployed to the Google Kubernetes Engine.
We have an Extensible Service Proxy sidecar in front of all of our applications, with a Swagger (OpenApi) 2.0 YAML descriptor specifying which endpoints can be accessed by which other services.
Every service has its own Service Account, and it's straightforward to create the necessary security definition:

securityDefinitions:
  service-foo:
    authorizationUrl: ""
    flow: "implicit"
    type: "oauth2"
    x-google-issuer: "[email protected]"
    x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/service-foo-my-gcloud-project.iam.gserviceaccount.com"

This works well for service-to-service communication in GKE.

But during development, sometimes we want to send requests to these service from our development machines. And with this setup, we need to have access to a raw Service Account key to generate the JWT token, which is inconvenient, and also raises security concerns.

It would be very nice if we could create a security definition with which a developer could access a service using not a Service Account, but their own Google Account.

I tried to create a JWT token using the gcloud CLI with the following command:

$ gcloud auth print-identity-token

This prints a valid JWT token, where the Audience is 32555940559.apps.googleusercontent.com, and the token has an email field with my own Google account email address.
I tried creating a security definition for this, I tried the following.

  my-dev-account:
    authorizationUrl: ""
    flow: "implicit"
    type: "oauth2"
    x-google-issuer: "https://accounts.google.com"
    x-google-jwks_uri: "https://www.googleapis.com/oauth2/v3/certs"
    x-google-audiences: "32555940559.apps.googleusercontent.com"

And this technically works, the ESP allows the request go through with the JWT token produced by gcloud auth print-identity-token. But the problem is that this doesn't limit access to my own account in any way, because 32555940559.apps.googleusercontent.com is the Client ID of the GCloud SDK itself, so anyone with a Google account would have access.

Is it maybe possible to specify in the security definition that the email field should be limited to a certain value?
Or am I completely on the wrong track, but is there another way to allow ESP access for a developer Google account?

2
Could you not write a simple (OAuth) client (instead of using gcloud), distribute it, have your developers authenticate using it and have it generate suitably-scoped JWTs? There's also oauth2l but I think that doesn't give you what you want ootb.DazWilkin
Or... better yet, publish a simple service limited to your devs that does this.DazWilkin

2 Answers

2
votes

Make a small service in app engine standard behind a Identity Aware proxy (IAP). There you can limit who has access to it.

And the purpose of this service would be replicate that same request to the specified endpoint with the correct authentication token in the header.

GET /home?next=https://your-kubernetes-endpoint/resource

If you add a new member to the team, you can grant access through the IAP.

If you add a new endpoint, you change the value of the query parameter next.

1
votes

You can generate an id_token with the audience that you want like this:

gcloud auth print-identity-token --audiences=<MySpecificAudience>

BUT, you can't generate this with a user account. You need a service account key file, that isn't so good for security reason (key management and so on...)

The solution could be to impersonate a service account when you request a token with a specific audience

gcloud auth print-identity-token --audiences=<MySpecificAudience> \
  --impersonate-service-account=<SA-Name>@<ProjectId>.iam.gserviceaccount.com \
  --include-email

The --include-email adds also the email.... of the impersonated service account. I don't know if that match your requirements (security, traceability,...)