2

Background

I created multiple micro services with Cloud functions and Cloud run. Right now, using Cloud Endpoints, I can securely trigger all my services using an API key. However, I would like to be able to control which micro service each API key is allowed to access. I want to use only one API key by user.

Example

Let's say I'm building a trading API, for security purposes, when a client creates an API key, he can choose whether the API key is only allowed to read data (e.g: watch market prices) or both read and write data (e.g: watch market prices and then place orders). The user can easily change his API key permissions.

I'm not building anything as sensitive as a trading API but this is a very good example of what I'm trying to do.

Research

I've seen a similar post. The accepted answer proposed two solutions :

  • Using Auth0 and checking user-authorization programmatically I need to monitor the usage of my API endpoints for each API key. Moreover, the API keys security is enough for my use case.

  • API keys I managed to restrict my API keys to access my Cloud Endpoints API, however, I don't see any option to allow my key to access only some paths of the Cloud Endpoints API.

I also believe that a service like Apigee could do what I need but I'm on a low budget (POC) so I don't think it's a service for me and I would prefer to use GCP products only.

Question

Does Cloud Endpoints propose a solution out of the box for my use case ? If so, what should I do ?

If not, would it be possible to either :

  • create another proxy using Cloud Functions that would check against a Firestore database whether the API key is allowed to access the requested method ? The logic would be like this : User request with Google's provided API key -> Cloud Endpoints approval -> Custom proxy function approval -> micro service execution

  • Customize ESP to meet my use case

  • Manage all the API authentication myself (seems like a lot of work)

Yoann
  • 112
  • 6

1 Answers1

1

TL;DR: It's not possible with Cloud Endpoint

There is few things and limitations to know with Cloud Endpoint:

  • Cloud Endpoint performs authentication, not authorization. In short, check if your user credential (auth0, OAuth2, Firebase auth, API Key) is valid.
    • For API Key only, you can restrict the key to one or several service URL. Then, here you can restrict an API Key to only one Cloud Endpoint if you want.
  • API keys "authenticates" a GCP projet, not a user, not an account.
    • If you create 2 keys in the same project, you won't be able to differentiate the requester -> You have to create 1 project per customer and generate an API Key on each project
  • (related to the previous point) API Keys can't be created automatically by script. You have to perform this action on the console, manually (And if you have a lot of customer to enroll, or if you want an automatic enrollment, it will be hard)

With these inputs, it's up to you to design your solution: You can perform an Authorization check by yourselves (a proxy as you mentioned), not on the API Key string value but on the project_id. I recommend you this solution because you can add quotas and rate limit on API Keys(I wrote an article on this)

You can also implement your own authorization process (and even your own API Key generation, it's simply a string at the end!), more complex...

guillaume blaquiere
  • 66,369
  • 2
  • 47
  • 76
  • Thank you very much for your response ! If I understood correctly, the best solution for me is to create one project for each user programmatically (seems overkill, maybe this is a misconception of mine ?) and then use a reverse proxy behind Cloud Endpoints, for authorization, using the project id. I'd use the same openAPI spec as Cloud Endpoints. I'd just have to rewrite the x-google-backend extension, right ? What I fundamentally don't understand though, is why we can't simply do this with an API key instead of a project id, since, in my understanding, 1 API key = 1 user (wrong assumption ?) – Yoann May 10 '20 at 12:02
  • As a side note, I think it is now possible to programmatically create API keys, see this [feature](https://cloud.google.com/api-keys/docs/create-delete-api-keys#create) in beta. – Yoann May 10 '20 at 12:03
  • Nice catch!! -> Last updated 2020-05-07. 3 days ago I wasn't aware of this!! Thereby the creation is now easier!! But, it apparently not solve your latest assumption (1API key = 1 user). Look at the API call for creating the API Key `gcurl https://apikeys.googleapis.com/v2beta1/projects/PROJECT_NUMBER/keys` -> You don't mention any email, only a project number. The number that you will get in your API after Cloud Endpoint validation. – guillaume blaquiere May 10 '20 at 12:34
  • The thing that I should mention is that I have the possibility to map each API key I create to a specific user. Indeed, I'll be the one creating the API keys from my CRM, where I have all the info about the user (it's a private API), and then I hand over the API KEY to the user. In this regard, I think this is a workaround to achieve 1 API key = 1 User, right ? With this workaround, I think I should be able to use Cloud Endpoints features such as quotas and monitoring and map the logs to each API KEY (i.e: each CRM client). – Yoann May 10 '20 at 13:22
  • As for the authorization restrictions on micro services, I'll make a reverse proxy as discussed above. For other people that would be interested by this topic, AWS Api Gateway and Lambda authorizers can also be an (easier / out of the box) solution to the question. @guillaume blaquiere Thank you for your help ! keep up the good work on Medium, your articles are really helpful, in fact, I had already read some of them eheh :) ! – Yoann May 10 '20 at 13:24
  • @YoannCC Thanks for this kind words. Hope you will successfully achieve your POC! Best – guillaume blaquiere May 10 '20 at 15:59