The gcp:firebase/appCheckServiceConfig:AppCheckServiceConfig resource, part of the Pulumi GCP provider, controls App Check enforcement for individual Firebase services: whether requests require valid attestation tokens and whether metrics are collected. This guide focuses on two capabilities: enforcement mode configuration and service-specific protection settings.
App Check enforcement requires the App Check API enabled in your Firebase project. When enforcement is active, client apps must have App Check providers configured. The examples are intentionally small. Combine them with your App Check provider setup and client integration.
Enforce App Check validation for production services
Production Firebase services often require App Check enforcement to block requests without valid attestation tokens.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const appcheck = new gcp.projects.Service("appcheck", {
project: "my-project-name",
service: "firebaseappcheck.googleapis.com",
});
const _default = new gcp.firebase.AppCheckServiceConfig("default", {
project: "my-project-name",
serviceId: "firebasestorage.googleapis.com",
enforcementMode: "ENFORCED",
}, {
dependsOn: [appcheck],
});
import pulumi
import pulumi_gcp as gcp
appcheck = gcp.projects.Service("appcheck",
project="my-project-name",
service="firebaseappcheck.googleapis.com")
default = gcp.firebase.AppCheckServiceConfig("default",
project="my-project-name",
service_id="firebasestorage.googleapis.com",
enforcement_mode="ENFORCED",
opts = pulumi.ResourceOptions(depends_on=[appcheck]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/firebase"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/projects"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
appcheck, err := projects.NewService(ctx, "appcheck", &projects.ServiceArgs{
Project: pulumi.String("my-project-name"),
Service: pulumi.String("firebaseappcheck.googleapis.com"),
})
if err != nil {
return err
}
_, err = firebase.NewAppCheckServiceConfig(ctx, "default", &firebase.AppCheckServiceConfigArgs{
Project: pulumi.String("my-project-name"),
ServiceId: pulumi.String("firebasestorage.googleapis.com"),
EnforcementMode: pulumi.String("ENFORCED"),
}, pulumi.DependsOn([]pulumi.Resource{
appcheck,
}))
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var appcheck = new Gcp.Projects.Service("appcheck", new()
{
Project = "my-project-name",
ServiceName = "firebaseappcheck.googleapis.com",
});
var @default = new Gcp.Firebase.AppCheckServiceConfig("default", new()
{
Project = "my-project-name",
ServiceId = "firebasestorage.googleapis.com",
EnforcementMode = "ENFORCED",
}, new CustomResourceOptions
{
DependsOn =
{
appcheck,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.projects.Service;
import com.pulumi.gcp.projects.ServiceArgs;
import com.pulumi.gcp.firebase.AppCheckServiceConfig;
import com.pulumi.gcp.firebase.AppCheckServiceConfigArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var appcheck = new Service("appcheck", ServiceArgs.builder()
.project("my-project-name")
.service("firebaseappcheck.googleapis.com")
.build());
var default_ = new AppCheckServiceConfig("default", AppCheckServiceConfigArgs.builder()
.project("my-project-name")
.serviceId("firebasestorage.googleapis.com")
.enforcementMode("ENFORCED")
.build(), CustomResourceOptions.builder()
.dependsOn(appcheck)
.build());
}
}
resources:
appcheck:
type: gcp:projects:Service
properties:
project: my-project-name
service: firebaseappcheck.googleapis.com
default:
type: gcp:firebase:AppCheckServiceConfig
properties:
project: my-project-name
serviceId: firebasestorage.googleapis.com
enforcementMode: ENFORCED
options:
dependsOn:
- ${appcheck}
When enforcementMode is set to ENFORCED, the service rejects requests that lack valid App Check tokens, with limited exceptions for privileged service accounts. The serviceId specifies which Firebase backend to protect; supported services include Cloud Storage, Realtime Database, Firestore, and Authentication. Metrics continue to be collected to help you monitor token validation and detect integration issues.
Collect metrics without blocking requests
Before enforcing App Check, teams often collect metrics to understand traffic patterns and identify clients needing updates.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const appcheck = new gcp.projects.Service("appcheck", {
project: "my-project-name",
service: "firebaseappcheck.googleapis.com",
});
const _default = new gcp.firebase.AppCheckServiceConfig("default", {
project: "my-project-name",
serviceId: "identitytoolkit.googleapis.com",
enforcementMode: "UNENFORCED",
}, {
dependsOn: [appcheck],
});
import pulumi
import pulumi_gcp as gcp
appcheck = gcp.projects.Service("appcheck",
project="my-project-name",
service="firebaseappcheck.googleapis.com")
default = gcp.firebase.AppCheckServiceConfig("default",
project="my-project-name",
service_id="identitytoolkit.googleapis.com",
enforcement_mode="UNENFORCED",
opts = pulumi.ResourceOptions(depends_on=[appcheck]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/firebase"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/projects"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
appcheck, err := projects.NewService(ctx, "appcheck", &projects.ServiceArgs{
Project: pulumi.String("my-project-name"),
Service: pulumi.String("firebaseappcheck.googleapis.com"),
})
if err != nil {
return err
}
_, err = firebase.NewAppCheckServiceConfig(ctx, "default", &firebase.AppCheckServiceConfigArgs{
Project: pulumi.String("my-project-name"),
ServiceId: pulumi.String("identitytoolkit.googleapis.com"),
EnforcementMode: pulumi.String("UNENFORCED"),
}, pulumi.DependsOn([]pulumi.Resource{
appcheck,
}))
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var appcheck = new Gcp.Projects.Service("appcheck", new()
{
Project = "my-project-name",
ServiceName = "firebaseappcheck.googleapis.com",
});
var @default = new Gcp.Firebase.AppCheckServiceConfig("default", new()
{
Project = "my-project-name",
ServiceId = "identitytoolkit.googleapis.com",
EnforcementMode = "UNENFORCED",
}, new CustomResourceOptions
{
DependsOn =
{
appcheck,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.projects.Service;
import com.pulumi.gcp.projects.ServiceArgs;
import com.pulumi.gcp.firebase.AppCheckServiceConfig;
import com.pulumi.gcp.firebase.AppCheckServiceConfigArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var appcheck = new Service("appcheck", ServiceArgs.builder()
.project("my-project-name")
.service("firebaseappcheck.googleapis.com")
.build());
var default_ = new AppCheckServiceConfig("default", AppCheckServiceConfigArgs.builder()
.project("my-project-name")
.serviceId("identitytoolkit.googleapis.com")
.enforcementMode("UNENFORCED")
.build(), CustomResourceOptions.builder()
.dependsOn(appcheck)
.build());
}
}
resources:
appcheck:
type: gcp:projects:Service
properties:
project: my-project-name
service: firebaseappcheck.googleapis.com
default:
type: gcp:firebase:AppCheckServiceConfig
properties:
project: my-project-name
serviceId: identitytoolkit.googleapis.com
enforcementMode: UNENFORCED
options:
dependsOn:
- ${appcheck}
The UNENFORCED mode collects App Check metrics without rejecting requests. This lets you monitor which clients present valid tokens and plan your enforcement rollout. Other protections like user authorization remain active. Use this mode to verify your App Check integration works correctly before switching to ENFORCED.
Disable enforcement and metrics collection
Services that don’t require App Check protection can explicitly disable enforcement and metrics.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const appcheck = new gcp.projects.Service("appcheck", {
project: "my-project-name",
service: "firebaseappcheck.googleapis.com",
});
const _default = new gcp.firebase.AppCheckServiceConfig("default", {
project: "my-project-name",
serviceId: "firestore.googleapis.com",
}, {
dependsOn: [appcheck],
});
import pulumi
import pulumi_gcp as gcp
appcheck = gcp.projects.Service("appcheck",
project="my-project-name",
service="firebaseappcheck.googleapis.com")
default = gcp.firebase.AppCheckServiceConfig("default",
project="my-project-name",
service_id="firestore.googleapis.com",
opts = pulumi.ResourceOptions(depends_on=[appcheck]))
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/firebase"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/projects"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
appcheck, err := projects.NewService(ctx, "appcheck", &projects.ServiceArgs{
Project: pulumi.String("my-project-name"),
Service: pulumi.String("firebaseappcheck.googleapis.com"),
})
if err != nil {
return err
}
_, err = firebase.NewAppCheckServiceConfig(ctx, "default", &firebase.AppCheckServiceConfigArgs{
Project: pulumi.String("my-project-name"),
ServiceId: pulumi.String("firestore.googleapis.com"),
}, pulumi.DependsOn([]pulumi.Resource{
appcheck,
}))
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var appcheck = new Gcp.Projects.Service("appcheck", new()
{
Project = "my-project-name",
ServiceName = "firebaseappcheck.googleapis.com",
});
var @default = new Gcp.Firebase.AppCheckServiceConfig("default", new()
{
Project = "my-project-name",
ServiceId = "firestore.googleapis.com",
}, new CustomResourceOptions
{
DependsOn =
{
appcheck,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.projects.Service;
import com.pulumi.gcp.projects.ServiceArgs;
import com.pulumi.gcp.firebase.AppCheckServiceConfig;
import com.pulumi.gcp.firebase.AppCheckServiceConfigArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var appcheck = new Service("appcheck", ServiceArgs.builder()
.project("my-project-name")
.service("firebaseappcheck.googleapis.com")
.build());
var default_ = new AppCheckServiceConfig("default", AppCheckServiceConfigArgs.builder()
.project("my-project-name")
.serviceId("firestore.googleapis.com")
.build(), CustomResourceOptions.builder()
.dependsOn(appcheck)
.build());
}
}
resources:
appcheck:
type: gcp:projects:Service
properties:
project: my-project-name
service: firebaseappcheck.googleapis.com
default:
type: gcp:firebase:AppCheckServiceConfig
properties:
project: my-project-name
serviceId: firestore.googleapis.com
options:
dependsOn:
- ${appcheck}
Omitting the enforcementMode property (or deleting the resource entirely) returns the service to its default unconfigured state. In this mode, App Check is not enforced and metrics are not collected, though other protections like user authorization remain active. This is equivalent to the OFF state in the REST API.
Beyond these examples
These snippets focus on specific service configuration features: enforcement modes and service-specific protection settings. They’re intentionally minimal rather than complete App Check deployments.
The examples assume pre-existing infrastructure such as a Firebase project with App Check API enabled, and client apps configured with App Check providers when enforcement is active. They focus on configuring enforcement rather than provisioning the underlying App Check providers.
To keep things focused, common App Check patterns are omitted, including:
- App Check provider configuration (DeviceCheck, Play Integrity, reCAPTCHA)
- Custom token generation and validation
- Replay protection settings
- Service-specific exceptions and allowlists
These omissions are intentional: the goal is to illustrate how enforcement modes are configured, not provide drop-in App Check modules. See the Firebase AppCheckServiceConfig resource reference for all available configuration options.
Let's configure GCP Firebase App Check Service
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Enforcement Modes & Behavior
UNENFORCED mode first to collect metrics and verify client compatibility before switching to ENFORCED. For apps that haven’t launched yet, you can enable ENFORCED immediately since there are no outdated clients.There are three modes:
- Unset (OFF) - No enforcement or metrics collection (default for unconfigured services)
- UNENFORCED - Metrics collected but requests not blocked; helps you decide when to enforce
- ENFORCED - Requests without valid App Check tokens are rejected (with some exceptions for privileged service accounts)
enforcementMode to UNENFORCED instead of deleting the resource.Service Configuration
Currently, four services are supported:
firebasestorage.googleapis.com(Cloud Storage for Firebase)firebasedatabase.googleapis.com(Firebase Realtime Database)firestore.googleapis.com(Cloud Firestore)identitytoolkit.googleapis.com(Authentication)
firebaseappcheck.googleapis.com service must be enabled in your project before you can configure enforcement for individual Firebase services. All examples show this dependency using dependsOn.Resource Lifecycle
serviceId and project are immutable. Changing either property will force resource replacement.projects/{{project}}/services/{{service_id}}, {{project}}/{{service_id}}, or just {{service_id}}. The service ID must be one of the four supported Firebase services.