The gcp:networksecurity/serverTlsPolicy:ServerTlsPolicy resource, part of the Pulumi GCP provider, defines how servers authenticate incoming TLS connections: certificate provisioning, client validation requirements, and mTLS enforcement. This guide focuses on three capabilities: server certificate provisioning from external providers, mTLS client validation modes, and trust config integration.
Server TLS policies reference external certificate providers, gRPC endpoints, and Certificate Manager trust configs. The policy itself has no effect until attached to a target HTTPS proxy or endpoint config selector. The examples are intentionally small. Combine them with your own load balancer or proxy configuration.
Provision server certificates from a gRPC endpoint
Load balancers need to present certificates during TLS handshakes. When certificates are managed externally, the policy fetches them from a gRPC endpoint.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = new gcp.networksecurity.ServerTlsPolicy("default", {
name: "my-server-tls-policy",
labels: {
foo: "bar",
},
description: "my description",
location: "global",
allowOpen: false,
serverCertificate: {
grpcEndpoint: {
targetUri: "unix:mypath",
},
},
});
import pulumi
import pulumi_gcp as gcp
default = gcp.networksecurity.ServerTlsPolicy("default",
name="my-server-tls-policy",
labels={
"foo": "bar",
},
description="my description",
location="global",
allow_open=False,
server_certificate={
"grpc_endpoint": {
"target_uri": "unix:mypath",
},
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networksecurity"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := networksecurity.NewServerTlsPolicy(ctx, "default", &networksecurity.ServerTlsPolicyArgs{
Name: pulumi.String("my-server-tls-policy"),
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
Description: pulumi.String("my description"),
Location: pulumi.String("global"),
AllowOpen: pulumi.Bool(false),
ServerCertificate: &networksecurity.ServerTlsPolicyServerCertificateArgs{
GrpcEndpoint: &networksecurity.ServerTlsPolicyServerCertificateGrpcEndpointArgs{
TargetUri: pulumi.String("unix:mypath"),
},
},
})
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 @default = new Gcp.NetworkSecurity.ServerTlsPolicy("default", new()
{
Name = "my-server-tls-policy",
Labels =
{
{ "foo", "bar" },
},
Description = "my description",
Location = "global",
AllowOpen = false,
ServerCertificate = new Gcp.NetworkSecurity.Inputs.ServerTlsPolicyServerCertificateArgs
{
GrpcEndpoint = new Gcp.NetworkSecurity.Inputs.ServerTlsPolicyServerCertificateGrpcEndpointArgs
{
TargetUri = "unix:mypath",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networksecurity.ServerTlsPolicy;
import com.pulumi.gcp.networksecurity.ServerTlsPolicyArgs;
import com.pulumi.gcp.networksecurity.inputs.ServerTlsPolicyServerCertificateArgs;
import com.pulumi.gcp.networksecurity.inputs.ServerTlsPolicyServerCertificateGrpcEndpointArgs;
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 default_ = new ServerTlsPolicy("default", ServerTlsPolicyArgs.builder()
.name("my-server-tls-policy")
.labels(Map.of("foo", "bar"))
.description("my description")
.location("global")
.allowOpen(false)
.serverCertificate(ServerTlsPolicyServerCertificateArgs.builder()
.grpcEndpoint(ServerTlsPolicyServerCertificateGrpcEndpointArgs.builder()
.targetUri("unix:mypath")
.build())
.build())
.build());
}
}
resources:
default:
type: gcp:networksecurity:ServerTlsPolicy
properties:
name: my-server-tls-policy
labels:
foo: bar
description: my description
location: global
allowOpen: 'false'
serverCertificate:
grpcEndpoint:
targetUri: unix:mypath
The serverCertificate block tells the policy where to fetch certificates at runtime. The grpcEndpoint.targetUri points to a certificate provider service. Setting allowOpen to false ensures the server rejects plain text connections.
Validate client certificates with mTLS and SPIFFE
Mutual TLS requires both server and client to present certificates. Service mesh architectures often use SPIFFE for workload identity.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = new gcp.networksecurity.ServerTlsPolicy("default", {
name: "my-server-tls-policy",
labels: {
foo: "bar",
},
description: "my description",
allowOpen: false,
serverCertificate: {
certificateProviderInstance: {
pluginInstance: "google_cloud_private_spiffe",
},
},
mtlsPolicy: {
clientValidationCas: [{
grpcEndpoint: {
targetUri: "unix:mypath",
},
}],
},
});
import pulumi
import pulumi_gcp as gcp
default = gcp.networksecurity.ServerTlsPolicy("default",
name="my-server-tls-policy",
labels={
"foo": "bar",
},
description="my description",
allow_open=False,
server_certificate={
"certificate_provider_instance": {
"plugin_instance": "google_cloud_private_spiffe",
},
},
mtls_policy={
"client_validation_cas": [{
"grpc_endpoint": {
"target_uri": "unix:mypath",
},
}],
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networksecurity"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := networksecurity.NewServerTlsPolicy(ctx, "default", &networksecurity.ServerTlsPolicyArgs{
Name: pulumi.String("my-server-tls-policy"),
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
Description: pulumi.String("my description"),
AllowOpen: pulumi.Bool(false),
ServerCertificate: &networksecurity.ServerTlsPolicyServerCertificateArgs{
CertificateProviderInstance: &networksecurity.ServerTlsPolicyServerCertificateCertificateProviderInstanceArgs{
PluginInstance: pulumi.String("google_cloud_private_spiffe"),
},
},
MtlsPolicy: &networksecurity.ServerTlsPolicyMtlsPolicyArgs{
ClientValidationCas: networksecurity.ServerTlsPolicyMtlsPolicyClientValidationCaArray{
&networksecurity.ServerTlsPolicyMtlsPolicyClientValidationCaArgs{
GrpcEndpoint: &networksecurity.ServerTlsPolicyMtlsPolicyClientValidationCaGrpcEndpointArgs{
TargetUri: pulumi.String("unix:mypath"),
},
},
},
},
})
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 @default = new Gcp.NetworkSecurity.ServerTlsPolicy("default", new()
{
Name = "my-server-tls-policy",
Labels =
{
{ "foo", "bar" },
},
Description = "my description",
AllowOpen = false,
ServerCertificate = new Gcp.NetworkSecurity.Inputs.ServerTlsPolicyServerCertificateArgs
{
CertificateProviderInstance = new Gcp.NetworkSecurity.Inputs.ServerTlsPolicyServerCertificateCertificateProviderInstanceArgs
{
PluginInstance = "google_cloud_private_spiffe",
},
},
MtlsPolicy = new Gcp.NetworkSecurity.Inputs.ServerTlsPolicyMtlsPolicyArgs
{
ClientValidationCas = new[]
{
new Gcp.NetworkSecurity.Inputs.ServerTlsPolicyMtlsPolicyClientValidationCaArgs
{
GrpcEndpoint = new Gcp.NetworkSecurity.Inputs.ServerTlsPolicyMtlsPolicyClientValidationCaGrpcEndpointArgs
{
TargetUri = "unix:mypath",
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networksecurity.ServerTlsPolicy;
import com.pulumi.gcp.networksecurity.ServerTlsPolicyArgs;
import com.pulumi.gcp.networksecurity.inputs.ServerTlsPolicyServerCertificateArgs;
import com.pulumi.gcp.networksecurity.inputs.ServerTlsPolicyServerCertificateCertificateProviderInstanceArgs;
import com.pulumi.gcp.networksecurity.inputs.ServerTlsPolicyMtlsPolicyArgs;
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 default_ = new ServerTlsPolicy("default", ServerTlsPolicyArgs.builder()
.name("my-server-tls-policy")
.labels(Map.of("foo", "bar"))
.description("my description")
.allowOpen(false)
.serverCertificate(ServerTlsPolicyServerCertificateArgs.builder()
.certificateProviderInstance(ServerTlsPolicyServerCertificateCertificateProviderInstanceArgs.builder()
.pluginInstance("google_cloud_private_spiffe")
.build())
.build())
.mtlsPolicy(ServerTlsPolicyMtlsPolicyArgs.builder()
.clientValidationCas(ServerTlsPolicyMtlsPolicyClientValidationCaArgs.builder()
.grpcEndpoint(ServerTlsPolicyMtlsPolicyClientValidationCaGrpcEndpointArgs.builder()
.targetUri("unix:mypath")
.build())
.build())
.build())
.build());
}
}
resources:
default:
type: gcp:networksecurity:ServerTlsPolicy
properties:
name: my-server-tls-policy
labels:
foo: bar
description: my description
allowOpen: 'false'
serverCertificate:
certificateProviderInstance:
pluginInstance: google_cloud_private_spiffe
mtlsPolicy:
clientValidationCas:
- grpcEndpoint:
targetUri: unix:mypath
The serverCertificate block provisions server identity using the google_cloud_private_spiffe plugin. The mtlsPolicy.clientValidationCas block specifies where to fetch client CA certificates for validation. This configuration enforces mutual authentication: both parties must present valid certificates.
Allow invalid or missing client certificates
During migration to mTLS, you may need to accept connections from clients without valid certificates.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = new gcp.networksecurity.ServerTlsPolicy("default", {
name: "my-server-tls-policy",
labels: {
foo: "bar",
},
description: "my description",
location: "global",
allowOpen: false,
mtlsPolicy: {
clientValidationMode: "ALLOW_INVALID_OR_MISSING_CLIENT_CERT",
},
});
import pulumi
import pulumi_gcp as gcp
default = gcp.networksecurity.ServerTlsPolicy("default",
name="my-server-tls-policy",
labels={
"foo": "bar",
},
description="my description",
location="global",
allow_open=False,
mtls_policy={
"client_validation_mode": "ALLOW_INVALID_OR_MISSING_CLIENT_CERT",
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networksecurity"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := networksecurity.NewServerTlsPolicy(ctx, "default", &networksecurity.ServerTlsPolicyArgs{
Name: pulumi.String("my-server-tls-policy"),
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
Description: pulumi.String("my description"),
Location: pulumi.String("global"),
AllowOpen: pulumi.Bool(false),
MtlsPolicy: &networksecurity.ServerTlsPolicyMtlsPolicyArgs{
ClientValidationMode: pulumi.String("ALLOW_INVALID_OR_MISSING_CLIENT_CERT"),
},
})
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 @default = new Gcp.NetworkSecurity.ServerTlsPolicy("default", new()
{
Name = "my-server-tls-policy",
Labels =
{
{ "foo", "bar" },
},
Description = "my description",
Location = "global",
AllowOpen = false,
MtlsPolicy = new Gcp.NetworkSecurity.Inputs.ServerTlsPolicyMtlsPolicyArgs
{
ClientValidationMode = "ALLOW_INVALID_OR_MISSING_CLIENT_CERT",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.networksecurity.ServerTlsPolicy;
import com.pulumi.gcp.networksecurity.ServerTlsPolicyArgs;
import com.pulumi.gcp.networksecurity.inputs.ServerTlsPolicyMtlsPolicyArgs;
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 default_ = new ServerTlsPolicy("default", ServerTlsPolicyArgs.builder()
.name("my-server-tls-policy")
.labels(Map.of("foo", "bar"))
.description("my description")
.location("global")
.allowOpen(false)
.mtlsPolicy(ServerTlsPolicyMtlsPolicyArgs.builder()
.clientValidationMode("ALLOW_INVALID_OR_MISSING_CLIENT_CERT")
.build())
.build());
}
}
resources:
default:
type: gcp:networksecurity:ServerTlsPolicy
properties:
name: my-server-tls-policy
labels:
foo: bar
description: my description
location: global
allowOpen: 'false'
mtlsPolicy:
clientValidationMode: ALLOW_INVALID_OR_MISSING_CLIENT_CERT
The clientValidationMode property controls how strictly the server validates client certificates. ALLOW_INVALID_OR_MISSING_CLIENT_CERT accepts connections even when clients don’t present certificates or present invalid ones. This mode supports gradual mTLS adoption.
Validate client certificates against a trust config
Production mTLS deployments validate client certificates against a trust store containing root and intermediate CAs.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as std from "@pulumi/std";
const project = gcp.organizations.getProject({});
const defaultTrustConfig = new gcp.certificatemanager.TrustConfig("default", {
name: "my-trust-config",
description: "sample trust config description",
location: "global",
trustStores: [{
trustAnchors: [{
pemCertificate: std.file({
input: "test-fixtures/ca_cert.pem",
}).then(invoke => invoke.result),
}],
intermediateCas: [{
pemCertificate: std.file({
input: "test-fixtures/ca_cert.pem",
}).then(invoke => invoke.result),
}],
}],
labels: {
foo: "bar",
},
});
const _default = new gcp.networksecurity.ServerTlsPolicy("default", {
name: "my-server-tls-policy",
description: "my description",
location: "global",
allowOpen: false,
mtlsPolicy: {
clientValidationMode: "REJECT_INVALID",
clientValidationTrustConfig: pulumi.all([project, defaultTrustConfig.name]).apply(([project, name]) => `projects/${project.number}/locations/global/trustConfigs/${name}`),
},
labels: {
foo: "bar",
},
});
import pulumi
import pulumi_gcp as gcp
import pulumi_std as std
project = gcp.organizations.get_project()
default_trust_config = gcp.certificatemanager.TrustConfig("default",
name="my-trust-config",
description="sample trust config description",
location="global",
trust_stores=[{
"trust_anchors": [{
"pem_certificate": std.file(input="test-fixtures/ca_cert.pem").result,
}],
"intermediate_cas": [{
"pem_certificate": std.file(input="test-fixtures/ca_cert.pem").result,
}],
}],
labels={
"foo": "bar",
})
default = gcp.networksecurity.ServerTlsPolicy("default",
name="my-server-tls-policy",
description="my description",
location="global",
allow_open=False,
mtls_policy={
"client_validation_mode": "REJECT_INVALID",
"client_validation_trust_config": default_trust_config.name.apply(lambda name: f"projects/{project.number}/locations/global/trustConfigs/{name}"),
},
labels={
"foo": "bar",
})
package main
import (
"fmt"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/certificatemanager"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/networksecurity"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/organizations"
"github.com/pulumi/pulumi-std/sdk/go/std"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
project, err := organizations.LookupProject(ctx, &organizations.LookupProjectArgs{}, nil)
if err != nil {
return err
}
invokeFile, err := std.File(ctx, &std.FileArgs{
Input: "test-fixtures/ca_cert.pem",
}, nil)
if err != nil {
return err
}
invokeFile1, err := std.File(ctx, &std.FileArgs{
Input: "test-fixtures/ca_cert.pem",
}, nil)
if err != nil {
return err
}
defaultTrustConfig, err := certificatemanager.NewTrustConfig(ctx, "default", &certificatemanager.TrustConfigArgs{
Name: pulumi.String("my-trust-config"),
Description: pulumi.String("sample trust config description"),
Location: pulumi.String("global"),
TrustStores: certificatemanager.TrustConfigTrustStoreArray{
&certificatemanager.TrustConfigTrustStoreArgs{
TrustAnchors: certificatemanager.TrustConfigTrustStoreTrustAnchorArray{
&certificatemanager.TrustConfigTrustStoreTrustAnchorArgs{
PemCertificate: pulumi.String(invokeFile.Result),
},
},
IntermediateCas: certificatemanager.TrustConfigTrustStoreIntermediateCaArray{
&certificatemanager.TrustConfigTrustStoreIntermediateCaArgs{
PemCertificate: pulumi.String(invokeFile1.Result),
},
},
},
},
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
})
if err != nil {
return err
}
_, err = networksecurity.NewServerTlsPolicy(ctx, "default", &networksecurity.ServerTlsPolicyArgs{
Name: pulumi.String("my-server-tls-policy"),
Description: pulumi.String("my description"),
Location: pulumi.String("global"),
AllowOpen: pulumi.Bool(false),
MtlsPolicy: &networksecurity.ServerTlsPolicyMtlsPolicyArgs{
ClientValidationMode: pulumi.String("REJECT_INVALID"),
ClientValidationTrustConfig: defaultTrustConfig.Name.ApplyT(func(name string) (string, error) {
return fmt.Sprintf("projects/%v/locations/global/trustConfigs/%v", project.Number, name), nil
}).(pulumi.StringOutput),
},
Labels: pulumi.StringMap{
"foo": pulumi.String("bar"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Std = Pulumi.Std;
return await Deployment.RunAsync(() =>
{
var project = Gcp.Organizations.GetProject.Invoke();
var defaultTrustConfig = new Gcp.CertificateManager.TrustConfig("default", new()
{
Name = "my-trust-config",
Description = "sample trust config description",
Location = "global",
TrustStores = new[]
{
new Gcp.CertificateManager.Inputs.TrustConfigTrustStoreArgs
{
TrustAnchors = new[]
{
new Gcp.CertificateManager.Inputs.TrustConfigTrustStoreTrustAnchorArgs
{
PemCertificate = Std.File.Invoke(new()
{
Input = "test-fixtures/ca_cert.pem",
}).Apply(invoke => invoke.Result),
},
},
IntermediateCas = new[]
{
new Gcp.CertificateManager.Inputs.TrustConfigTrustStoreIntermediateCaArgs
{
PemCertificate = Std.File.Invoke(new()
{
Input = "test-fixtures/ca_cert.pem",
}).Apply(invoke => invoke.Result),
},
},
},
},
Labels =
{
{ "foo", "bar" },
},
});
var @default = new Gcp.NetworkSecurity.ServerTlsPolicy("default", new()
{
Name = "my-server-tls-policy",
Description = "my description",
Location = "global",
AllowOpen = false,
MtlsPolicy = new Gcp.NetworkSecurity.Inputs.ServerTlsPolicyMtlsPolicyArgs
{
ClientValidationMode = "REJECT_INVALID",
ClientValidationTrustConfig = Output.Tuple(project, defaultTrustConfig.Name).Apply(values =>
{
var project = values.Item1;
var name = values.Item2;
return $"projects/{project.Apply(getProjectResult => getProjectResult.Number)}/locations/global/trustConfigs/{name}";
}),
},
Labels =
{
{ "foo", "bar" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.organizations.OrganizationsFunctions;
import com.pulumi.gcp.organizations.inputs.GetProjectArgs;
import com.pulumi.gcp.certificatemanager.TrustConfig;
import com.pulumi.gcp.certificatemanager.TrustConfigArgs;
import com.pulumi.gcp.certificatemanager.inputs.TrustConfigTrustStoreArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.FileArgs;
import com.pulumi.gcp.networksecurity.ServerTlsPolicy;
import com.pulumi.gcp.networksecurity.ServerTlsPolicyArgs;
import com.pulumi.gcp.networksecurity.inputs.ServerTlsPolicyMtlsPolicyArgs;
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) {
final var project = OrganizationsFunctions.getProject(GetProjectArgs.builder()
.build());
var defaultTrustConfig = new TrustConfig("defaultTrustConfig", TrustConfigArgs.builder()
.name("my-trust-config")
.description("sample trust config description")
.location("global")
.trustStores(TrustConfigTrustStoreArgs.builder()
.trustAnchors(TrustConfigTrustStoreTrustAnchorArgs.builder()
.pemCertificate(StdFunctions.file(FileArgs.builder()
.input("test-fixtures/ca_cert.pem")
.build()).result())
.build())
.intermediateCas(TrustConfigTrustStoreIntermediateCaArgs.builder()
.pemCertificate(StdFunctions.file(FileArgs.builder()
.input("test-fixtures/ca_cert.pem")
.build()).result())
.build())
.build())
.labels(Map.of("foo", "bar"))
.build());
var default_ = new ServerTlsPolicy("default", ServerTlsPolicyArgs.builder()
.name("my-server-tls-policy")
.description("my description")
.location("global")
.allowOpen(false)
.mtlsPolicy(ServerTlsPolicyMtlsPolicyArgs.builder()
.clientValidationMode("REJECT_INVALID")
.clientValidationTrustConfig(defaultTrustConfig.name().applyValue(_name -> String.format("projects/%s/locations/global/trustConfigs/%s", project.number(),_name)))
.build())
.labels(Map.of("foo", "bar"))
.build());
}
}
resources:
default:
type: gcp:networksecurity:ServerTlsPolicy
properties:
name: my-server-tls-policy
description: my description
location: global
allowOpen: 'false'
mtlsPolicy:
clientValidationMode: REJECT_INVALID
clientValidationTrustConfig: projects/${project.number}/locations/global/trustConfigs/${defaultTrustConfig.name}
labels:
foo: bar
defaultTrustConfig:
type: gcp:certificatemanager:TrustConfig
name: default
properties:
name: my-trust-config
description: sample trust config description
location: global
trustStores:
- trustAnchors:
- pemCertificate:
fn::invoke:
function: std:file
arguments:
input: test-fixtures/ca_cert.pem
return: result
intermediateCas:
- pemCertificate:
fn::invoke:
function: std:file
arguments:
input: test-fixtures/ca_cert.pem
return: result
labels:
foo: bar
variables:
project:
fn::invoke:
function: gcp:organizations:getProject
arguments: {}
The clientValidationTrustConfig property references a Certificate Manager TrustConfig resource that defines trusted CAs. Setting clientValidationMode to REJECT_INVALID enforces strict validation: connections fail if the client certificate isn’t signed by a trusted CA. This builds on basic mTLS by adding centralized trust management.
Beyond these examples
These snippets focus on specific server TLS policy features: server certificate provisioning, mTLS client validation modes, and trust config integration. They’re intentionally minimal rather than complete load balancer configurations.
The examples reference pre-existing infrastructure such as gRPC certificate provider endpoints, Certificate Manager TrustConfig resources, SPIFFE plugin configuration, and target HTTPS proxies or endpoint config selectors for policy attachment. They focus on policy configuration rather than provisioning the surrounding infrastructure.
To keep things focused, common server TLS patterns are omitted, including:
- Policy attachment to load balancers or proxies
- Certificate rotation and renewal
- Traffic Director-specific configuration
- Plain text connection handling (allowOpen variations)
These omissions are intentional: the goal is to illustrate how each server TLS feature is wired, not provide drop-in load balancer modules. See the ServerTlsPolicy resource reference for all available configuration options.
Let's configure GCP Server TLS Policies
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Attachment
Load Balancer Compatibility
mtlsPolicy is required and allowOpen must be set to false. For Traffic Director, mtlsPolicy can be empty and allowOpen can be true to allow plaintext connections.allowOpen allows plaintext connections alongside encrypted traffic. Use it when upgrading deployments to TLS with mixed TLS and non-TLS traffic on port 80. This field only applies to Traffic Director policies and must be false for external HTTPS load balancers.mTLS & Certificate Configuration
mtlsPolicy (for peer validation certificates) or serverCertificate (for client identity provisioning). The presence of serverCertificate dictates mTLS. For certificate validation, use mtlsPolicy with clientValidationMode and clientValidationTrustConfig pointing to a TrustConfig resource.Resource Properties & Lifecycle
name and project properties are immutable and cannot be changed after the ServerTlsPolicy is created.global.