Skip to content

feat(tls): add HTTPS support for in-cluster fixtures - #95

Open
dwmkerr wants to merge 3 commits into
mainfrom
feat/tls-support
Open

feat(tls): add HTTPS support for in-cluster fixtures#95
dwmkerr wants to merge 3 commits into
mainfrom
feat/tls-support

Conversation

@dwmkerr

@dwmkerr dwmkerr commented Apr 22, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds opt-in HTTPS support so strict MCP clients (notably the Go SDK, which enforces HTTPS on OAuth discovery per RFC 8414 / RFC 9728) can run against mock-llm in Kubernetes.
  • Runtime reads cert + key paths from config or `MOCK_LLM_TLS_CERT` / `MOCK_LLM_TLS_KEY` env vars (env takes precedence). No discovery, no runtime generation — same pattern as nginx, caddy, etcd, kubelet.
  • Helm chart generates a self-signed cert via built-in `genSelfSignedCert` and emits a `kubernetes.io/tls` Secret (mounted into the pod) plus a CA-only ConfigMap (for consumers to mount as a trust bundle). Bring-your-own via `tls.existingSecret` + `tls.existingCAConfigMap`.
  • Liveness/readiness/startup probes switch to `scheme: HTTPS` when TLS is on.
  • Default is unchanged: plain HTTP, no TLS artifacts emitted.

Test plan

  • `npx jest` — 152/152 pass (new: 6 unit tests for `loadTLSCredentials` incl. real HTTPS handshake; 3 updated `main.ts` tests covering env-var override and HTTPS branch)
  • `npm run test:samples` — 16/16 pass incl. new `samples/17-tls-basic.sh` verifying HTTPS handshake, HTTP rejection, and untrusted-cert rejection
  • `npx tsc --noEmit` clean
  • `helm lint ./chart` + `helm lint ./chart --set tls.enabled=true` clean
  • `helm template ... --set tls.enabled=true` — Secret, ConfigMap, env vars, volume mount, HTTPS probes all rendered correctly; with flag off, nothing added

dwmkerr added 2 commits April 22, 2026 14:24
The MCP 2025-06-18 spec + RFC 8414 / RFC 9728 require HTTPS issuer and
resource metadata URLs. The Go MCP SDK (and other strict clients) reject
non-HTTPS, non-loopback URLs at fetch time with no escape hatch. A mock-llm
running as a Kubernetes fixture needs real TLS for those clients to exercise
the full wire protocol.

mock-llm does not generate or discover certificates. It reads cert + key
paths from config (or MOCK_LLM_TLS_CERT / MOCK_LLM_TLS_KEY env vars, which
take precedence) and calls https.createServer. Same pattern as nginx, caddy,
etcd, kubelet.

The Helm chart generates a self-signed cert via genSelfSignedCert and emits:
  - Secret   {fullname}-tls  mounted into the pod (type kubernetes.io/tls)
  - ConfigMap {fullname}-ca  for consumers to mount as a trust bundle

Liveness / readiness / startup probes switch to scheme: HTTPS when
tls.enabled. Bring-your-own-cert via tls.existingSecret + tls.existingCAConfigMap.
Spins up an isolated mock-llm on port 6557 with a self-signed cert in a
tmpdir, then verifies:
  - /health returns 200 over HTTPS with the CA pinned
  - Plain HTTP is rejected on the TLS port
  - TLS verification rejects the cert without --cacert

Runs as part of npm run test:samples alongside the existing OAuth samples.
@codecov

codecov Bot commented Apr 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.94%. Comparing base (82901f8) to head (3d248e7).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #95      +/-   ##
==========================================
+ Coverage   92.77%   93.94%   +1.17%     
==========================================
  Files          20       21       +1     
  Lines         609      628      +19     
  Branches      110      117       +7     
==========================================
+ Hits          565      590      +25     
+ Misses         30       24       -6     
  Partials       14       14              
Flag Coverage Δ
samples 93.94% <100.00%> (+1.17%) ⬆️
unittests 93.94% <100.00%> (+1.17%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…ader

- main.ts: cover partial env override (enabled via env, paths fall back to
  config file) and the enabled=false disables branch.
- config.spec.ts: cover loadConfig non-existent path + YAML file containing a
  tls block (config.ts coverage 57% -> 100%).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant