Skip to content

[Feature] Peer identity cannot be required — certificateAdmits fails open without a certificate; add a fail-closed requirePeerIdentity option #1190

Description

@pathosDev

Problem

certificateAdmits fails open by design: when the socket exposes no peer certificate, the identity check passes.

    const certificate = connection.socket?.peerCertificate?.();
    if (certificate === undefined) return true;

The surrounding comment explains the intent — strengthen mTLS deployments "without introducing a new configuration knob that could be left off" — and for the plaintext and one-way-TLS cases, fail-open is the only workable default. But the same branch means peer identity can never be required:

  • On Deno, peerCertificate is structurally unavailable (Deno.TlsConn exposes none — the reason the field is optional), so a Deno node in an otherwise-mTLS cluster silently performs zero identity binding while looking fully configured. [Security] DenoTcpBackend silently drops ca, requestClientCert and the client cert/key — cluster mTLS cannot be enabled at all on Deno #576 fixed the listener half (a Deno mTLS listener is refused); the dial-side/identity half has no equivalent guard.
  • On any runtime, a misconfiguration that drops the client-certificate request (or a backend that stops exposing the certificate accessor) degrades identity binding to a no-op silently — the exact failure mode the "no knob that could be left off" reasoning wanted to avoid, just inverted: there is also no knob to insist.

The ask is the fail-closed opt-in the comment decided against, now as a deliberate choice: a requirePeerIdentity (name negotiable) transport option under which certificate === undefined rejects the handshake instead of admitting it. Deployments that enable it get a hard guarantee ("every peer proved its name") and an immediate, loud failure on Deno or on half-applied TLS bundles — instead of a quiet downgrade discovered during an incident.

Evidence

src/cluster/Transport.ts:431-437 — the fail-open branch and its rationale comment (v0.15.0 tree). src/runtime/tcp/TcpBackend.tspeerCertificate optional in TcpSocketLike specifically for the Deno case.

Verification status

CONFIRMED-BY-READ — quoted from the shipped source; no cluster was stood up in this pass. From the independent production-readiness pass (2026-08-14), second batch (design decisions). Related: #576 (Deno listener refusal, closed), #941/#591 (enabling TLS at all), #1172 (rotation), #964 (the missing wire credential this check partially compensates for).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: mediumUseful, not urgentsecuritySecurity-relevant — see severity label for impact tier

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions