Skip to content

feat: automatic ACME certificate rotation and integration tests - #13

Open
phaus wants to merge 15 commits into
mainfrom
feat/letsencrypt
Open

feat: automatic ACME certificate rotation and integration tests#13
phaus wants to merge 15 commits into
mainfrom
feat/letsencrypt

Conversation

@phaus

@phaus phaus commented Sep 5, 2026

Copy link
Copy Markdown
Member

Summary

Closes #12 (continuation).

This PR finishes the remaining data-layer and rotation work for Let's Encrypt ACME certificate management:

  • Automatic router cert rotation: adds an acme_domain column to http_routes. When an ACME certificate is provisioned or renewed, controller/data/route.go now syncs the new certificate to all bound routes and fires route events so the router hot-swaps without requiring flynn route update --acme <domain> to be re-run.
  • ACME domain tracking: flynn route update <id> --acme <domain> persists acme_domain on the route while still snapshotting the current cert; the field is cleared when the route is switched back to manual -c/-k.
  • Data-layer integration tests: controller/data/acme_test.go covers ACMEStore account/certificate CRUD, upsert, domain normalization, deletion, and RouteRepo.SyncACMECert route binding + renewal rotation (requires PostgreSQL to run).
  • Schema: migration 51 adds acme_domain; the route JSON schema is updated.

Test Results

  • go build ./... clean
  • go test -vet=off ./pkg/autocert/... → 7 passed
  • go test -vet=off ./controller/ -run TestACME → 7 passed
  • New controller/data/acme_test.go integration tests compile (require Postgres).

Commits

  • router: add acme_domain field to Route and HTTPRoute
  • controller/data: add acme_domain column and ACME cert route sync
  • controller: wire ACME store to sync route certs on renewal
  • cli: persist acme_domain on route update --acme
  • controller/data: add ACMEStore integration tests

root added 15 commits September 5, 2026 00:57
Adds a new pkg/autocert package that orchestrates Let's Encrypt
certificate provisioning and renewal via go-acme/lego v4.35.2.

- Config (HTTP-01/DNS-01 challenge selection, email, CA URL)
- Account creation/persistence interface
- HTTP-01 challenge handler (/.well-known/acme-challenge/)
- DNS-01 wiring for lego's built-in autodns provider
- Obtain/Renew certificate flow with PostgreSQL storage interface
- Background renewal loop

Also vendors lego and its transitive dependencies. Because lego v4
requires newer x/net, x/crypto, grpc, protobuf etc., the whole graph
is upgraded; go.mod now declares go 1.25.0 (required by the dep
graph). The legacy Azure SDK used by blobstore/backend/azure.go is
pinned back to the previously-vendored version via a replace directive
so that backend continues to compile unchanged.
The CI runner installs Go 1.22.12. With go 1.25.0 in go.mod it downloaded the Go 1.25 toolchain, which then failed to find the covdata tool when running -race -cover tests for pkg/rpcplus/comborpc and fdrpc. Revert to go 1.23 so the downloaded toolchain matches the project baseline and coverage works.
The project now depends on packages (e.g. cloud.google.com/go/auth) that require Go >= 1.25.0. The CI runner was installing Go 1.22.12, causing toolchain downloads and missing the covdata coverage tool. Install Go 1.25.0 directly in both build and test jobs.
Adds a self-contained integration test (TestManagerObtainWithPebble) that starts a local Pebble ACME test server, runs the autocert HTTP-01 challenge flow, and verifies the issued certificate chains back to the Pebble root CA.

Test is gated by the ACME_PEBBLE_TEST environment variable because it downloads and runs the letsencrypt/pebble module.

Also adds an optional HTTPClient field to autocert.Config so tests can inject a TLS client that trusts the test CA.

Includes the pebbletest helper as a separate Go module to keep Pebble out of the main module's vendor tree.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Let's Encrypt ACME certificate integration (HTTP-01 + DNS-01 challenges)

1 participant