Support custom ACME providers#620
Open
NiccoMlt wants to merge 10 commits into
Open
Conversation
Replace deprecated update() with fetch() on challenge and order polling, as recommended by the acme4j migration guide before upgrading to 4.x.
No code changes needed: deprecated APIs were already dropped in the 3.5.0 step, and the new Java 17 baseline is below our Java 21 build.
Login.getKeyPair() was removed as a security precaution: private key handling now stays inside acme4j, and only Login.getPublicKey() is exposed. Tests now stub getPublicKey(), which the challenge digest computation relies on.
Align slf4j with the version acme4j 5.1.0 builds against.
acme4j's Authorization.findChallenge(Class) makes the manual casts unnecessary.
checkResponseForChallenge and checkResponseForOrder returned the status read before fetch(), so callers always saw the stale value and the certificate state machine converged one cycle late. Return the post-fetch status instead, and cover the polling logic with direct ACMEClient tests.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Any RFC 8555 CA via acme.<n>.* config (EAB kid/hmac supported, validated at parse time), per-certificate provider selection, per-provider account keys. Let's Encrypt stays default with the legacy account key. Closes diennea#536
CA rejections (stale orders, malformed responses) bump the cert attempts and fall back to a fresh order; network errors, rate limits and CA outages retry in the same state. Order polls fetch once per cycle. Policy lives in AcmeFailureClassifier with fast pure unit tests replacing five heavy harness runs.
Unknown local failures now bump attemptsCount and surface in the UI instead of retrying invisibly forever. Also review nits: hoisted server local, documented reserved _acmeuserkey prefix.
NiccoMlt
force-pushed
the
536-acme-certificate-support-custom-acme-providers
branch
from
July 23, 2026 13:27
8d2198e to
a696ea2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implementation
Certificates can now be issued by any RFC 8555 compliant CA, not just Let's Encrypt.
Closes #536. Stacked on #619 so merge that first.
Caution
CI mocks the ACME boundary, so external account binding and custom directory URLs are not exercised end-to-end; QA will verify against a real provider. A local run against Pebble) is a meaningful smoke check.
Configuration
Providers are configured with a new configuration family and referenced per certificate:
If no provider is specified, Let's Encrypt is used, as before. Therefore, the
letsencryptname is reserved for the built-in provider.kidandhmacare optional, but both-or-neither; those allow logging in with EAB (External Account Binding) credentials, if required by the provider.Built-in
letsencryptprovider still stores the account key under the legacy_acmeuserkeyentry, while custom providers use_acmeuserkey_<name>, e.g._acmeuserkey_digicert.Important
carapace.acme.testmodeJVM system property keeps affecting only the built-in Let's Encrypt provider (staging vs production); custom providers always use their configured URL.REST APIs
POST /api/certificatesacceptsprovidertoo.POST /api/certificates/{domain}/uploadaccepts provider query param too (ACME type only);GET /api/certificatesexposes each certificate'sprovideracmeProviders, that feeds the UI select.Web UI