Search code examples
authenticationgoogle-cloud-functionsgoogle-cloud-endpoints

Cloud Endpoints, grant roles to API keys to restrict some methods/paths (e:g read/write roles)


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)


Solution

  • 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...