To keep your Firebase resources and your users' data secure, follow these
guidelines. Not every item will necessarily apply to your requirements, but keep
them in mind as you develop your app.

## Avoid abusive traffic

#### Yes Set up monitoring and alerting for backend services

To detect abusive traffic, such as denial-of-service (DOS) attacks, set up
monitoring and alerting for [Cloud Firestore](https://firebase.google.com/docs/firestore/monitor-usage.md.txt),
[Realtime Database](https://firebase.google.com/docs/database/usage/monitor-usage.md.txt),
[Cloud Storage](https://firebase.google.com/docs/storage/monitor-storage.md.txt), and
[Hosting](https://firebase.google.com/docs/hosting/usage-quotas-pricing.md.txt)

If you suspect an attack on your application,
[reach out to Support](https://firebase.google.com/support/troubleshooter/contact) as soon as possible to
let them know what is happening.

#### Yes Enable App Check

To help ensure only your apps can access your backend services, enable
[Firebase App Check](https://firebase.google.com/docs/app-check.md.txt) for every service that supports it.

#### Yes Configure your Cloud Functions to scale for normal traffic

Cloud Functions automatically scales to meet your app's demands, but in the
event of an attack, this can mean a big bill. To prevent this, you can
[limit the number of concurrent instances](https://cloud.google.com/functions/docs/configuring/max-instances)
of a function based on normal traffic for your app.

#### Yes Set up alerting to be notified when the limits are nearly reached

If your service has request spikes, often quotas will kick in, and automatically
throttle traffic to your application.

- Make sure to monitor your
  [*Usage and billing* dashboard](https://console.firebase.google.com/project/_/usage?useAutoProject=true).

- Set up [budget alerts](https://firebase.google.com/docs/projects/billing/budget-alerts.md.txt)
  for your project to be notified when resource usage is exceeding expectations.

- If you use Firebase AI Logic, Firebase App Hosting, Cloud Functions for Firebase, and Firebase Extensions, set up
  [spend caps](https://firebase.google.com/docs/projects/billing/spend-caps.md.txt) to pause the applicable
  service if your project reaches the budget set for that service.

#### Yes Prevent self-DOSes: test functions locally with the emulators

It can be easy to accidentally DOS yourself while developing
Cloud Functions: for example, by creating an infinite trigger-write loop.
You can prevent these mistakes from affecting live services by doing your
development with the [Firebase Local Emulator Suite](https://firebase.google.com/docs/emulator-suite.md.txt).

And if you do accidentally DOS yourself, undeploy your function by deleting it
from `index.js` and then running
`firebase deploy --only functions`.

#### Yes Where real-time responsiveness is less important, structure functions defensively

If you don't need to present the result of a function in real time, you can
mitigate against abusive traffic by processing the results in batches: publish
results to a
[Pub/Sub](https://cloud.google.com/pubsub/docs/overview)
topic, and process the results at regular intervals with a
[scheduled function](https://firebase.google.com/docs/functions/schedule-functions.md.txt).

## Understand API keys

> [!CAUTION]
> **Caution:** **Always restrict an app's API key to the set of APIs used by that
> app.** The following entries are high-level information about using API keys with Firebase apps, but make sure to review the details in [Learn about using and managing API keys for Firebase](https://firebase.google.com/docs/projects/api-keys.md.txt).

#### Yes API keys for Firebase services are not secret

API keys for Firebase services only *identify* your Firebase project and app to
those services. *Authorization* is handled through Google Cloud IAM permissions,
Firebase Security Rules, and Firebase App Check.

All Firebase-provisioned API keys are *automatically* restricted to
[Firebase-related APIs](https://firebase.google.com/docs/projects/api-keys.md.txt#faq-required-apis-for-restricted-firebase-api-key).
If your app's setup follows the guidelines in this page, then
*API keys restricted to Firebase services* do *not* need to be treated as
secrets, and it's safe to include them in your code or configuration files.

#### Yes Set up API key restrictions

If you use API keys for other Google services, make sure that you apply
[API key restrictions](https://cloud.google.com/docs/authentication/api-keys#api_key_restrictions)
to scope your API keys to your app clients and the APIs you use.

Use your Firebase-provisioned API keys *only* for
[Firebase-related APIs](https://firebase.google.com/docs/projects/api-keys.md.txt#faq-required-apis-for-restricted-firebase-api-key).
If your app uses any other APIs (for example, the Places API for Maps or the
Gemini Developer API), use a
[separate API key](https://firebase.google.com/docs/projects/api-keys.md.txt#use-separate-keys-for-specific-apis)
and restrict it to the applicable API.

#### Yes Keep FCM server keys secret

Unlike API keys for Firebase services, FCM server keys (used by the
[legacy FCM HTTP API](https://firebase.google.com/docs/cloud-messaging/auth-server#authorize-legacy-protocol-send-requests))
*are* sensitive and must be kept secret.

#### Yes Enable audit logging for Cloud Messaging

Consider enabling [cloud audit
logging](https://firebase.google.com/docs/cloud-messaging/cloud-audit-logging) for Cloud Messaging so
that you can record administrative activities and access events within your FCM
resources.

#### Yes Keep service account keys secret

Unlike API keys for Firebase services, service account private keys (used by the
[Firebase Admin SDK](https://firebase.google.com/docs/admin/setup.md.txt#initialize-sdk)) *are* sensitive and must
be kept secret.

## Firebase Security Rules

#### Yes Initialize rules in production or locked mode

When you set up Cloud Firestore, Realtime Database, and Cloud Storage, initialize your
[Firebase Security Rules](https://firebase.google.com/docs/rules.md.txt) to deny all access by default, and add rules that grant
access to specific resources as you develop your app.

Use one of the default settings for new instances of Cloud Firestore (production
mode) and Realtime Database (locked mode). For Cloud Storage, start with a security
rules configuration like the following:

    rules_version = '2';
    service firebase.storage {
      match /b/{bucket}/o {
        match /{allPaths=**} {
          allow read, write: if false;
        }
      }
    }

#### Yes Security rules are a schema; add rules when you add documents

Don't write security rules after you write your app, as a kind of pre-launch
task. Instead, write security rules as you write your app, treating them like a
database schema: whenever you need to use a new document type or path structure,
write its security rule first.

#### Yes Unit test security rules with the Local Emulator Suite; add it to CI

To make sure your security rules are keeping up with your app's development,
unit test your rules with the
[Firebase Local Emulator Suite](https://firebase.google.com/docs/emulator-suite.md.txt)
and add these tests to your CI pipeline. See these guides for
[Cloud Firestore](https://firebase.google.com/docs/firestore/security/test-rules-emulator.md.txt)
and [Realtime Database](https://firebase.google.com/docs/rules/unit-tests.md.txt#database).

## Authentication

#### Yes Custom authentication: mint JWTs from a trusted (server-side) environment

If you already have a secure sign-in system, whether a custom system or a
third-party service, you can use your existing system to authenticate with
Firebase services. [Create custom JWTs](https://firebase.google.com/docs/auth/admin/create-custom-tokens.md.txt)
from a trusted environment, then pass the tokens to your client, which uses the
token to authenticate ([iOS+](https://firebase.google.com/docs/auth/ios/custom-auth.md.txt),
[Android](https://firebase.google.com/docs/auth/android/custom-auth.md.txt), [Web](https://firebase.google.com/docs/auth/web/custom-auth.md.txt),
[Unity](https://firebase.google.com/docs/auth/unity/custom-auth.md.txt), [C++](https://firebase.google.com/docs/auth/cpp/custom-auth.md.txt)).

For an example of using custom authentication with a third-party provider, see
the blog post,
[Authenticate with Firebase using Okta](https://firebase.googleblog.com/2020/08/authenticate-with-firebase-using-okta.html).

#### Yes Managed authentication: OAuth 2.0 providers are the most secure

If you use Firebase's managed authentication features, the OAuth 2.0 / OpenID
Connect provider options (Google, Facebook, etc.) are the most secure. You
should support one or more of these providers if you can (depending on your user
base).

#### Yes Email-password authentication: set tight quota for the sign-in endpoint to prevent brute force attacks

If you use Firebase's managed email-password authentication service, tighten the
default quota of the `identitytoolkit.googleapis.com` endpoints to prevent brute
force attacks. You can do so from the
[*Identity Toolkit API* page](https://console.cloud.google.com/apis/api/identitytoolkit.googleapis.com/quotas?project=_)
in the Google Cloud console.

#### Yes Email-password authentication: Enable email enumeration protection

If you use Firebase's managed email-password authentication service,
[enable email enumeration protection](https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection),
which prevents malicious actors from abusing your project's auth endpoints to
guess account names.

#### Yes Upgrade to Google Cloud Identity Platform for multi-factor authentication

For extra security on sign-in, you can add multi-factor authentication support
by upgrading to [Google Cloud Identity Platform](https://cloud.google.com/identity-platform/docs/android/mfa).
Your existing Firebase Authentication code will continue to work after you upgrade.

## Anonymous authentication

#### Yes Only use anonymous authentication for warm onboarding

Only use anonymous authentication to save basic state for users before they
actually sign in. Anonymous authentication is not a replacement for user
sign-in.

#### Yes Convert users to another sign-in method if they'll want their data on other devices

Anonymous authentication data will *not* persist if the user clears local
storage or switches devices. If you need to persist data beyond app restarts on
a single device,
[convert the user to a permanent account](https://firebase.google.com/docs/auth/android/anonymous-auth.md.txt#convert-an-anonymous-account-to-a-permanent-account).

#### Yes Use security rules that require users to have converted to a sign in provider or have verified their email

Anyone could create an anonymous account in your project. With that in mind,
protect all non-public data with
[security rules that require specific sign-in methods or verified email addresses](https://firebase.google.com/docs/rules/rules-and-auth.md.txt).

For example:

    allow write: if request.auth.token.firebase.sign_in_provider != "anonymous";
    allow write: if request.auth.token.email_verified = true;

## Cloud Functions safety

#### Yes Never put sensitive information in environment variables

Often in a self-hosted Node.js app, you use environment variables to contain
sensitive information like private keys.
*Do not do this in Cloud Functions* . Because Cloud Functions reuses
environments between function invocations, sensitive information shouldn't be
stored in the environment.

- To store Firebase API keys (which are [*not* secret](https://firebase.google.com/support/guides/security-checklist.md.txt#api-keys-not-secret)),
  just embed them in code.

- If you're using the Firebase Admin SDK in a Cloud Functions, you don't need
  to explicitly provide service account credentials, because the Admin SDK
  can automatically acquire them during initialization.

- If you're calling Google and Google Cloud APIs that require service account
  credentials, the Google Auth library for Node.js can get these credentials
  from the
  [application default credentials](https://github.com/googleapis/google-auth-library-nodejs#application-default-credentials),
  which are automatically populated in Cloud Functions.

- To make private keys and credentials for non-Google services available to your
  Cloud Functions, use
  [Secret Manager](https://cloud.google.com/secret-manager).

#### Yes Encrypt sensitive information

If you can't avoid passing sensitive information to your functions, you must
come up with your own custom solution to encrypt the information.

#### Yes Simple functions are safer; if you need complexity, consider Cloud Run

Try to keep your functions as basic and understandable as possible. Complexity
in your functions can often lead to hard-to-spot bugs or unexpected behavior.

If you do need complex logic or environment configurations, consider using
[Cloud Run](https://cloud.google.com/run) instead of
Cloud Functions.

## Environment management

#### Yes Set up development and staging projects

Set up separate Firebase projects for development, staging, and production.
Don't merge client code to production until it's been tested against the staging
project.

#### Yes Limit team access to production data

If you work with a larger team, you can mitigate the consequences of mistakes
and breaches by limiting access to production data using either
[predefined IAM roles](https://firebase.google.com/docs/projects/iam/roles-predefined.md.txt) or
[custom IAM roles](https://firebase.google.com/docs/projects/iam/roles-custom.md.txt).

If your team uses the [Firebase Local Emulator Suite](https://firebase.google.com/docs/emulator-suite.md.txt)
*(recommended)* for development, you might not need to grant wider access to the
production project.

## Library management

#### Yes Watch out for library misspellings or new maintainers

When adding libraries to your project, pay close attention to the name of the
library and its maintainers. A similarly-named library to the one you intend to
install could contain malicious code.

#### Yes Don't update libraries without understanding the changes

Look over the change logs of any libraries you use before you upgrade. Be sure
the upgrade adds value, and check that the maintainer is still a party you
trust.

#### Yes Install watchdog libraries as dev or test dependencies

Use a library such as [Snyk](https://snyk.io/) to scan your project
for insecure dependencies.

#### Yes Set up monitoring for Cloud Functions; check it after library updates

If you use the
[Cloud Functions logger SDK](https://firebase.google.com/docs/functions/writing-and-viewing-logs.md.txt), then
you can
[monitor and be alerted](https://cloud.google.com/logging/docs/logs-based-metrics/charts-and-alerts)
of unusual behavior, including behavior caused by library updates.