gRPC Security#
gRPC uses HTTP/2 as its transport, which means TLS is not just a security feature — it is a practical necessity. Many load balancers, proxies, and clients expect HTTP/2 over TLS (h2) rather than plaintext HTTP/2 (h2c). Securing gRPC means configuring TLS correctly, authenticating clients, authorizing RPCs, and handling the gRPC-specific gotchas that do not exist with REST APIs.
gRPC Over TLS#
Server-Side TLS in Go#
import (
"crypto/tls"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
func main() {
cert, err := tls.LoadX509KeyPair("server-cert.pem", "server-key.pem")
if err != nil {
log.Fatal(err)
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS13,
}
creds := credentials.NewTLS(tlsConfig)
server := grpc.NewServer(grpc.Creds(creds))
pb.RegisterMyServiceServer(server, &myService{})
lis, _ := net.Listen("tcp", ":50051")
server.Serve(lis)
}Client-Side TLS in Go#
import (
"crypto/x509"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
func main() {
// For public CAs (Let's Encrypt, etc.), use system cert pool
creds := credentials.NewTLS(&tls.Config{
MinVersion: tls.VersionTLS13,
})
// For internal CAs, load the CA cert explicitly
caCert, _ := os.ReadFile("ca-cert.pem")
certPool := x509.NewCertPool()
certPool.AppendCertsFromPEM(caCert)
creds = credentials.NewTLS(&tls.Config{
RootCAs: certPool,
MinVersion: tls.VersionTLS13,
})
conn, err := grpc.NewClient("api.internal:50051",
grpc.WithTransportCredentials(creds),
)
defer conn.Close()
client := pb.NewMyServiceClient(conn)
}TLS in Python#
import grpc
# Server
server_credentials = grpc.ssl_server_credentials(
[(open("server-key.pem", "rb").read(), open("server-cert.pem", "rb").read())]
)
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
pb_grpc.add_MyServiceServicer_to_server(MyService(), server)
server.add_secure_port("[::]:50051", server_credentials)
server.start()
# Client
ca_cert = open("ca-cert.pem", "rb").read()
channel_credentials = grpc.ssl_channel_credentials(root_certificates=ca_cert)
channel = grpc.secure_channel("api.internal:50051", channel_credentials)
client = pb_grpc.MyServiceStub(channel)Mutual TLS for gRPC#
mTLS is the strongest authentication model for service-to-service gRPC. Each service has a certificate, and both sides verify each other.