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 trust anchor configuration. This guide focuses on three capabilities: server certificate provisioning from gRPC endpoints, mTLS client validation modes, and Trust Config integration for certificate authorities.
Server TLS policies don’t affect traffic until attached to HTTPS proxies or endpoint config selectors. Examples reference gRPC endpoints and Certificate Manager TrustConfig resources that must exist separately. The examples are intentionally small. Combine them with your own proxy configuration and certificate infrastructure.
Provision server certificates from a gRPC endpoint
Load balancers need server certificates to terminate TLS. When certificates are managed externally, the policy references a gRPC endpoint that provides certificate material at runtime.
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 proxy where to fetch its certificate. The grpcEndpoint.targetUri points to a certificate provider (here, a Unix socket). Setting allowOpen to false ensures the server rejects plaintext connections.
Validate client certificates with mTLS
Mutual TLS requires both server and client to present certificates, enabling zero-trust authentication for service-to-service communication.
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 mtlsPolicy block enables client certificate validation. The clientValidationCas array specifies gRPC endpoints that provide trusted CA certificates for validating client certificates. The serverCertificate block provisions the server’s own certificate using the google_cloud_private_spiffe plugin, which integrates with SPIFFE-based identity systems.
Reject invalid client certificates with Trust Config
Production mTLS deployments often need strict validation against a trusted certificate authority hierarchy managed through Certificate Manager.
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: {}
This configuration extends basic mTLS with strict validation. The clientValidationMode set to REJECT_INVALID refuses connections from clients with invalid or missing certificates. The clientValidationTrustConfig references a Certificate Manager TrustConfig resource that defines trust anchors and intermediate CAs. The TrustConfig resource loads CA certificates from PEM files and manages the trust hierarchy.
Allow connections with missing or invalid client certificates
During migration to mTLS, services may need to accept both authenticated and unauthenticated clients while monitoring certificate adoption.
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 set to ALLOW_INVALID_OR_MISSING_CLIENT_CERT permits connections even when clients don’t present valid certificates. This supports gradual mTLS rollout: you can deploy the policy, observe which clients send certificates, and later switch to REJECT_INVALID for strict enforcement.
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 full load balancer configurations.
The examples reference pre-existing infrastructure such as HTTPS proxies or endpoint config selectors (policy attachment points), gRPC endpoints for certificate provisioning, Certificate Manager TrustConfig resources, and CA certificate files for trust anchors. They focus on configuring the policy rather than provisioning the surrounding infrastructure.
To keep things focused, common TLS patterns are omitted, including:
- Policy attachment to HTTPS proxies or endpoint selectors
- Certificate rotation and renewal workflows
- Custom certificate provider plugins
- Traffic Director-specific configurations (allowOpen with plaintext)
These omissions are intentional: the goal is to illustrate how each TLS policy 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
Policy Attachment & Activation
mTLS Configuration
mtlsPolicy field is required for external HTTPS load balancers but can be empty for Traffic Director policies.serverCertificate dictates whether mTLS is enabled. It provisions client identity (public and private keys) for peer-to-peer authentication.mtlsPolicy.clientValidationTrustConfig to reference your TrustConfig resource, and configure clientValidationMode (e.g., REJECT_INVALID).clientValidationMode to values like ALLOW_INVALID_OR_MISSING_CLIENT_CERT (permissive) or REJECT_INVALID (strict validation).Traffic Director vs External HTTPS Load Balancer
allowOpen for plaintext connections and have optional mtlsPolicy. External HTTPS load balancer policies must set allowOpen to false and require mtlsPolicy.allowOpen field allows plaintext connections alongside TLS/mTLS. Use it for in-place upgrades when you have mixed TLS and non-TLS traffic. It only applies to Traffic Director policies and must be false for external HTTPS load balancers.Resource Management
name and project properties cannot be changed after the ServerTlsPolicy is created.labels field is non-authoritative and only manages labels in your configuration. Use effectiveLabels to see all labels on the resource, including those set by other clients and services.global.