Fix stale documentation found by a doc-accuracy audit

firmware/README.md's HTTP vs HTTPS section still described the
public-CA-bundle trust approach that was tried and abandoned in favor
of pinning one specific certificate -- rewritten to match what's
actually there. docs/architecture.md was missing the back-photo button
entirely (sequence diagram and boot-flow bullets only covered next) and
still said the system talks "over plain HTTP" despite HTTPS support.
docker-compose.yml.example's MANAGEMENT_TOKEN comment understated its
scope (said "the web UI", omitting that every /frame/* endpoint is
gated too).
This commit is contained in:
2026-07-19 15:20:12 -04:00
parent aef8a10029
commit d5de882b1e
3 changed files with 48 additions and 25 deletions
+24 -11
View File
@@ -96,17 +96,30 @@ The Tools Server field accepts either:
manage-menu overlay data, the QR codes' own links) uses whichever
scheme you enter.
The firmware trusts the standard public CA bundle ESP-IDF ships
(`esp_crt_bundle_attach`, the same root store a browser trusts) -- so
any reverse proxy with a normal publicly-trusted certificate just
works: Let's Encrypt, a Cloudflare-proxied hostname (Cloudflare's own
edge certificate, issued by Google Trust Services or similar -- **not**
Cloudflare's Origin CA cert, which only ever sits on the Cloudflare-to-
origin leg and is never presented to a public client, ESP32 or browser
alike), or any other public CA. If your proxy uses a private/self-signed
cert instead (no public CA in the chain at all), the public bundle won't
trust it -- that's not supported today, would need switching back to
embedding that specific cert.
The firmware does **not** use ESP-IDF's general public CA bundle --
it pins one specific certificate, embedded at build time from
[`main/certs/tools_server_ca.pem`](main/certs/tools_server_ca.pem) and
trusted directly via `cert_pem` on every request. (The public bundle
was tried first and rejected: it does an exact byte-level match against
its compiled-in table, and a real-world root that's been re-issued
under a new serial/signature but the same name and key -- as Google did
for GTS Root R4 -- doesn't match it, confirmed on hardware.)
This means a normal publicly-trusted certificate (Let's Encrypt, a
Cloudflare-proxied hostname, etc.) does **not** automatically work --
only whichever certificate is actually embedded in
`certs/tools_server_ca.pem` is trusted. To point the device at a
different reverse proxy, extract that proxy's actual certificate and
replace the file's contents:
```
openssl s_client -connect <host>:443 -showcerts </dev/null
```
Pick whichever certificate in the printed chain you want as the trust
anchor (typically the root) and rebuild. A private/self-signed cert
works exactly the same way -- there's no requirement that it chain to
a public CA at all, since the device trusts this one file directly.
The device does perform normal hostname verification (it's not
skipped), so the Tools Server field's hostname has to match what the