agnes-the-ai-analyst/app/web
Minas Arustamyan af72c5d259 fix(setup): walk TLS chain for trust-store match — Let's Encrypt cleanup
`_read_agnes_ca_pem()` decides whether the served fullchain.pem needs
trust-bootstrapping in the rendered setup prompt. Pre-fix it only
checked the leaf's *immediate* issuer against `certifi`'s trust store.
For Let's Encrypt that's the intermediate (R13), which `certifi` does
not ship — only roots are in trust stores. So a publicly-trusted LE
chain still tripped the "needs bootstrap" path and the setup prompt
emitted a step-0 TLS trust block + clone-fallback marketplace block
that no client actually needs (Bun-compiled `claude.exe`, system git,
Python via certifi all validate the chain through the bundled ISRG
Root X1).

Now we walk every cert in the fullchain (leaf + intermediates) and
return None the first time any cert's issuer is in the certifi trust
store — that captures the standard "leaf signed by intermediate signed
by publicly-trusted root" shape. Trusted subjects are read once into
a set for O(1) lookup. Self-signed (leaf.issuer == leaf.subject) and
private-CA chains (no chain link's issuer in certifi) keep their
previous "return PEM" behavior, so deployments that genuinely need
the bootstrap still get it.

Validated end-to-end against the live VM at
agnes-marustamyan.groupondev.com (LE R13 → ISRG Root X1):
  - Let's Encrypt fullchain                   → has_ca=False (was True)
  - Self-signed cert                          → has_ca=True
  - Corporate-CA chain (private root)         → has_ca=True
  - Missing fullchain.pem                     → has_ca=False
2026-05-05 04:55:06 +02:00
..
static feat(rbac+marketplace): RBAC v13 + Claude Code marketplace + #81/#83/#44 hardening 2026-04-28 14:25:04 +02:00
templates feat(store): /store + /my-ai-stack — community marketplace + per-user composition 2026-05-05 02:53:49 +02:00
__init__.py feat: add FastAPI server with auth, RBAC, and all API endpoints 2026-03-27 15:19:18 +01:00
router.py fix(setup): walk TLS chain for trust-store match — Let's Encrypt cleanup 2026-05-05 04:55:06 +02:00
setup_instructions.py feat(setup-instructions): preflight checks both git and claude 2026-05-04 22:11:38 +02:00