Support using external certificates (file provider / BYOC, no ACME) with the cert scraper
- Dominant language
- TypeScript
- Stars
- 22.8k
- Forks
- 783
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 47
Description
### Describe the Bug
When Pangolin runs with **externally managed certificates** — Traefik serves certificates
from a file provider (e.g. wildcard certs issued by `acme.sh`) and no Traefik ACME
`certResolver` is configured — the dashboard shows the certificate status for
resources/domains as **`pending` permanently**.
HTTPS works correctly the whole time (Traefik picks the matching certificate from the
file-provider store via SNI), so this is purely a status/UI issue: Pangolin never learns
that a valid certificate already exists for the domain, because the only code path that
marks a certificate `valid` is the ACME cert sync, which doesn't apply to a
file-provider / BYOC deployment.
### Environment
- OS Type & Version: Debian 13 (Trixie)
- Pangolin Version: 1.18.4
- Edition (Community or Enterprise): Enterprise (`fosrl/pangolin:ee-1.18.4`)
- Gerbil Version: 1.4.1
- Traefik Version: v3.7.5
- Newt Version: not used (local site + Traefik file provider, no tunneled sites)
- Client Version: not used
### To Reproduce
1. Configure Traefik with a file provider that loads external certificates and **no** ACME
`certResolver`.
2. In `config.yml` set `traefik.cert_resolver: ""`.
3. (Optionally) disable ACME cert sync: `privateConfig.yml` → `flags.enable_acme_cert_sync: false`.
4. Create an HTTP resource under a configured base domain.
5. Open the dashboard and look at the certificate status of the resource/domain.
**Actual result:** the certificate status stays `Pending` indefinitely, even though the
resource is reachable over HTTPS with a valid certificate the whole time (Traefik selects
the matching cert from the file-provider store via SNI).
### Expected Behavior
The dashboard should reflect that a valid certificate is being served — or expose a
"bring your own certificate" / "externally managed" state — instead of showing `pending`
forever.
Why it stays `pending` (from reading the source):
- The `certificates` table defaults `status` to `pending`
(`server/setup/scriptsSqlite/1.11.0.ts`; status enum in
`server/routers/certificates/types.ts`: `pending, requested, valid, expired, failed`).
- The **only** code that sets `status: "valid"` is the ACME cert-sync logic
(`server/private/lib/acmeCertSync.ts`), which reads Traefik's `acme.json` or an HTTP
endpoint exposing issued certs.
- In a file-provider / BYOC setup there is no `acme.json` and no ACME flow, so nothing ever
transitions the record from `pending` to `valid`.
Possible fixes (any one):
1. Allow a domain/resource to be flagged "externally managed", suppressing the `pending`
status and ACME logic for it.
2. Optionally verify the certificate actually served (or read the file-provider store) and
mark it `valid` independent of ACME.
3. Let `acmeCertSync` ingest PEM certs from a directory, not only Traefik `acme.json`.
Note: this is not a functional bug — routing and TLS work correctly. It's confusing
because the UI permanently implies the certificate is incomplete.
Contributor guide
Assessment
This issue has not been assessed yet.