This document covers credential types, transport security, authentication mechanisms, and security configuration in gRPC-Go.
The credentials package implements various credentials supported by gRPC, which encapsulate all the state needed by a client to authenticate with a server and make various assertions about the client's identity, role, or authorization.
import "google.golang.org/grpc/credentials"Transport credentials define the common interface for all live gRPC wire protocols and supported transport security protocols (e.g., TLS, SSL).
type TransportCredentials interface {
// ClientHandshake does the authentication handshake for clients.
// Returns the authenticated connection and auth information.
// Implementations must use the provided context for timely cancellation.
// The authority parameter is the :authority header value used for new streams.
ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, AuthInfo, error)
// ServerHandshake does the authentication handshake for servers.
// Returns the authenticated connection and auth information.
ServerHandshake(rawConn net.Conn) (net.Conn, AuthInfo, error)
// Info provides the ProtocolInfo of this TransportCredentials
Info() ProtocolInfo
// Clone makes a copy of this TransportCredentials
Clone() TransportCredentials
// OverrideServerName specifies the value used for verifying hostname
// Deprecated: use grpc.WithAuthority instead
OverrideServerName(string) error
}// NewTLS uses tls.Config to construct TransportCredentials
func NewTLS(c *tls.Config) TransportCredentials
// NewClientTLSFromCert constructs TLS credentials from root CA certificate pool
// serverNameOverride is for testing only - use grpc.WithAuthority in production
func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) TransportCredentials
// NewClientTLSFromFile constructs TLS credentials from root CA certificate file
// serverNameOverride is for testing only - use grpc.WithAuthority in production
func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error)Client TLS Examples:
import (
"crypto/tls"
"crypto/x509"
"os"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// Basic TLS from file
creds, err := credentials.NewClientTLSFromFile("ca.pem", "")
if err != nil {
log.Fatalf("failed to load credentials: %v", err)
}
conn, err := grpc.NewClient("example.com:443", grpc.WithTransportCredentials(creds))
// TLS from cert pool
certPool := x509.NewCertPool()
ca, err := os.ReadFile("ca.pem")
if err != nil {
log.Fatal(err)
}
certPool.AppendCertsFromPEM(ca)
creds := credentials.NewClientTLSFromCert(certPool, "")
conn, err := grpc.NewClient("example.com:443", grpc.WithTransportCredentials(creds))
// Custom TLS config (for mTLS)
cert, err := tls.LoadX509KeyPair("client.pem", "client.key")
if err != nil {
log.Fatal(err)
}
certPool := x509.NewCertPool()
ca, err := os.ReadFile("ca.pem")
if err != nil {
log.Fatal(err)
}
certPool.AppendCertsFromPEM(ca)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: certPool,
}
creds := credentials.NewTLS(tlsConfig)
conn, err := grpc.NewClient("example.com:443", grpc.WithTransportCredentials(creds))// NewServerTLSFromCert constructs TLS credentials from certificate for server
func NewServerTLSFromCert(cert *tls.Certificate) TransportCredentials
// NewServerTLSFromFile constructs TLS credentials from certificate and key files
func NewServerTLSFromFile(certFile, keyFile string) (TransportCredentials, error)Server TLS Examples:
import (
"crypto/tls"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// TLS from files
creds, err := credentials.NewServerTLSFromFile("server.pem", "server.key")
if err != nil {
log.Fatalf("failed to load credentials: %v", err)
}
server := grpc.NewServer(grpc.Creds(creds))
// TLS from certificate
cert, err := tls.LoadX509KeyPair("server.pem", "server.key")
if err != nil {
log.Fatal(err)
}
creds := credentials.NewServerTLSFromCert(&cert)
server := grpc.NewServer(grpc.Creds(creds))
// Custom TLS config (for mTLS with client auth)
cert, err := tls.LoadX509KeyPair("server.pem", "server.key")
if err != nil {
log.Fatal(err)
}
certPool := x509.NewCertPool()
ca, err := os.ReadFile("ca.pem")
if err != nil {
log.Fatal(err)
}
certPool.AppendCertsFromPEM(ca)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: certPool,
}
creds := credentials.NewTLS(tlsConfig)
server := grpc.NewServer(grpc.Creds(creds))For development and testing only:
import "google.golang.org/grpc/credentials/insecure"
// NewCredentials returns credentials which disables transport security
func NewCredentials() credentials.TransportCredentials
// NewBundle returns a bundle with disabled transport security
func NewBundle() credentials.BundleExample:
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
// Client without TLS (testing only)
conn, err := grpc.NewClient("localhost:50051",
grpc.WithTransportCredentials(insecure.NewCredentials()))
// Server without TLS (testing only)
server := grpc.NewServer()For local connections (local TCP or Unix Domain Sockets):
import "google.golang.org/grpc/credentials/local"
// NewCredentials returns local transport credentials
// Reports NoSecurity for local TCP, PrivacyAndIntegrity for UDS
func NewCredentials() credentials.TransportCredentialsExample:
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/local"
)
// Client for Unix Domain Socket
conn, err := grpc.NewClient("unix:///tmp/grpc.sock",
grpc.WithTransportCredentials(local.NewCredentials()))
// Server for Unix Domain Socket
lis, err := net.Listen("unix", "/tmp/grpc.sock")
server := grpc.NewServer(grpc.Creds(local.NewCredentials()))Per-RPC credentials attach security information to every RPC (e.g., OAuth tokens).
type PerRPCCredentials interface {
// GetRequestMetadata gets the current request metadata, refreshing tokens if required.
// Called by the transport layer on each request.
// uri is the URI of the entry point for the request.
// ctx can be used for timeout and cancellation, and contains RequestInfo.
GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
// RequireTransportSecurity indicates whether the credentials requires transport security
RequireTransportSecurity() bool
}import "google.golang.org/grpc/credentials/oauth"
// TokenSource supplies PerRPCCredentials from an oauth2.TokenSource
type TokenSource struct {
oauth2.TokenSource
}
func (ts TokenSource) GetRequestMetadata(ctx context.Context, _ ...string) (map[string]string, error)
func (ts TokenSource) RequireTransportSecurity() bool
// Application Default Credentials
func NewApplicationDefault(ctx context.Context, scope ...string) (credentials.PerRPCCredentials, error)
// Compute Engine credentials
func NewComputeEngine() credentials.PerRPCCredentials
// JWT access credentials
func NewJWTAccessFromFile(keyFile string) (credentials.PerRPCCredentials, error)
func NewJWTAccessFromKey(jsonKey []byte) (credentials.PerRPCCredentials, error)
// Service account credentials
func NewServiceAccountFromFile(keyFile string, scope ...string) (credentials.PerRPCCredentials, error)
func NewServiceAccountFromKey(jsonKey []byte, scope ...string) (credentials.PerRPCCredentials, error)
// Static OAuth2 token (deprecated - use TokenSource instead)
func NewOauthAccess(token *oauth2.Token) credentials.PerRPCCredentialsOAuth2 Examples:
import (
"context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/oauth"
)
// Application Default Credentials
perRPC, err := oauth.NewApplicationDefault(context.Background(),
"https://www.googleapis.com/auth/cloud-platform")
if err != nil {
log.Fatal(err)
}
tlsCreds, _ := credentials.NewClientTLSFromFile("ca.pem", "")
conn, err := grpc.NewClient("example.googleapis.com:443",
grpc.WithTransportCredentials(tlsCreds),
grpc.WithPerRPCCredentials(perRPC))
// JWT from service account file
perRPC, err := oauth.NewJWTAccessFromFile("service-account.json")
if err != nil {
log.Fatal(err)
}
conn, err := grpc.NewClient("example.googleapis.com:443",
grpc.WithTransportCredentials(tlsCreds),
grpc.WithPerRPCCredentials(perRPC))
// OAuth2 token source
tokenSource, err := google.DefaultTokenSource(context.Background(),
"https://www.googleapis.com/auth/cloud-platform")
if err != nil {
log.Fatal(err)
}
perRPC := oauth.TokenSource{TokenSource: tokenSource}
conn, err := grpc.NewClient("example.googleapis.com:443",
grpc.WithTransportCredentials(tlsCreds),
grpc.WithPerRPCCredentials(perRPC))For service mesh environments where JWT tokens are provisioned by infrastructure:
import "google.golang.org/grpc/credentials/jwt"
// NewTokenFileCallCredentials creates PerRPCCredentials that reads JWT tokens from file
// Tokens are cached until expiration
// Requires transport security
// Experimental API
func NewTokenFileCallCredentials(tokenFilePath string) (credentials.PerRPCCredentials, error)Example:
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/jwt"
)
// JWT from file (for service mesh)
perRPC, err := jwt.NewTokenFileCallCredentials("/var/run/secrets/tokens/jwt")
if err != nil {
log.Fatal(err)
}
tlsCreds, _ := credentials.NewClientTLSFromFile("ca.pem", "")
conn, err := grpc.NewClient("example.com:443",
grpc.WithTransportCredentials(tlsCreds),
grpc.WithPerRPCCredentials(perRPC))For token exchange using STS as defined in RFC 8693:
import "google.golang.org/grpc/credentials/sts"
type Options struct {
// TokenExchangeServiceURI is the address of the STS server (required)
TokenExchangeServiceURI string
// Resource is a URI indicating the target service (optional)
Resource string
// Audience is the logical name of the target service (optional)
Audience string
// Scope is a list of space-delimited scopes (optional)
// Default: https://www.googleapis.com/auth/cloud-platform
Scope string
// RequestedTokenType is the type of requested security token (optional)
RequestedTokenType string
// SubjectTokenPath is the path to the file containing the subject token (required)
SubjectTokenPath string
// SubjectTokenType is the type of subject token (required)
SubjectTokenType string
// ActorTokenPath is the path to the file containing the actor token (optional)
ActorTokenPath string
// ActorTokenType is the type of actor token (optional)
ActorTokenType string
}
// NewCredentials returns new PerRPCCredentials using STS token exchange
// Experimental API
func NewCredentials(opts Options) (credentials.PerRPCCredentials, error)Example:
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/sts"
)
// STS credentials
opts := sts.Options{
TokenExchangeServiceURI: "https://sts.example.com/v1/token",
Resource: "https://backend.example.com",
Audience: "example-service",
SubjectTokenPath: "/var/run/secrets/tokens/subject",
SubjectTokenType: "urn:ietf:params:oauth:token-type:jwt",
}
perRPC, err := sts.NewCredentials(opts)
if err != nil {
log.Fatal(err)
}
tlsCreds, _ := credentials.NewClientTLSFromFile("ca.pem", "")
conn, err := grpc.NewClient("example.com:443",
grpc.WithTransportCredentials(tlsCreds),
grpc.WithPerRPCCredentials(perRPC))Implement the PerRPCCredentials interface for custom authentication:
type MyCredentials struct {
Token string
}
func (c *MyCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{
"authorization": "Bearer " + c.Token,
}, nil
}
func (c *MyCredentials) RequireTransportSecurity() bool {
return true
}
// Usage
creds := &MyCredentials{Token: "my-token"}
tlsCreds, _ := credentials.NewClientTLSFromFile("ca.pem", "")
conn, err := grpc.NewClient("example.com:443",
grpc.WithTransportCredentials(tlsCreds),
grpc.WithPerRPCCredentials(creds))A Bundle combines transport and per-RPC credentials with mode switching:
type Bundle interface {
// TransportCredentials returns transport credentials from the bundle
// Must return non-nil. Use insecure.NewCredentials() if not needed.
TransportCredentials() TransportCredentials
// PerRPCCredentials returns per-RPC credentials from the bundle
// May be nil if not needed
PerRPCCredentials() PerRPCCredentials
// NewWithMode creates a copy of Bundle with switched mode
// Returns nil if the requested mode is not supported
NewWithMode(mode string) (Bundle, error)
}Pre-configured bundles for Google Cloud services:
import "google.golang.org/grpc/credentials/google"
type DefaultCredentialsOptions struct {
// PerRPCCreds is per-RPC credentials passed to bundle
PerRPCCreds credentials.PerRPCCredentials
// ALTSPerRPCCreds supersedes PerRPCCreds for ALTS connections
ALTSPerRPCCreds credentials.PerRPCCredentials
}
// NewDefaultCredentials returns a bundle configured for Google services
// Experimental API
func NewDefaultCredentials() credentials.Bundle
// NewDefaultCredentialsWithOptions returns a bundle with custom options
// Experimental API
func NewDefaultCredentialsWithOptions(opts DefaultCredentialsOptions) credentials.Bundle
// NewComputeEngineCredentials returns a bundle for GCE VM default service account
// Must only be used when running on GCE
// Experimental API
func NewComputeEngineCredentials() credentials.BundleExample:
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/google"
)
// Default Google credentials
creds := google.NewDefaultCredentials()
conn, err := grpc.NewClient("example.googleapis.com:443",
grpc.WithCredentialsBundle(creds))
// Compute Engine credentials
creds := google.NewComputeEngineCredentials()
conn, err := grpc.NewClient("example.googleapis.com:443",
grpc.WithCredentialsBundle(creds))ALTS is Google's mutual authentication and transport encryption system for internal services:
import "google.golang.org/grpc/credentials/alts"
type ClientOptions struct {
// TargetServiceAccounts contains expected target service accounts
TargetServiceAccounts []string
// HandshakerServiceAddress is the ALTS handshaker service address
HandshakerServiceAddress string
}
type ServerOptions struct {
// HandshakerServiceAddress is the ALTS handshaker service address
HandshakerServiceAddress string
}
// NewClientCreds constructs client-side ALTS TransportCredentials
func NewClientCreds(opts *ClientOptions) credentials.TransportCredentials
// NewServerCreds constructs server-side ALTS TransportCredentials
func NewServerCreds(opts *ServerOptions) credentials.TransportCredentials
// DefaultClientOptions creates ClientOptions with default values
func DefaultClientOptions() *ClientOptions
// DefaultServerOptions creates ServerOptions with default values
func DefaultServerOptions() *ServerOptions
// ClientAuthorizationCheck verifies client authorization based on service accounts
// Should be called in gRPC server RPC handlers
func ClientAuthorizationCheck(ctx context.Context, expectedServiceAccounts []string) errorALTS Examples:
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/alts"
)
// ALTS client
opts := alts.DefaultClientOptions()
opts.TargetServiceAccounts = []string{"service1@example.iam.gserviceaccount.com"}
creds := alts.NewClientCreds(opts)
conn, err := grpc.NewClient("example.com:443", grpc.WithTransportCredentials(creds))
// ALTS server
opts := alts.DefaultServerOptions()
creds := alts.NewServerCreds(opts)
server := grpc.NewServer(grpc.Creds(creds))
// Server-side authorization check
func (s *server) MyMethod(ctx context.Context, req *pb.Request) (*pb.Response, error) {
if err := alts.ClientAuthorizationCheck(ctx,
[]string{"client@example.iam.gserviceaccount.com"}); err != nil {
return nil, status.Error(codes.PermissionDenied, "unauthorized")
}
// Process request
}Extract ALTS authentication information:
type AuthInfo interface {
ApplicationProtocol() string
RecordProtocol() string
SecurityLevel() altspb.SecurityLevel
PeerServiceAccount() string
LocalServiceAccount() string
PeerRPCVersions() *altspb.RpcProtocolVersions
}
// AuthInfoFromContext extracts ALTS AuthInfo from context (server-side)
func AuthInfoFromContext(ctx context.Context) (AuthInfo, error)
// AuthInfoFromPeer extracts ALTS AuthInfo from peer (client-side)
func AuthInfoFromPeer(p *peer.Peer) (AuthInfo, error)Example:
import (
"google.golang.org/grpc/credentials/alts"
"google.golang.org/grpc/peer"
)
// Server-side: get ALTS info from context
func (s *server) MyMethod(ctx context.Context, req *pb.Request) (*pb.Response, error) {
authInfo, err := alts.AuthInfoFromContext(ctx)
if err != nil {
return nil, err
}
fmt.Printf("Peer service account: %s\n", authInfo.PeerServiceAccount())
// Process request
}
// Client-side: get ALTS info from peer
var p peer.Peer
resp, err := client.MyMethod(ctx, req, grpc.Peer(&p))
if err == nil {
authInfo, err := alts.AuthInfoFromPeer(&p)
if err == nil {
fmt.Printf("Connected to: %s\n", authInfo.PeerServiceAccount())
}
}Transport credentials with security configuration pushed by xDS management server:
import "google.golang.org/grpc/credentials/xds"
type ClientOptions struct {
// FallbackCreds used when xds scheme not used or no security config from management server
// Required - creation will fail without fallback credentials
FallbackCreds credentials.TransportCredentials
}
type ServerOptions struct {
// FallbackCreds used when management server returns no security config
// Required - creation will fail without fallback credentials
FallbackCreds credentials.TransportCredentials
}
// NewClientCredentials returns client-side xDS transport credentials
func NewClientCredentials(opts ClientOptions) (credentials.TransportCredentials, error)
// NewServerCredentials returns server-side xDS transport credentials
func NewServerCredentials(opts ServerOptions) (credentials.TransportCredentials, error)Example:
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/xds"
)
// xDS client credentials
fallback, _ := credentials.NewClientTLSFromFile("ca.pem", "")
xdsCreds, err := xds.NewClientCredentials(xds.ClientOptions{
FallbackCreds: fallback,
})
if err != nil {
log.Fatal(err)
}
conn, err := grpc.NewClient("xds:///my-service", grpc.WithTransportCredentials(xdsCreds))
// xDS server credentials
fallback, _ := credentials.NewServerTLSFromFile("server.pem", "server.key")
xdsCreds, err := xds.NewServerCredentials(xds.ServerOptions{
FallbackCreds: fallback,
})
if err != nil {
log.Fatal(err)
}
server := grpc.NewServer(grpc.Creds(xdsCreds))AuthInfo defines the common interface for authentication information:
type AuthInfo interface {
AuthType() string
}type TLSInfo struct {
State tls.ConnectionState
CommonAuthInfo
SPIFFEID *url.URL // Experimental
}
func (t TLSInfo) AuthType() string
func (t TLSInfo) GetSecurityValue() ChannelzSecurityValue
func (t TLSInfo) ValidateAuthority(authority string) errortype CommonAuthInfo struct {
SecurityLevel SecurityLevel
}
func (c CommonAuthInfo) GetCommonAuthInfo() CommonAuthInfotype SecurityLevel int
const (
// InvalidSecurityLevel indicates invalid security level (zero value)
InvalidSecurityLevel SecurityLevel = iota
// NoSecurity indicates insecure connection
NoSecurity
// IntegrityOnly indicates integrity protection only
IntegrityOnly
// PrivacyAndIntegrity indicates both privacy and integrity protection
PrivacyAndIntegrity
)
func (s SecurityLevel) String() string
func CheckSecurityLevel(ai AuthInfo, level SecurityLevel) errorRequest data available to GetRequestMetadata calls:
type RequestInfo struct {
// The method passed to Invoke or NewStream (e.g., "/some.Service/Method")
Method string
// AuthInfo from security handshake
AuthInfo AuthInfo
}
// RequestInfoFromContext extracts RequestInfo from context
// Experimental API
func RequestInfoFromContext(ctx context.Context) (ri RequestInfo, ok bool)
// NewContextWithRequestInfo creates context with RequestInfo attached
// For testing PerRPCCredentials implementations
// Experimental API
func NewContextWithRequestInfo(ctx context.Context, ri RequestInfo) context.Contexttype ProtocolInfo struct {
// Deprecated: unused by gRPC
ProtocolVersion string
// SecurityProtocol is the security protocol in use
SecurityProtocol string
// Deprecated: use Peer.AuthInfo instead
SecurityVersion string
// Deprecated: use grpc.WithAuthority instead
ServerName string
}type AuthorityValidator interface {
// ValidateAuthority checks the authority value used to override :authority header
// Returns non-nil error if validation fails
ValidateAuthority(authority string) error
}TLSInfo implements AuthorityValidator and validates against peer certificates.
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// Transport credentials only
tlsCreds, _ := credentials.NewClientTLSFromFile("ca.pem", "")
conn, err := grpc.NewClient("example.com:443",
grpc.WithTransportCredentials(tlsCreds))
// Transport + per-RPC credentials
tlsCreds, _ := credentials.NewClientTLSFromFile("ca.pem", "")
perRPC, _ := oauth.NewApplicationDefault(ctx)
conn, err := grpc.NewClient("example.com:443",
grpc.WithTransportCredentials(tlsCreds),
grpc.WithPerRPCCredentials(perRPC))
// Credentials bundle
bundle := google.NewDefaultCredentials()
conn, err := grpc.NewClient("example.googleapis.com:443",
grpc.WithCredentialsBundle(bundle))import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// Transport credentials
creds, _ := credentials.NewServerTLSFromFile("server.pem", "server.key")
server := grpc.NewServer(grpc.Creds(creds))
// Extract auth info in handlers
func (s *server) MyMethod(ctx context.Context, req *pb.Request) (*pb.Response, error) {
p, ok := peer.FromContext(ctx)
if ok {
tlsInfo := p.AuthInfo.(credentials.TLSInfo)
fmt.Printf("Client cert CN: %s\n", tlsInfo.State.PeerCertificates[0].Subject.CommonName)
}
// Process request
}insecure.NewCredentials() only for local developmentserverNameOverride in productionGetRequestMetadataGetRequestMetadataRequireTransportSecurity() to true unless you have specific reasonsimport (
"testing"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/test/bufconn"
)
// Use bufconn for in-memory testing
func TestMyService(t *testing.T) {
lis := bufconn.Listen(1024 * 1024)
server := grpc.NewServer()
pb.RegisterMyServiceServer(server, &myServer{})
go server.Serve(lis)
defer server.Stop()
conn, _ := grpc.NewClient("bufnet",
grpc.WithContextDialer(func(ctx context.Context, s string) (net.Conn, error) {
return lis.DialContext(ctx)
}),
grpc.WithTransportCredentials(insecure.NewCredentials()))
defer conn.Close()
client := pb.NewMyServiceClient(conn)
// Test RPCs
}