From 87f670657f84946a502de1461819e0c41a67cba0 Mon Sep 17 00:00:00 2001 From: slayerjain Date: Mon, 19 Oct 2026 09:33:59 +0530 Subject: [PATCH] docs: tell a client that pins its own CA how to trust keploy's A client that trusts only a CA file it names itself (Python requests with verify=, a Go client with its own RootCAs) rejects the certificate keploy answers its HTTPS calls with, and keploy record does not record the call. keploy record now warns of it at the end of a recording, naming the test cases, and its next_step links here (keploy/keploy#4853). Nothing in the docs said what to do: the TLS page covers keploy's automatic trust injection and OS-trust-store libraries only. The new section "A client that pins its own CA" shows the warning and how to point such a client at a file that holds keploy's per-run CA as well as its own: - in Docker and Docker Compose, from /tmp/keploy-tls/keploy-ca.crt, which keploy mounts in the app container; - natively, from the file SSL_CERT_FILE names in the app's environment. Checked against keploy main in a lane container. The compose example as written makes both pinned calls answer 200 and be recorded, with no warning. Natively, SSL_CERT_FILE names a file holding one certificate, "Keploy MITM CA ". Signed-off-by: slayerjain --- .../running-keploy/docker-tls.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/versioned_docs/version-4.0.0/running-keploy/docker-tls.md b/versioned_docs/version-4.0.0/running-keploy/docker-tls.md index 50440e745..1e9c188ec 100644 --- a/versioned_docs/version-4.0.0/running-keploy/docker-tls.md +++ b/versioned_docs/version-4.0.0/running-keploy/docker-tls.md @@ -83,6 +83,54 @@ Voilà! 🧑🏻‍💻 We have the tests with data mocks running! 🐰🎉 You'll be able to see the test cases that ran with the results report on the console as well as locally in the `testReport` directory. +## A client that pins its own CA + +A client that trusts only a CA file it names itself rejects the certificate +Keploy answers its HTTPS calls with, because Keploy's per-run CA isn't in that +file. Examples are Python `requests` with `verify="/certs/ca.pem"` and a Go +client with its own `RootCAs`. Its call fails, and Keploy doesn't record it. +`keploy record` says so when the recording ends, and names the test cases +recorded while those calls failed: + +```text +WARN 2 TLS handshake(s) with keploy's proxy failed while this recording ran (a client that does not trust keploy's CA rejects keploy's certificate); those calls are not recorded {"testCases": ["get-pinned-1", "get-pinned-2"], ...} +``` + +To record those calls, point the client at a file that holds Keploy's CA as +well as its own while Keploy runs your application: + +- **Docker and Docker Compose:** Keploy mounts its per-run CA in your + application container at `/tmp/keploy-tls/keploy-ca.crt`. Combine it with your + own CA when the container starts, and point the client at the combined file: + + ```yaml + services: + app: + environment: + PINNED_CA: /tmp/ca-with-keploy.pem + command: + [ + "/bin/sh", + "-c", + "cat /certs/ca.pem /tmp/keploy-tls/keploy-ca.crt > /tmp/ca-with-keploy.pem 2>/dev/null || cp /certs/ca.pem /tmp/ca-with-keploy.pem; exec python -u /app.py", + ] + ``` + + ```python + requests.get(url, verify=os.environ.get("PINNED_CA", "/certs/ca.pem")) + ``` + + Outside Keploy the file doesn't exist, so the container falls back to your + own CA. + +- **Native:** while Keploy runs your application, it sets `SSL_CERT_FILE` in the + application's environment to a file that holds Keploy's per-run CA. Combine + that file with your own CA in the same way: + + ```shell + cat /certs/ca.pem "$SSL_CERT_FILE" > /tmp/ca-with-keploy.pem + ``` + ## Removing Keploy's CA from a host For containerized runs there is nothing to clean up — the per-run CA lives in the