Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
02 Aug 2025 · 5 min read ·Article 55 / 110
Go

55. gRPC + Let's Encrypt with Autotls

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

55. gRPC + Let’s Encrypt with Autotls: TLS Automation for Modern Microservices

As an engineer who frequently builds distributed systems, I’m keenly aware that securing communication between services is a must—not optional. Yet configuring TLS often becomes a challenge in itself. This is especially true when you use a modern protocol like gRPC, prized for its performance in microservice systems, where setting up TLS can feel cumbersome and error-prone.

On the other hand, services like Let’s Encrypt offer free TLS with digital certificates that can be renewed automatically. The challenge: how do you automate that entire process inside a gRPC application? This is where a library like Autotls (for example, Go’s autocert ) takes the stage. In this article, I’ll walk through a practical way to integrate gRPC with Let’s Encrypt using autotls tooling, complete with diagrams, code samples, workflow simulations, and comparison tables.


How gRPC + Let’s Encrypt + Autotls Work Together

Let’s start with a high-level picture of the flow. Here it is using Mermaid:

MERMAID
flowchart TD
  A[Client gRPC] -- TLS handshake --> B[gRPC Server]
  B -- TLS missing? --> C[Autotls Handler]
  C -- Request Certificate --> D[Let's Encrypt CA]
  D -- Provide Certificate --> C
  C -- Store/Cache Cert --> B
  B -- Secure Channel --> A

A quick explanation:

  • The client initiates the connection (which must be over TLS).
  • If the server doesn’t yet have a valid certificate, it triggers Autotls to request one from Let’s Encrypt (via the ACME protocol).
  • The certificate is stored (in a persistent cache, for example on disk).
  • From then on, the channel is encrypted automatically.

Why Automate TLS?

Many engineers put off implementing TLS for three classic reasons:

  1. Configuration is tedious: Create a CSR, obtain the certificate, set up renewal, and update it before it expires.
  2. Risk of manual error: Copy-pasting private keys/certificates between nodes is prone to typos.
  3. Automatic renewal is complex: The manual renewal process becomes a source of downtime.

With autotls, the process above becomes seamless and requires minimal human intervention.


A Practical Implementation: a gRPC Server with Autotls in Go

For this demo, I’m using Golang because of its rich autotls ecosystem and native support for gRPC.

Prerequisites

A Basic Example: gRPC with Autotls

Suppose you have a simple server. Here’s how to plug autotls and Let’s Encrypt directly into the gRPC server:

go
 1package main
 2
 3import (
 4    "context"
 5    "log"
 6    "net"
 7    "google.golang.org/grpc"
 8    "golang.org/x/crypto/acme/autocert"
 9    "crypto/tls"
10)
11
12func main() {
13    // Autotls configuration
14    mgr := autocert.Manager{
15        Prompt:     autocert.AcceptTOS,
16        HostPolicy: autocert.HostWhitelist("grpc.example.com"), // Replace with your domain
17        Cache:      autocert.DirCache("/var/certs"), // Store the cert on disk
18    }
19
20    // Wrap it into a TLS Config
21    tlsConfig := &tls.Config{
22        GetCertificate: mgr.GetCertificate,
23        NextProtos:     []string{"h2"}, // In production, gRPC uses HTTP/2
24    }
25
26    lis, err := net.Listen("tcp", ":443")
27    if err != nil {
28        log.Fatalf("failed to listen: %v", err)
29    }
30
31    s := grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsConfig)))
32    // Register your gRPC services here...
33    // pb.RegisterMyServiceServer(s, &serverImpl{})
34
35    log.Println("gRPC-server listening on port 443 with Let's Encrypt TLS")
36    if err := s.Serve(lis); err != nil {
37        log.Fatalf("server error: %v", err)
38    }
39}

Key points:

  • The TLS handshake happens before any request is accepted, without any hardcoded certificate.
  • The certificate is issued and renewed directly by Let’s Encrypt via a background process.
  • The directory cache can be swapped for cloud storage/NFS to achieve a zero-downtime cluster.

Simulating Renewal and Failure Handling

Let’s Encrypt requires renewal every 90 days. autocert performs a pre-emptive renewal roughly 30 days before expiry, automatically. If your server restarts, the cache minimizes the risk of “repeat challenges” and rate limiting from Let’s Encrypt.

Simulating Failure Scenarios:

ScenarioAutotls ResponseImpact
No internet accessFails to renew/issue certgRPC listen fails; fallback can be a self-signed cert
Corrupt certificateRe-requests from the CACan get blocked by rate limits if it happens often
Disk cache full/read-onlyCert isn’t storedRenewal fails when the server restarts

Solution: Ensure cache persistence and monitor renewals using alerting/metrics.


Cluster: Sharing Certificates Across Nodes

In a horizontal deployment (multiple server instances), sharing the cache file via NFS or a shared volume is necessary. Avoid triggering ACME challenges simultaneously from multiple nodes (LE rate limiting). The library also offers built-in automation with Redis, GCS, or S3.

Alternative: Use a load balancer (an L4 proxy that terminates TLS) for centralized TLS provisioning—though you lose mTLS visibility on the backend between microservices.


When Is Autotls a Good Fit?

CriteriaAutotls (autocert)Manual TLSLoad Balancer TLS
Dev/TestHIGHLY suitableOverkillNot needed
Prod (1-2 nodes)Good if single LBMore flexibleStandard (best)
Large clusterNeeds cache cautionTedious mass renewalHighly recommended

Tip: For internal service-to-service communication, consider mTLS, for which autocert is less suitable (since it only handles server-side certificates)—use cert-manager + Istio or spiffe/spire for enterprise zero-trust scenarios.


Conclusion & Best Practices

By adopting autotls with Let’s Encrypt, engineers can eliminate operational overhead and strengthen the security posture of their microservice systems. Still, keep these in mind:

  • DNS must point to your deployment so that the HTTP/ALPN challenge succeeds.
  • Use a persistent cache and monitor certificate expiry.
  • Test end-to-end, including simulating expired-certificate and ACME challenge-failure scenarios.

With the approach above, building a secure gRPC channel—once a hassle—now takes just a few lines of code. Your application’s security gets an automatic upgrade!


References & Additional Resources


Found this helpful? Don’t hesitate to leave a comment or share your own experience adopting certificate automation in microservices! 🚀

Related Articles

💬 Comments