Skip to content

curl_ca_bundle() overrides curl's own trust config and writes a derived CA bundle into the account dir #5

Description

@lroolle

statusline.sh:498 (curl_ca_bundle) splices NODE_EXTRA_CA_CERTS onto a copy of the system CA bundle, writes it to $CLAUDE_ACCOUNT_DIR/ca-bundle.pem, and passes --cacert on every API curl.

The motivation in the comment is real: node trusts NODE_EXTRA_CA_CERTS additively, curl has no additive flag, so behind a trusted mitm proxy (corporate TLS inspection) curl gets HTTP 000 while the CLI keeps working. For users whose environment sets ONLY NODE_EXTRA_CA_CERTS (which is exactly what Anthropic's corporate-proxy docs tell people to set), the splice is the difference between a working statusline and a permanent !net.

But the current implementation has three problems:

  1. --cacert OVERRIDES curl's own trust configuration. curl natively honors CURL_CA_BUNDLE and SSL_CERT_FILE. An environment that already exports a correct combined bundle through those vars (mitm tracers do this; cctrace has since 0.10.0 -- it exports system CAs + its CA as CURL_CA_BUNDLE / SSL_CERT_FILE to every subprocess precisely so tools need no per-tool CA hacks) gets second-guessed: the script replaces a deliberate curl trust config with a file derived from a node-only variable. If NODE_EXTRA_CA_CERTS is stale or points somewhere else, the spliced bundle is WRONG while the env's own config was right.

  2. It silently writes trust material to disk. A derived ca-bundle.pem appears in every account dir (~/.claude/statusline/accounts//ca-bundle.pem) with no indication of what created it or why. Trust bundles are the kind of file a user should never be surprised by. Verified on a live box: three copies (root + two accounts), one of them stale relative to the CA it was spliced from.

  3. General users pay for a niche fix. The splice runs for anyone with NODE_EXTRA_CA_CERTS set, whether or not their curl trust is already fine.

Proposed fix -- one guard at the top of curl_ca_bundle():

curl_ca_bundle() {
    # curl already has trust config -- never second-guess it
    [ -n "$CURL_CA_BUNDLE" ] || [ -n "$SSL_CERT_FILE" ] && return 0
    [ -n "$NODE_EXTRA_CA_CERTS" ] && [ -r "$NODE_EXTRA_CA_CERTS" ] || return 0
    ...

This demotes the splice to a pure fallback for node-only corp setups:

  • env exports CURL_CA_BUNDLE/SSL_CERT_FILE (well-configured mitm, cctrace >= 0.10) -> curl handles it natively, no bundle written, no --cacert
  • env sets only NODE_EXTRA_CA_CERTS (corp proxy per Anthropic docs) -> splice still saves the statusline, unchanged
  • no extra CA anywhere -> no-op, unchanged

Optionally: write the fallback bundle under a cache path (statusline/cache/) rather than the account dir, and name it something self-describing (curl-trust-fallback.pem) -- account dirs hold identity/config, and a trust file sitting there uncommented reads as something scarier than a cache.

Verified live (2026-07-28): with CURL_CA_BUNDLE/SSL_CERT_FILE exported by the environment, removing the --cacert override changes nothing -- the profile/usage fetches succeed through curl's native env trust. The splice only ever mattered for the node-only case.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions