2

I am developing an Android app (Java) that uses Firebase authentication and GCP Pubsub. To connect to Pubsub I currently use a service account key that is stored in a JSON file in my project. But this is not something that seems secure in a production environment since it exposes my key.

So what would the best practice in that case ?

I though about having something like a token linked to the Firebase user account but I don't see how to do this, and this documentation from Google indicates that I should use a service account in my case since since I don't need to access user-specific information.

https://cloud.google.com/docs/authentication/

robsiemb
  • 6,157
  • 7
  • 32
  • 46
baptistef
  • 21
  • 2

2 Answers2

1

You're right -- it's not secure to distribute the service account key. Even with just the minimal Pub/Sub Publisher role, this would allow anyone who has a copy of the key to inject as much data as they wanted into Pubsub (billing you), and depending on how your subscribers use the data thus provided, it could open up an attack surface on the side of your subscribers. Likewise, you would want to plan for what to do should you need to rotate the key. I do not recommend you take this approach.

Given that you're not including the key with the app itself, you're left with finding a way to do something in a controlled server environment which also has access to the service account credentials.

One option is that you could create a Callable Cloud Function to do the Pubsub operation. The cloud function would reside securely on Google's servers, and could run as a service account no problem. This would then be called from your application.

Inside the function, you would need to validate that the request is allowed (since the function could still be called by anyone -- they're effectively public), and then do the Pubsub operation. Validation could involve checking the authentication of the user using the app, checking that the app is well formed, and even possibly implementing some form of rate limiting. This is likely to be a very lightweight function in practice.

Even with the most minimal request validation, this still restricts callers to doing exactly what the function has been written to do, as opposed to full access to the service account, which minimizes the attack surface to what basically any interaction with code on a web server might be, and it allows you to validate that the input is valid before you inject it into Pubsub -- thus protecting all downstream consumers.

robsiemb
  • 6,157
  • 7
  • 32
  • 46
  • 1
    Yes but a cloud function would cost a lot (price per invocation) compared to a direct link to pub-sub. – baptistef Nov 07 '19 at 00:22
  • Its all tradeoffs -- releasing the service account key would also be expensive (given the potential for abuse, and the difficulty of changing it quickly were it to be comprised). You need the key to access the Pubsub APIs. Presumably, this function would be lightweight (its just doing validation and a pubsub call) and would not be very expensive to actually execute in practice in terms of RAM or CPU. You could also compare to just running a server full time to handle the requests. – robsiemb Nov 07 '19 at 00:25
1

The basic issue is how do you manage the service account keys that are used for Server to Server or App to app communication. Here are some of the recommendation from Google cloud.

Google recommends to have enforce an IAM policy to restrict/manage access.

Prashant
  • 1,144
  • 8
  • 17
  • 28