Hey!
I started running stalwart with automatic certificate and DNS management a while ago and all works well, I run it on mail.domain
Now, I want to run another software on the same server, and reside on another.domain I’d like this another software to be run behind Caddy, for the ease of HTTPS management.
I hear your advice on running with Caddy as a transparent TCP proxy, but my problem here is that Stalwart already have created all the certificates and CAA DNS records for the domain and seems to be managing it alright, whilst Caddy is choking on it:
"While processing CAA for another.mydomain.com: CAA record for mydomain.com prevents issuance
So I tried to be smart and maybe make use of the same letsencrypt account as stalwart generated, for which I’d need a private key with which the certificate was requested, according to caddy json config, but it seems to be impossible to pull out from stalwart by any means: Cli’s snapshot Certificate --include-secrets outputs *** for the private keys still, despite --include-secrets.
I am hitting the wall here a little bit, any advice would be appreciated!
Thanks!
I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
The ACME account private key cannot be exported through the CLI, by design. AcmeProvider.accountKey is marked server-set in the schema, and stalwart-cli snapshot skips every server-set field before it even reaches the secret-redaction logic, so --include-secrets has no effect on it. That field is intentionally never returned to clients, so there’s no way to hand the same Let’s Encrypt account key to Caddy.
The real fix for your CAA error is different: your mydomain.com zone almost certainly has a CAA record that Stalwart placed with an accounturi=... restriction, tying issuance for that zone to Stalwart’s own ACME account. CAA lookups walk up from another.mydomain.com to the parent zone when the subdomain has no CAA record of its own, so Caddy’s request for another.mydomain.com is being blocked by the CAA record scoped to mydomain.com. You have two practical options:
Publish an explicit CAA record on another.mydomain.com itself (e.g. CAA 0 issue "letsencrypt.org" with no accounturi restriction). A subdomain’s own CAA records take precedence over the parent’s, so this lets Caddy’s separate ACME account issue for that name. Just be aware that if another.mydomain.com is ever brought under Stalwart’s own automatic DNS/certificate management, Stalwart will rewrite the CAA set for that name to match its own AcmeProvider account.
Run another.domain fully behind Caddy without Stalwart managing DNS/certs for it at all (i.e. don’t add it as a Stalwart Domain with automatic certificate management), and only add the CAA record above manually.
That refusal is Stalwart’s own CAA record. Automatic DNS management publishes issue "<ca>; accounturi=<the account Stalwart uses>" at the apex of mydomain.com, and an accounturi on an issue record pins issuance to that one ACME account for the domain and everything under it. Caddy has its own account, so the CA declines.
Put a CAA RRset directly on another.mydomain.com, for example 0 issue "letsencrypt.org". CAA lookup stops at the first name that has records and never climbs to the parent, and Stalwart only ever writes at the apex and at _validation-persist, so the two never meet. If you would rather keep a single RRset at the apex, adding a second issue record with no accounturi also works: the DNS reconciler recognises only CAA records carrying its own accounturi and leaves anything else in place. The tradeoff is that it re-opens issuance to any account across the whole domain.
You do not have to hand certificates to Caddy. Stalwart keeps mail.mydomain.com, Caddy keeps another.mydomain.com, and the CAA record is the only thing they contend over. The Caddy page assumes Caddy owns issuance because that is the common layout, not because it is required.
On --include-secrets: the masking is applied server-side on every read and cannot be switched off, so the flag will never give you the ACME account key. The CLI docs claim there is a server setting for that. There is not, and I will fix the page.