Skip to content

Repository files navigation

acme — go-ruby-acme

go-ruby-acme/acme

Go Reference License: BSD-3-Clause CI Coverage

A pure-Go (no cgo) reimplementation of the surface of Ruby's acme-client gem — the ACME / Let's Encrypt (RFC 8555) protocol client. It mirrors the ergonomics of Acme::Client — accounts, orders, authorizations, challenges, finalization and certificate download — while delegating the ACME/JWS wire protocol itself to the standard, pure-Go golang.org/x/crypto/acme client, so no part of RFC 8555 is reimplemented here.

It is the ACME backend for go-embedded-ruby, but is a standalone, reusable module — a sibling of go-ruby-jwt and go-ruby-oauth2.

Surface

The Ruby object graph is reproduced with idiomatic Go types:

  • ClientNewClient(privateKey, directory)Acme::Client.new(private_key:, directory:)
  • AccountNewAccount(ctx, contact, tosAgreed)#new_account, Account(ctx) for lookup
  • OrderNewOrder(ctx, identifiers)#new_order; Order#Authorizations, #Finalize(csr), #Certificate (PEM chain), #Status, #Reload
  • Authorization#Challenges, #HTTP01 / #DNS01 / #TLSALPN01, #Domain, #Status
  • Challenge#KeyAuthorization (token.thumbprint), #RequestValidation, #Status, #Error, #Reload
  • Errors — an error tree rooted at *Error with *Unauthorized, *RateLimited, *BadNonce and *Malformed, mapping ACME problem documents onto the Acme::Client::Error subclasses

Usage

import "github.com/go-ruby-acme/acme"

client, _  := acme.NewClient(accountKey, "https://acme-v02.api.letsencrypt.org/directory")
account, _ := client.NewAccount(ctx, []string{"mailto:me@example.com"}, true)
order, _   := client.NewOrder(ctx, []string{"example.com"})

authzs, _ := order.Authorizations(ctx)
chal      := authzs[0].HTTP01()
ka, _     := chal.KeyAuthorization()   // serve at /.well-known/acme-challenge/<token>
_ = chal.RequestValidation(ctx)

csr, _ := acme.NewCSR(certKey, "example.com")
_ = order.Finalize(ctx, csr)
pemChain, _ := order.Certificate(ctx)

Transport seam

The ACME transport is injectable. WithHTTPClient swaps the *http.Client (the whole flow runs against an in-process mock ACME server with no live network) and WithRetryBackoff tunes the retry policy. The test suite drives the full account → order → authz → http-01 → finalize → certificate flow, plus the badNonce retry, rate-limit, unauthorized and invalid-challenge error paths, against a mock CA — deterministic, and with no real Let's Encrypt.

Tests & coverage

go test ./... runs the full flow against the mock ACME server. The CI gate enforces 100% statement coverage under -race and builds/tests on all six 64-bit Go targets — amd64, arm64, riscv64, loong64, ppc64le, s390x (big-endian).

License

BSD-3-Clause. Copyright (c) the go-ruby-acme/acme authors.

WebAssembly

Being pure Go (CGO=0), this library also compiles to WebAssembly — both GOOS=js GOARCH=wasm (browser / Node.js) and GOOS=wasip1 GOARCH=wasm (WASI). CI builds both targets on every push, alongside the six 64-bit native/qemu arches.

GOOS=js     GOARCH=wasm go build ./...   # browser / Node
GOOS=wasip1 GOARCH=wasm go build ./...   # WASI (wasmtime, wasmer, wasmedge, …)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages