Repository navigation
Conversation
Both properties existed on the Request class (Node/Bun/uWS) but only `authorized` was mentioned, and only in prose. Add both to the Properties table with per-runtime behavior, and cross-link them from the "Trust and mTLS" paragraph, which already explained authorized but not by name in a linkable spot. Verified against harper's server/serverHelpers/Request.ts and proxyProtocol.ts: both getters are populated not just on a directly- terminated TLS connection but also on Harper Fabric's proxy-protocol UDS mirror once it decodes a verified client cert. peerCertificate returns an empty object (not null) when the connection is TLS-capable but no client cert was presented -- Node's own getPeerCertificate() semantics. Dispatch-Task: documentation-request-authorized-peercert Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HbtUN4YmHf5NBj25wZZnsV
Pre-push review (codex + Harper domain) flagged that the initial wording
implied a single "server's configured CA(s)" and an identical parsed
certificate object across both paths. In fact the Fabric UDS mirror
verifies against Symphony's own client_ca_pem (symphony src/tls.rs),
not Harper's http.mtls config, and its synthesized peerCertificate
(proxyProtocol.ts synthesizePeerCertificate) carries a reduced field set
and returns {} in more cases than "no cert presented" (proxy-verified but
oversized chain omitted, or an unparseable leaf). Also drop the "added in
v5.2.0" implication -- both getters predate v5.2.0 (present in the local
v5.0.0 core tag); what's new in v5.2.0 is the Fabric mirror populating
them, so the badges are now type="changed".
Dispatch-Task: documentation-request-authorized-peercert
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HbtUN4YmHf5NBj25wZZnsV
Round-2 review (codex + gemini + domain) caught that http.mtls has no CA
field -- Harper's client CA is tls.certificateAuthority
(reference/http/configuration.md:200). Also softened "different CA" to
"not guaranteed to share a trust root": Symphony's CA and Harper's are
independently configured, not proven to always differ. Fixed a
self-contradicting "forwarded but omitted" phrase, added the omitted
`raw` field to the mirror's certificate shape (it's the escape hatch for
pubkey/bits/etc via re-parsing), scoped chain-omission language to the
mirror path only, and noted the rare authorized:true + peerCertificate:{}
combination when the forwarded leaf fails to parse.
Dispatch-Task: documentation-request-authorized-peercert
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HbtUN4YmHf5NBj25wZZnsV
…ate cases Round-3 review (codex + gemini + domain) caught two more accuracy gaps, both already documented elsewhere in this repo: - Direct-TLS `authorized`/`peerCertificate` verification isn't limited to `tls.certificateAuthority` -- Harper also trusts any certificate record marked as an authority, including its own auto-generated install-time CA (harper core security/keys.ts). Reused this repo's existing wording from reference/security/certificate-verification.md:229 and linked it. - `peerCertificate.issuerCertificate` isn't always present on a direct connection either: Harper omits the chain on every resumed TLS session and on Node.js 26.8.0/26.8.1 (documented at reference/security/certificate-verification.md:227). Dispatch-Task: documentation-request-authorized-peercert Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HbtUN4YmHf5NBj25wZZnsV
…ecords on the mTLS page - request.peerCertificate: issuerCertificate is also absent when the issuer is in neither the client's chain nor Harper's trusted CAs (e.g. an unverified client when mTLS is optional), not only on resumed sessions and Node.js 26.8.0/26.8.1. - request.authorized reflects chain trust only; revocation is checked separately by Harper's mTLS authentication when http.mtls is configured. - mtls-authentication.md named only tls.certificateAuthority as a CA source; certificate records marked as an authority count too. Dispatch-Task: documentation-request-authorized-peercert Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UrvaPnSVqfCTL7KPatikPN
The http.mtls option said client certificates verify only against tls.certificateAuthority; certificate records marked as an authority count too, matching the mTLS authentication and request.authorized docs. Dispatch-Task: documentation-request-authorized-peercert Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UrvaPnSVqfCTL7KPatikPN
There was a problem hiding this comment.
Code Review
This pull request updates the documentation for Harper's HTTP API, configuration, and mTLS authentication, specifically detailing the new authorized and peerCertificate request properties and clarifying CA verification behavior. The review feedback recommends enhancing the clarity and conciseness of the security warnings in the mTLS section by removing filler phrases like 'Note that' and splitting complex sentences into distinct, readable points.
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-735 This preview will update automatically when you push new commits. |
…n sentences Drops "Note that" and gives each caveat in the Trust and mTLS paragraph its own sentence so it can be found when scanning. Dispatch-Task: documentation-request-authorized-peercert Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UrvaPnSVqfCTL7KPatikPN
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-735 This preview will update automatically when you push new commits. |
⊙ Problem
The HTTP
Requestreference mentionedrequest.authorizedonly in prose and never mentionedrequest.peerCertificate. A handler doing mTLS could not tell what either returns, or that results differ behind Harper Fabric's proxy and on Bun and uWebSockets.🤔 Is this requirement warranted?
As specified, yes. Both getters ship in
Request.ts, and the proxy path from harper#1858 (v5.2.0) changes who verifies the client and what the certificate object holds. Without the rows, a reader can assume the wrong trust root. No in-flight PR covers this.💡 Solution
authorizedandpeerCertificate, with their results on direct TLS, behind the Fabric proxy, on a plain connection, and on Bun and uWebSockets.issuerCertificatecan be missing.authorizedignores revocation, which Harper's mTLS authentication checks separately.http.mtlspages now name authority certificate records as a CA source.🤔 Is
request.authorizedthe right gate to recommend?The proxy path verifies against Symphony's CA, not Harper's, so the same
truecan rest on different trust roots. The alternative is to point apps at Harper's mTLS authentication (request.user), which also applies revocation. I keptauthorizedbecause it works in any middleware, and added the caveats. Reversing it later means re-teaching readers.🤔 Keep both TLS paths inside the table cells?
The
peerCertificatecell is now long, and a short "Client certificates" subsection the table links to would scan better. I kept the cells so each row stands alone. Links from the mTLS paragraph land at the table top, not on the row, because no table inreference/uses per-row anchors. Easy to restructure later.✅ Verification
npm run buildpasses with no broken links or anchors, andnpm run format:checkis clean. Prettier re-widened the table, so every row in it shows as changed.origin/main: the Node, Bun and uWebSockets getters inserver/serverHelpers/Request.ts, and the proxy path inserver/serverHelpers/proxyProtocol.ts(applyProxyHeader,synthesizePeerCertificate). The revocation caveat matches the gate insecurity/auth.ts.git tag --containsplaces the proxy path (harper#1858) in v5.2.0, which thev5.2.0badges on the new rows reflect. The related harper#1985 addedconnectionInfo.🤖 Generated by Anthropic Claude Sonnet 5.5; posted via @kriszyp.
🤖 Generated with Claude Code
https://claude.ai/code/session_01UrvaPnSVqfCTL7KPatikPN
Related PRs: none found
Complexity: medium
Deferred findings
839360062b78ca53nit documentation —reference/http/api.md— #properties links land at table top, not the new rows — NOT FILEDReview-Coverage: authored=claude; ran=gemini,cursor-muse,codex; adjudicated=domain; blocked=muse(failed); declined=cursor-grok,cursor-composer,cursor-kimi; rounds=7; full=1 @ d8b1e49
Review-Attention: skim ~2m (decisions: mirror-semantics-in-table-cells, authorized-as-recommended-gate) @ d8b1e49