[gRPC] Authentication

Tags
gRPC
Engineering
Created
Nov 17, 2023 12:56 AM
Edited
Nov 16, 2023
Description

TLS/SSL

Very common and required for gRPC. Support building mTLS with the followings:
  • "server_cert.pem" contains the server certificate (public key).
  • "server_key.pem" contains the server private key.
  • "ca_cert.pem" contains the certificate (certificate authority) that can verify the server's certificate.
Although it mostly covers “encryption”, still, the certificate itself should be provisioned by trusted CAs.

Server side

// Load server cert and key
cert, err := tls.LoadX509KeyPair(data.Path("x509/server_cert.pem"), data.Path("x509/server_key.pem"))
if err != nil {
  log.Fatalf("failed to load key pair: %s", err)
}

// Load client CA cert
ca := x509.NewCertPool()
caFilePath := data.Path("x509/client_ca_cert.pem")
caBytes, err := os.ReadFile(caFilePath)

if ok := ca.AppendCertsFromPEM(caBytes); !ok {
	log.Fatalf("failed to parse %q", caFilePath)
}

// Set up TLS config
tlsConfig := &tls.Config{
	ClientAuth:   tls.RequireAndVerifyClientCert,
	Certificates: []tls.Certificate{cert},
	ClientCAs:    ca,
}

// Create server with tls config
s := grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsConfig)))

Client side

// Load client cert and key
cert, err := tls.LoadX509KeyPair(data.Path("x509/client_cert.pem"), data.Path("x509/client_key.pem"))
if err != nil {
  log.Fatalf("failed to load client cert: %v", err)
}

// Load client CA cert
ca := x509.NewCertPool()
caFilePath := data.Path("x509/ca_cert.pem")
caBytes, err := os.ReadFile(caFilePath)
if ok := ca.AppendCertsFromPEM(caBytes); !ok {
	log.Fatalf("failed to parse %q", caFilePath)
}

// Set up TLS config
tlsConfig := &tls.Config{
	ServerName:   "x.test.example.com",
	Certificates: []tls.Certificate{cert},
	RootCAs:      ca,
}

// Connect to server with TLS
conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)))
 

Token-based

So token is still an available option.

JWT

jwtCreds, err := oauth.NewServiceAccountFromFile(*serviceAccountKeyFile, *oauthScope)
if err != nil {
  log.Fatalf("Failed to create JWT credentials: %v", err)
}
conn, err := grpc.Dial(serverAddr, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), grpc.WithPerRPCCredentials(jwtCreds))

Source