3

I use Firebase secrets for two things in my GitHub Actions workflow:

  1. FIREBASE_TOKEN to run tests with the hosting emulators. The docs say "The token should be treated like a password; make sure it is kept secret."
  2. firebaseServiceAccount to deploy after the build succeeds. Pushing to the master branch deploys the code to the production site, while in a PR it deploys a preview. The action README says "It's important to store this token as an encrypted secret to prevent unintended access to your Firebase project. Set it in the "Secrets" area of your repository settings"

The problem is that when an external contributor makes a PR from a fork, the build doesn't have access to those secrets. That means that GitHub actions can't run tests on the code in the PR, and even if it could, it couldn't deploy a preview.

I understand that GitHub can't magically make these secrets available to the workflow without risking exposing them to arbitrary malicious code. But I can't understand how Firebase intends for these features to be used in practice. Builds not working for external contributors seems like a serious limitation in an open source project. I can't imagine that I'm supposed to add every person who opens a PR as a GitHub collaborator. That sounds very dangerous for security - I only want to do that after having some time to build trust.

So I have a question for each secret and use case. The questions are different, so I can post a second question if people want, but you can see how they're closely related.

  1. Running tests with emulators, i.e. specifically not against a live environment, seems like precisely the kind of thing that shouldn't require a special secret token. Why is this required? What would be the consequences of making FIREBASE_TOKEN publicly available?
  2. Can I make a service account that only has permission to deploy preview channels, but not 'live'? If so, would there still be risks to making that service account public? Can people abuse the account in a way that I would have to pay for?
Alex Hall
  • 34,833
  • 5
  • 57
  • 89

1 Answers1

0

I'm not an expert on GitHub Actions and shared secrets (especially in the context of a public/open-source repo), but this is how I would approach it.

As you say, both the FIREBASE_TOKEN and firebaseServiceAccount grant highly critical access to your project.

I would therefore approach it by having two different Firebase projects: one for the production/live code, of which secrets (auth and service account tokens) are private to you, and another project for the preview/staging environments (and dev too via the emulators). This way you would definitely get a service account key that is separate from the production one. As for the FIREBASE_TOKEN, since I believe it's tied to your account, I think you could add a collaborator to the "dev/staging" Firebase project and get the token specifically for that project.

I think the 2 projects setup ("dev+staging" and "production") on Firebase is quite common and I've seen it recommended multiple times.

Francesco Bianchi
  • 772
  • 1
  • 4
  • 13
  • Thanks, this sounds reasonable. So I would make a new Google account, only give that account access to the separate staging project, and then the `FIREBASE_TOKEN` and `firebaseServiceAccount` associated with that account/project can safely be made publicly available? Have you seen the 'publicly available' part recommended anywhere? What do you think is the worst thing that could happen if someone wanted to do something malicious with those 'secrets'? – Alex Hall Nov 10 '22 at 16:40
  • Overall yes. I'd still store it as a GitHub secret, in case that's what you mean. I believe that still adds some layers of security (again, I'm not an expert about public Github open source repos, but I think there's still a layer of secrecy that it's offered). I haven't seen the "publicly available" part officially recommended, but for the rest (2 project per environment etc) that's common practice. As far as I know, if somebody would use the auth code with the purpose of making damage, best they could do would be A) change configurations or delete data or B) create new Firebase project. – Francesco Bianchi Nov 10 '22 at 19:57
  • Both these two are IMO not big issues considering that they'll have access only to the staging account with fake data. The only thing to consider is that the staging project should stay as free project. If you enable payments, then they could indeed make damage by repurposing the project for their needs and go well above the free quota, resulting in you being overcharged. However, as long as the project is not linked to a credit card it's fine. – Francesco Bianchi Nov 10 '22 at 19:57
  • I can't store these as GitHub secrets, that's the whole point. I've gone ahead with this advice and made them a public part of the repo in https://github.com/alexmojaki/futurecoder/pull/401. Even if they weren't quite that visible, ultimately the point is that PRs from forks need access to the values, so a malicious actor would find a way to obtain them. The project doesn't have payments enabled, and the account with the public token is only a 'viewer' of that project. – Alex Hall Nov 11 '22 at 09:16
  • When I pushed the public firebaseServiceAccount to GitHub, I *instantly* got an email from Google "Potentially Compromised Credentials for " – Alex Hall Nov 11 '22 at 09:38
  • Ah ok. Gotcha about the GitHub Secrets part, now I fully get it. Anyway, I know this is more of a workaround to use Firebase as you wish. There might be better ways. As for Google's security alert, it's nice that they alert you right away, but it just repeated what we already knew. Anyway, I hope that helped! Maybe Firebase will release at some point additional features to cater to this use case. – Francesco Bianchi Nov 11 '22 at 15:04