[FEATURE] Client-certificate mTLS from the OS credential store (non-exportable keys), including for http MCP servers

Status Open
Maintainer reply None cached
Activity 0 comments · opened Oct 9, 2026

Preflight Checklist

  • [x] I have searched existing requests. #58825 asked for the same OS-credential-store mTLS and was auto-closed for inactivity (then locked); this re-opens it and extends it to remote MCP servers.
  • [x] This is a single feature request (not multiple features)

Problem Statement

Zero Trust edges (e.g. Cloudflare Access) commonly require a device client certificate for every request. On managed Macs and Windows machines that identity lives in the OS credential store with a non-exportable private key (Secure Enclave / TPM-backed), by design.

Claude Code's mTLS support (CLAUDE_CODE_CLIENT_CERT / CLAUDE_CODE_CLIENT_KEY) only accepts PEM file paths, so it cannot use such an identity at all. The network-config docs also don't say whether these variables apply to remote MCP servers ("type": "http" / sse in .mcp.json) or only to model API traffic.

The result: an internal MCP gateway placed behind a device-cert Zero Trust policy cannot be reached with Claude Code's native http MCP transport. The only workaround is to wrap it in a local stdio proxy that does the mTLS handshake itself through the OS (NSURLSession + Keychain SecIdentity, or CNG/SChannel on Windows). That means one more binary to ship and keep in sync, and the proxy's own token refresh, error-flag and annotation handling has to be re-implemented to match the native transport.

Proposed Solution

  1. Let the client certificate be selected from the OS credential store instead of a file. For example:
  • CLAUDE_CODE_CLIENT_CERT_KEYCHAIN_ISSUER="<issuer CN>" (or a SHA-1/SHA-256 fingerprint selector) on macOS, with the TLS signature performed by the Security framework so the key never leaves the Secure Enclave;
  • the equivalent Windows certificate-store selector (CNG / CertStore by thumbprint).
  1. Apply client-certificate settings to remote MCP server connections, ideally configurable per server in .mcp.json, e.g.:

``json
"my-gateway": {
"type": "http",
"url": "https://mcp.example.internal/mcp",
"clientCertificate": { "source": "keychain", "issuer": "Example Device Intermediate CA" }
}
``
Only present the certificate when the server sends a TLS CertificateRequest.

  1. Document clearly which connections (API, proxy, MCP http/sse, OTEL) each mTLS setting covers.

Alternative Solutions

  • Exporting the device key to a PEM file: not possible (non-exportable key), and it would defeat the device-binding purpose if it were.
  • headersHelper can inject a Zero Trust JWT header, but it can't satisfy a policy that also requires the device certificate at the TLS layer.
  • A local stdio or localhost-HTTP proxy that does the mTLS itself works today, but duplicates the native MCP transport and has to be distributed to every user.

Priority

High - Significant impact on productivity

Feature Category

MCP / Configuration and settings

Use Case Example

An enterprise runs one internal MCP gateway for all engineers and is moving it behind a Zero Trust edge that requires a managed-device certificate (Secure-Enclave key in the macOS Keychain) plus SSO. With Keychain-backed client certs on http MCP servers, .mcp.json keeps "type": "http" and every engineer's Claude Code reaches the gateway from an enrolled laptop with no extra binary. Unmanaged machines are refused at the edge.

Additional Context

Related: #58825 (same OS-credential-store request, closed for inactivity), #57152 (docs for proxy/mTLS compatibility with MCP OAuth).

View original on GitHub ↗