Implementing Authentication
1. Using TLS Credentials
| Form | Detail |
|---|---|
| Channel-level | Encrypt all RPCs on connection |
| Per-RPC | grpc.PerRPCCredentials on top of TLS |
| mTLS | Identity carried in client cert |
2. Implementing Token-Based Auth
Example: PerRPCCredentials with token
type tokenAuth struct{ token string }
func (t tokenAuth) GetRequestMetadata(ctx context.Context, _ ...string) (map[string]string, error) {
return map[string]string{"authorization": "Bearer " + t.token}, nil
}
func (tokenAuth) RequireTransportSecurity() bool { return true }
conn, _ := grpc.NewClient(addr,
grpc.WithTransportCredentials(credentials.NewTLS(cfg)),
grpc.WithPerRPCCredentials(tokenAuth{tok}),
)
3. Creating Custom Credentials
| Interface | Method |
|---|---|
PerRPCCredentials | GetRequestMetadata(ctx, uri...) |
| Security | RequireTransportSecurity() bool |
| Refresh | Implement inside GetRequestMetadata |
4. Validating Tokens in Interceptor
Example: JWT verification
func authInterceptor(jwks jwt.Keyfunc) grpc.UnaryServerInterceptor {
return func(ctx context.Context, req any, info *grpc.UnaryServerInfo,
h grpc.UnaryHandler) (any, error) {
md, _ := metadata.FromIncomingContext(ctx)
raw := strings.TrimPrefix(first(md, "authorization"), "Bearer ")
tok, err := jwt.Parse(raw, jwks)
if err != nil || !tok.Valid {
return nil, status.Error(codes.Unauthenticated, "invalid token")
}
ctx = context.WithValue(ctx, claimsKey{}, tok.Claims)
return h(ctx, req)
}
}
5. Implementing JWT Authentication
| Step | Detail |
|---|---|
| Discover JWKS | From /.well-known/jwks.json |
| Cache keys | TTL with background refresh |
| Verify | Signature, iss, aud, exp |
| Inject claims | Into ctx for downstream |
6. Setting Insecure Connection
Example: Insecure for local dev
import "google.golang.org/grpc/credentials/insecure"
conn, _ := grpc.NewClient("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
| Use | Warning |
|---|---|
| Local dev only | Never in production |
| PerRPC creds blocked | If RequireTransportSecurity=true |
7. Using Transport Credentials
| Type | Use |
|---|---|
credentials.NewTLS | Standard TLS |
alts.NewServerCreds / NewClientCreds | GCP ALTS |
insecure.NewCredentials | None |
8. Implementing OAuth2
Example: oauth2 token source
import (
"golang.org/x/oauth2/google"
"google.golang.org/grpc/credentials/oauth"
)
ts, _ := google.DefaultTokenSource(ctx, "https://www.googleapis.com/auth/cloud-platform")
conn, _ := grpc.NewClient(addr,
grpc.WithTransportCredentials(credentials.NewTLS(cfg)),
grpc.WithPerRPCCredentials(oauth.TokenSource{TokenSource: ts}),
)
9. Extracting Peer Information
Example: Peer info on server
p, _ := peer.FromContext(ctx)
fmt.Println("client addr", p.Addr)
if t, ok := p.AuthInfo.(credentials.TLSInfo); ok {
if len(t.State.VerifiedChains) > 0 {
fmt.Println("subject", t.State.VerifiedChains[0][0].Subject)
}
}
10. Implementing API Key Auth
| Step | Detail |
|---|---|
| Header | x-api-key via metadata |
| Validate | Hash compare against store; check active & scopes |
| Rate limit | Per-key bucket |
| Always TLS | Never send keys in plaintext |