Hey everyone, Alex here. Welcome back to another edition of Coding with Alex at sysseder.com.
If you have ever had to set up automated local HTTPS certificates, configured a staging environment to mirror production TLS, or wrangled with Let's Encrypt’s automated validation protocols, you have likely run into Pebble. For the uninitiated, Pebble is the miniature, RFC 8555-compliant ACME (Automated Certificate Management Environment) server designed specifically for testing. Created by the Let's Encrypt team, it’s a lightweight, intentional "toy" CA that mimics the real Let's Encrypt production API without the rate limits, slow validation times, or public certificate logging.
And let me tell you, the July 2026 Pebble Mega Update that just hit the top of Hacker News is an absolute game-changer for local developer environments, CI/CD pipelines, and cloud-native network engineering.
In this post, we are going to dive deep into what Pebble is, unpack the brilliant new features introduced in this Mega Update, and look at how you can spin up a fully compliant local PKI testing suite with hands-on configuration files and code. Let’s get into it!
Why Pebble Matters to Modern Developers
Historically, local development with HTTPS has been a notoriously messy affair. We’ve all been there: generating self-signed certificates via raw openssl commands, manually adding them to our OS keychain, or hardcoding rejectUnauthorized: false into our Node.js or Python backend APIs just to bypass local TLS errors.
But cutting corners in local development creates a massive gap between your dev machine and production. In production, we use real ACME clients (like Certbot, Lego, or Traefik/Caddy auto-TLS) to fetch real certificates. If your local environment doesn't replicate this ACME handshake, you risk running into critical bugs—like misconfigured ALPN protocols, routing issues, or expired certificate handling—only after you deploy to production.
Pebble solves this by letting you run a complete, simulated ACME directory on localhost. Your application containers can request, validate, and renew TLS certificates exactly like they would in production. Up until now, however, Pebble had some rigid constraints around IP validation, DNS mocking, and certificate revocation behaviors. The July 2026 update tears those walls down.
What's New in the July 2026 Mega Update?
The July 2026 update focuses heavily on realistic network topologies, multi-IP routing, and testing edge cases in ACME validation. Here are the core architectural changes you need to know about:
1. Multi-IP and Multi-Perspective Validation Mocking
In a real-world Let's Encrypt scenario, the CA doesn't just validate your HTTP-01 or DNS-01 challenge from a single data center. To prevent DNS spoofing and BGP hijacking attacks, Let's Encrypt performs multi-perspective validation—checking your domain from multiple geographically distributed vantage points.
The new Pebble release introduces native multi-perspective mocking. You can now configure Pebble to simulate validation queries originating from different virtual subnets, complete with synthetic latency and randomized network packet loss. This is massive for developers building global CDN edge-routing platforms or multi-region Kubernetes ingress controllers.
2. Enhanced DNS-01 Challenge Flexibility
Previously, Pebble’s built-in DNS server was quite rigid, making it difficult to test complex split-horizon DNS setups or wildcards with specific TXT records. The Mega Update brings a fully programmable DNS mock engine. You can now dynamically register and tear down DNS records inside Pebble via a new management API endpoint, eliminating the need to run a separate CoreDNS or BIND container in your Docker Compose setups.
3. Strict Mode & RFC 8555 Compliance Toggles
ACME clients have evolved, but legacy setups still exist. This update adds fine-grained toggles to force strict adherence to the latest draft specs, or to intentionally trigger specific ACME errors (like urn:ietf:params:acme:error:connection or dns failures) to test how gracefully your production application's auto-renewal agent recovers.
Setting Up the New Pebble: A Step-by-Step Guide
Let’s build a local development sandbox using the new Pebble features. We will set up a docker-compose.yml file containing Pebble and a sample client service (using Go's lego ACME client) to demonstrate how quickly we can automate local, valid TLS generation.
The Docker Compose Blueprint
Below is a modern Docker Compose configuration. We are pulling the latest Pebble image and configuring it to run with its internal DNS server enabled, mapping validation requests to our local services.
version: '3.8'
services:
# The ACME Directory Server (Pebble)
pebble:
image: letsencrypt/pebble:latest
command: pebble -config /test/config/pebble-config.json -strict
ports:
- "14000:14000" # ACME Directory API Port
- "15000:15000" # Pebble Management API Port
volumes:
- ./pebble-config.json:/test/config/pebble-config.json
environment:
- PEBBLE_WATH_CONFIG=1
networks:
- acme-net
# Our local web service that needs a TLS certificate
web-app:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
networks:
- acme-net
networks:
acme-net:
driver: bridge
Configuring Pebble (pebble-config.json)
Now, let's write the pebble-config.json configuration file. Note the new multiPerspectiveValidation and dnsToggles introduced in this update, which allow us to simulate real-world WAN latency and distributed checks right inside our local network.
{
"pebble": {
"listenAddress": "0.0.0.0:14000",
"managementListenAddress": "0.0.0.0:15000",
"certificateValidityPeriod": 259200,
"httpPort": 5002,
"tlsPort": 5001,
"dnsPort": 8053,
"validationDelay": 50,
"multiPerspectiveValidation": {
"enabled": true,
"perspectivesCount": 3,
"requiredSuccesses": 2
},
"dnsToggles": {
"allowDynamicUpdates": true,
"fallbackToUpstream": false
},
"strictMode": true
}
}
In this config, certificateValidityPeriod is set to 259,200 seconds (exactly 3 days). This is a classic Pebble best practice: by keeping certificate lifespans extremely short, you force your application’s automated certificate renewal logic to trigger frequently. If your renewal code works smoothly with a 3-day certificate under Pebble, it will sail through 90-day certificates on real Let's Encrypt servers!
Programmatic DNS-01 Mocking with Go
One of the coolest features of the new update is the ability to hit the Pebble management API to dynamically inject DNS records. This is incredibly useful when running integration tests for DNS-01 challenges. Here is a quick Go snippet demonstrating how you can programmatically register a mock DNS record for validation during a test run:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
type MockDNSRecord struct {
Host string `json:"host"`
Type string `json:"type"`
Value string `json:"value"`
}
func main() {
// Pebble Management API URL
pebbleMgmtURL := "https://localhost:15000/add-dns-record"
record := MockDNSRecord{
Host: "_acme-challenge.dev.sysseder.local.",
Type: "TXT",
Value: "mock_acme_token_challenge_value_12345",
}
payload, err := json.Marshal(record)
if err != nil {
fmt.Printf("Error marshalling payload: %v\n", err)
os.Exit(1)
}
// Note: Pebble uses self-signed certs for its management port by default.
// Ensure your client trusts the Pebble test root CA!
resp, err := http.Post(pebbleMgmtURL, "application/json", bytes.NewBuffer(payload))
if err != nil {
fmt.Printf("Error sending mock DNS record: %v\n", err)
os.Exit(1)
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
fmt.Println("Successfully injected mock DNS-01 record into Pebble!")
} else {
fmt.Printf("Pebble returned unexpected status: %s\n", resp.Status)
}
}
Testing Failure Paths: Why Every Dev Needs This
Most developers only write happy-path code. We write the ACME orchestration, run a quick manual test, see the green lock icon in the browser, and call it a day. But what happens when the Let's Encrypt validation server times out? What happens if your DNS provider takes too long to propagate a TXT record, causing a partial validation failure?
Pebble’s new multi-perspective validation lets you explicitly test these failure scenarios. By configuring requiredSuccesses: 3 but simulating a network outage on one of the mock perspectives via Pebble’s management endpoint, you can verify that your certificate controller handles the failure gracefully. It can log the correct error, trigger a retry backoff loop, and alert your team, instead of crashing the process or getting stuck in an infinite renewal loop that eventually hits Let's Encrypt's strict rate limits.
Conclusion & Next Steps
The July 2026 Pebble Mega Update bridges the final remaining gap between local certificate orchestrations and production reality. By including multi-perspective validation simulations, dynamic DNS manipulation, and a robust strict-mode controller, the Let's Encrypt team has elevated Pebble from a simple testing tool to a powerhouse platform for testing local PKI networks.
If you are still using manual self-signed certificates or skipping TLS verification in your local environments, it's time to level up. Pull down the new Pebble Docker image, inject it into your integration pipelines, and ensure your code is secure and compliant from local commit to production deployment.
Let’s Hear From You!
Are you using ACME locally, or are you still relying on manual certs or local tools like mkcert? Have you ever had your automated TLS certificates break in production due to a validation error? Let's talk about it in the comments below!
Until next time, keep your connections encrypted and your code clean. See you in the next post!