Firebase: Separating configuration from code in Admin SDK
Firebase Admin SDKs are used to access Firebase services from trusted server-side environments. However, before any Firebase services can be accessed, one must initialize the Admin SDK with a valid set of Google credentials. Google credentials come in several forms, and they authorize applications to access Firebase and various other Google Cloud Platform (GCP) services.
Service account credentials are one of the most commonly used types of Google credentials. These credentials can be downloaded as JSON files from the GCP console or the Firebase console, and explicitly passed into the Admin SDK as shown in listing 1.
While this approach is fairly straightforward to get started with, it poses some challenges in the long run:
- The service account credentials must be packaged and deployed along with the code, which complicates the associated DevOps procedures.
- The accidental exposure of a service account credentials file may have serious consequences in terms of application and data security.
Therefore it is often a good idea to use an implicit form of credentials such as Google Application Default Credentials (ADC). ADC prevents the developer from having to ship a tangible credentials file along with the code. Instead, ADC enables the application to automatically discover credentials from its runtime environment. And since there are no sensitive assets that may get accidentally exposed during the deployment process, ADC can also improve the security level of deployed applications.
Using Application Default Credentials
ADC discovery works out of the box when application code is deployed in GCP environments like App Engine, Compute Engine and Cloud Functions. For local testing there are two ways to seed the environment with Google credentials so ADC discovery would succeed:
- Save a service account credentials file to a secure location in the local file system, and set the
GOOGLE_APPLICATION_CREDENTIALSenvironment variable pointing to that file.
- Install the Google Cloud SDK, and execute the command
gcloud auth application-default login.
The first approach is suitable for both local testing, and production deployments outside of GCP. The latter is strictly for local testing. Once you have your development environment set up in one of these two ways, you can initialize the Firebase Admin SDK with ADC as shown in listing 2.
Notice that we no longer have to hardcode a file path into the application. Once you have tested your code locally, you can simply move it to GCP where it will continue to work without any additional configurations.
There is one caveat to using ADC that is worth mentioning here. Features that involve cryptographically signing data do not work when the Firebase Admin SDK is initialized with ADC. Custom token minting and generating signed URLs for Cloud Storage objects are the most prominent features of this nature. A private key is required to sign data, and currently the Admin SDK can only obtain private keys from service account credentials. This limitation may get addressed in the future, thereby enabling more unconstrained usage of ADC.
Loading other Firebase options from the environment
ADC enables us to take Google credentials out of the application. But what about other Firebase settings? Listing 2 shows that we still have to hardcode the Firebase database URL into the application. Same is true for other Firebase options like Cloud Storage bucket and GCP project ID. Wouldn’t it be nice if the Admin SDK could auto discover these parameters from the environment, so that you can completely decouple your code from the configuration? Actually, now you can!
Firebase team just released a new feature in the Admin SDK that enables loading all Firebase configuration options from the environment. Simply create a JSON file similar to listing 3 containing the necessary settings, and set the
FIREBASE_CONFIG environment variable to point to it.
Now you can initialize the Firebase Admin SDK without any arguments as shown in listing 4.
This instructs the SDK to fetch Firebase options from the environment, while using ADC for authorization. Similar APIs are now available in all programming languages that are supported by the Admin SDK (Node.js, Java, Python and Go). However, this is a new feature, and GCP does not support it out-of-the-box yet. But you can employ it in your development environments, and non-GCP deployments of Firebase Admin SDK as you see fit.
If you wish to immediately use this feature in GCP, you may do so by setting the
FIREBASE_CONFIG environment variable in your cloud instances. This is easily achievable in Compute Engine and App Engine. Without the variable your application will not auto discover Firebase options, but ADC discovery will work as usual. Hence right now this feature may not seem as powerful as ADC. Nevertheless, it provides a simple and language-neutral mechanism to separate Firebase options from application code. It will come to its own with time, as it becomes standardized in GCP.
Separating configuration from code is a widely used software engineering practice that leads to simpler and more maintainable code. With Application Default Credentials, and the new Admin SDK initialization APIs, developers can cleanly separate Google credentials and Firebase options from their applications. I hope this post encourages more developers to leverage these features, which simplifies development, while making applications more portable across different environments. Happy coding, and let me know what you think of the new Admin SDK initialization APIs.