Authentication & Security in gRPC

gRPC — Authentication & Security in gRPC
gRPC
Chapter 7 · Authentication & Security in gRPC

🔐 Authentication & Security in gRPC

Chapters 5–6 built the metadata and interceptor mechanics. This chapter puts real security behind them — reusing the https1 course's TLS mechanics and bc1's token-based auth wholesale, plus one technique especially suited to gRPC's service-to-service origins: mutual TLS.

TLS by Default

Where a REST API often starts as plain HTTP and has HTTPS bolted on later, gRPC channels are typically created with TLS from the very start — the same handshake and certificate mechanics https1-4/https1-6 already covered in depth, just carrying gRPC's HTTP/2 traffic instead of a browser's.

// Production: a secure channel using TLS const client = new ProductServiceClient( 'products.internal:443', grpc.credentials.createSsl() ); // Local development ONLY — never in production const devClient = new ProductServiceClient( 'localhost:50051', grpc.credentials.createInsecure() );

Token-Based Auth via Metadata

Chapters 5–6 already built this pattern — a bearer token passed as metadata, validated once by a server interceptor. This chapter names it formally: it's gRPC's version of bc1-7's token-based authentication, and it's a genuinely separate layer from the channel's TLS. Channel credentials (TLS) secure the transport itself; call credentials (the token in metadata) establish who's making a specific call — the same "one secret, defended end to end" layering bc1's quartet framing established for the site's Auth course generally.

Mutual TLS (mTLS) for Service-to-Service Calls

Standard TLS only proves the server's identity to the client, via the server's certificate. Mutual TLS goes further: the client also presents its own certificate, and the server verifies it — both sides authenticate each other. This fits gRPC's original service-to-service use case (Chapter 1) especially well: there's no human typing a password on either end, so a certificate-based identity is the natural fit for proving "this call is genuinely coming from the order service, not an impostor."

// Server requiring client certificates (mTLS) const serverCredentials = grpc.ServerCredentials.createSsl( rootCert, [{ private_key: serverKey, cert_chain: serverCert }], true // checkClientCertificate — enforce mTLS );

Standard TLS vs. Mutual TLS

Standard TLS

Only the server proves its identity — right for calls from a human or external client that doesn't have its own certificate.

Mutual TLS

Both sides present certificates — right for internal service-to-service calls where each service has a well-defined identity worth verifying.

Security LayerMechanismProtects Against
Channel credentials (TLS)Server certificate, encrypted transportEavesdropping, tampering in transit
Call credentials (bearer token)Metadata, validated per-callUnauthenticated/unauthorized calls
Mutual TLSClient and server certificatesAn impostor service pretending to be a trusted caller

Bearer Tokens Fit When

The caller is a human user or an external client authenticating via credentials rather than a certificate — the same territory bc1 covers generally.

mTLS Fits When

Both endpoints are internal services within a trusted network, where each service having its own verifiable certificate identity is practical (Chapter 8's microservices territory).

💻 Coding Challenges

Challenge 1: Channel vs. Call Credentials

Explain the difference between channel credentials and call credentials in gRPC, using this chapter's TLS-and-bearer-token example.

Goal: Practice distinguishing transport-level security from per-call identity as two separate, layered concerns.

→ Solution

Challenge 2: Bearer Token or mTLS?

For each, recommend bearer-token auth or mTLS: (a) a mobile app calling a public-facing gRPC gateway, (b) an internal payments service calling an internal ledger service, both within the same company's private network.

Goal: Practice applying the human/external-vs-internal-service distinction to concrete scenarios.

→ Solution

Challenge 3: Spot the Security Mistake

A developer ships a gRPC service to production using grpc.credentials.createInsecure() "because it worked fine in local testing." Explain what's wrong with this.

Goal: Practice recognizing a real, concrete security regression rather than a purely theoretical one.

→ Solution

⚠️ Gotcha: createInsecure() Belongs Only in Local Development

An insecure channel sends every call — including any bearer token attached via metadata — in plaintext, exactly the same risk the site's HTTPS/TLS and Database Security courses have flagged repeatedly for other protocols: an unencrypted channel means anyone positioned to observe the traffic reads everything, credentials included. It's easy to reach for createInsecure() during local development (no certificates to manage) and simply forget to switch to createSsl() before deploying — treat this exactly like the site's recurring "never expose unencrypted" theme (database connections, TLS certificate verification): a deliberate, checked step before anything reaches production, not an assumption.

🎯 What's Next

The next chapter is gRPC in Microservices & Load Balancing — service discovery, client-side vs. proxy load balancing, and when gRPC is the right internal-service choice vs. REST/GraphQL for public-facing APIs.