Skip to content

Support custom CA certificates without disabling TLS verification #123

Description

@ZilvinasKucinskas

Priority: P1

Related API contract: Provide a stable error hierarchy and safe, class-specific metadata

Describe the issue

Wreq::Client currently exposes TLS verification as a boolean verify: option but cannot configure a custom CA certificate or CA bundle. Connections through an intercepting HTTPS proxy, private PKI, or local TLS test service therefore require globally changing trust configuration or using verify: false.

Disabling verification is not a safe substitute for adding the intended trust anchor. The underlying Rust wreq client already supports custom certificate stores and PEM/DER certificate parsing; this is primarily a Ruby binding and API-design gap.

Proposed Ruby API

Use conventional path and content options while retaining verification:

client = Wreq::Client.new(
  ca_file: "/path/to/ca-bundle.pem",
  verify: true
)

client = Wreq::Client.new(
  ca_pem: File.binread("/path/to/root-ca.pem"),
  verify: true
)

ca_file: is the important first API because it matches Net::HTTP, OpenSSL, Faraday, and common environment configuration. ca_pem: is useful when certificate material comes from a secret store without a durable file. A future Wreq::CertStore object can be added if callers need reusable stores or DER certificates; it is not required for the first implementation.

Trust semantics

  • Keep hostname and certificate-chain verification enabled.
  • Define whether ca_file/ca_pem replace or augment the default roots. Do not imply append semantics accidentally: Net::HTTP and OpenSSL commonly treat an explicitly configured CA source as the trust source. If an augmenting API is offered, name it explicitly (for example additional_ca_pem) and test that public roots remain available.
  • Read ca_file while building the client and raise synchronously for a missing, unreadable, or invalid file.
  • Accept a path-like object via to_path in addition to String paths.
  • Invalid PEM content should raise a typed TLS/configuration error before any request.
  • Do not include PEM contents or path credentials in exception messages or inspect output.
  • Client identities/mTLS are a separate feature and are intentionally out of scope.

Acceptance criteria

  • A client can connect to a locally generated CA-signed HTTPS server with verification enabled when that CA is supplied.
  • The same server is rejected when its CA is not trusted.
  • Supplying a custom CA does not implicitly set verify: false.
  • Tests establish the documented trust-store policy: replacement uses only the supplied store, while any explicitly named augmenting mode retains default public roots.
  • Invalid paths and invalid PEM fail during client construction.
  • Tests cover single and bundled PEM certificates, a path-like object, hostname mismatch, missing file, and malformed certificate data.

Ruby ecosystem precedent

  • Net::HTTP exposes ca_file, ca_path, and cert_store while keeping peer verification separate.
  • Faraday's structured SSL options include ca_file, ca_path, and cert_store.
  • wreq-python binds the same Rust feature through path-based verification and a reusable CertStore supporting PEM and DER certificates.

Relevant source

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions