acumen/register_account
Register a new ACME account.
Before requesting certificates, you must register an account with the ACME server.
Example
import acumen
import acumen/account.{type Account}
import acumen/register_account
import gose/key
import kryptos/ec
// Generate an account key (store this securely!)
let key = key.generate_ec(ec.P256)
let unregistered = acumen.UnregisteredKey(key)
// Build the registration request
let reg = register_account.request()
|> register_account.contacts(["mailto:admin@example.com"])
|> register_account.agree_to_terms
// Execute the request
let assert Ok(#(resp, ctx)) = acumen.execute(
ctx,
build: register_account.build(reg, _, unregistered),
send: httpc.send,
)
// Parse the response to get the account and registered key
let assert Ok(#(account, registered_key)) =
register_account.response(resp, unregistered)
Types
Request builder for account registration.
Use request to create a builder, configure it with contacts,
agree_to_terms, and/or only_existing, then call build.
pub opaque type RequestBuilder
Values
pub fn agree_to_terms(builder: RequestBuilder) -> RequestBuilder
Indicates agreement to the ACME server’s terms of service.
Most ACME servers (including Let’s Encrypt) require you to agree to their
terms of service. The ToS URL is available in directory.meta.terms_of_service.
pub fn build(
builder: RequestBuilder,
context: acumen.Context,
key: acumen.UnregisteredKey,
) -> Result(request.Request(String), acumen.AcmeError)
Builds the HTTP request for account registration.
The full JWK is embedded in the protected header since the key isn’t registered yet.
pub fn contacts(
builder: RequestBuilder,
contacts: List(String),
) -> RequestBuilder
Adds contact URLs to the registration request.
Contact URLs are typically mailto: addresses where the CA can reach you
about certificate expiration, policy changes, or security issues.
pub fn external_account_binding(
builder: RequestBuilder,
key_id key_id: String,
mac_key mac_key: BitArray,
) -> RequestBuilder
Adds external account binding credentials to the registration request.
Some CAs (like Google, ZeroSSL) require you to bind your ACME account to an existing account with them. They provide a key ID and a MAC key (usually base64url-encoded).
Example
let assert Ok(mac_key) = bit_array.base64_url_decode(mac_key_b64)
let reg = register_account.request()
|> register_account.external_account_binding(key_id: "key-id-from-ca", mac_key: mac_key)
|> register_account.agree_to_terms
pub fn only_existing(builder: RequestBuilder) -> RequestBuilder
Configures the request to only return an existing account.
When set, the server will return the existing account for this key if one
exists, or return an AccountDoesNotExist error if not. No new account
will be created.
This is useful for recovering an account URL when you have the private key but lost the account metadata.
pub fn request() -> RequestBuilder
Creates a new account registration request builder.
Example
let reg = register_account.request()
|> register_account.contacts(["mailto:admin@example.com"])
|> register_account.agree_to_terms
pub fn response(
resp: response.Response(String),
key key: acumen.UnregisteredKey,
) -> Result(
#(account.Account, acumen.RegisteredKey),
acumen.AcmeError,
)
Parses the account registration response.
Returns the account and a RegisteredKey (the key upgraded with the
account URL). Use the RegisteredKey for all subsequent operations.