Skip to content

macOS: apply Keychain trust settings when building the CA bundle (follow-up to #764/#766) #767

Description

@magurotuna

Follow-up to #764 / PR #766.

Context

PR #766 generates a combined CA bundle (system roots + clawpatrol MITM CA) so clawpatrol run no longer breaks TLS to passthrough hosts. On macOS the system-roots source is obtained by dumping Apple's curated root store:

security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain

This was deliberately narrowed to the SystemRoot keychain only (not System.keychain) to avoid promoting un-trust-evaluated certs to anchors.

Gap

security find-certificate -a -p exports certificate objects without evaluating trust:

  • It does not apply admin/user distrust overrides ("Never Trust"), trust domains, or SSL-purpose constraints, so a built-in root the operator/admin has explicitly distrusted would still land in the bundle.
  • It does not reflect Apple policy-layer constraints on built-in roots.
  • Roots the user trusted in the login keychain are omitted (under-trust) — those passthrough hosts still fail, though fail-closed (visible TLS error, never a silent MITM).

Proposed work

Derive the trusted set using Security.framework trust-settings semantics rather than a raw keychain dump — e.g. SecTrustSettingsCopyCertificates across the user/admin/system domains plus SecTrustSettingsCopyTrustSettings to honor deny/SSL-purpose, or an equivalent trust-evaluation pass — then emit the surviving roots as PEM. This needs cgo/Security.framework.

Also worth revisiting: the Darwin reader test currently runs locally only; the macOS CI job's -run 'Sandbox|Dial|Nosy|Plugin|ExternalCredential' filter excludes it.

Non-goals / current behavior

Until then, the current fail-closed behavior stands: an un-trusted or missing root is simply absent from the bundle, so verification fails visibly rather than silently trusting the wrong anchor.

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