Codecov uploader TLS validation with a private CA: no documented CA bundle option
0 reputation · 26 Oct 2024, 20:35 UTC
0 reputation · 26 Oct 2024, 20:35 UTC
Upload coverage reports from CI runners that sit behind a corporate TLS-inspecting proxy, where the Codecov endpoint presents a certificate chained to a private CA. The upload should succeed with full certificate validation intact, not with verification disabled.
From what I can determine, the Codecov uploader (recent versions) validates TLS against the system default CA store and exposes no documented flag, environment variable, or config file key to point at an alternative CA bundle. The only documented escape hatch appears to be --no-verify, which disables validation entirely and is not acceptable for production uploads.
Modifying the runner's system trust store is possible but requires privileged access on shared CI infrastructure and affects every other process on the host, so I would prefer an uploader-scoped option if one exists.
SSL_CERT_FILE or REQUESTS_CA_BUNDLE through its underlying HTTP stack?--no-verify, what is the recommended approach for runners where the system trust store cannot be modified?31275 reputation · 27 Oct 2024, 04:28 UTC
There is no uploader-specific flag or codecov.yml key for a custom CA bundle, but you most likely don't need one. The Codecov Bash uploader is a wrapper around curl, and curl honors the standard OpenSSL/cURL environment variables SSL_CERT_FILE and CURL_CA_BUNDLE. Setting one of those scoped to the upload step gives you full certificate validation against your private CA without modifying the system trust store and without resorting to --no-verify.
Confirmed by inspection: the Bash uploader shells out to curl for the actual upload, so its TLS behavior is curl's TLS behavior. You can verify this on your runner by reading the uploader script (curl -s https://codecov.io/bash | less) and confirming the upload commands.
Likely, but verify on your stack: that your runner's curl is linked against OpenSSL (which reads SSL_CERT_FILE) or a build that reads CURL_CA_BUNDLE. Most Linux CI images qualify, but check with curl --version — the SSL backend is printed on the first line (e.g., OpenSSL, GnuTLS, Secure Transport). Secure Transport (macOS) builds ignore these variables.
Not applicable: REQUESTS_CA_BUNDLE is specific to Python's requests library. The Bash uploader ignores it. It would only matter if you were uploading via a Python-based tool instead.
# CI step, scoped to this job only
export SSL_CERT_FILE=/path/to/corporate-ca-bundle.pem
# Optionally also, harmless if redundant:
export CURL_CA_BUNDLE="$SSL_CERT_FILE"
bash <(curl -s https://codecov.io/bash) -t "$CODECOV_TOKEN" -f coverage.xmlThe bundle file should contain your corporate CA's certificate (PEM), or a chain bundle if your proxy uses an intermediate. Keep it in the repo or fetch it from a trusted internal location during the job.
# 1. Confirm curl's TLS backend
curl --version
# 2. Reproduce the failure and the fix outside the uploader
curl -v https://codecov.io/ -o /dev/null
SSL_CERT_FILE=/path/to/corporate-ca-bundle.pem curl -v https://codecov.io/ -o /dev/nullThe second command should show a successful handshake (SSL certificate verify ok). If it works there, the same variable will work for the uploader, since it inherits the environment.
--no-verify: it disables validation entirely and exposes the upload to man-in-the-middle interception, which is exactly what your TLS-inspecting proxy makes easier.One detail that would change this recommendation: which uploader you're actually invoking (Bash uploader version, the newer Codecov CLI, or a CI action). The newer CLI is a compiled binary rather than a curl wrapper, so if that's what you use, verify its env-var handling separately before relying on the above.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.