Skip to content

docs(tls): document multi-source cipher/SECLEVEL resolution per listener#598

Open
heskew wants to merge 1 commit into
mainfrom
docs/tls-effective-ciphers
Open

docs(tls): document multi-source cipher/SECLEVEL resolution per listener#598
heskew wants to merge 1 commit into
mainfrom
docs/tls-effective-ciphers

Conversation

@heskew

@heskew heskew commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

Documents the composed per-listener cipher resolution shipped in HarperFast/harper#1841 (v5.2.0, closes harper#1840):

  • tls.ciphers field description updated: the value may live at the top level, on tls[] entries, or on certificate records, and is composed per listener.
  • New Cipher Suites and Security Level section on reference/http/tls.md: source priority (operationsApi.tls > root tls > certificate records), relevance rules (CA entries only for mTLS-verifying listeners; uses matching incl. legacy https/no-uses generics), suite-preserving @SECLEVEL composition with a worked legacy-client-CA example, composition warnings, and the restart-required caveat for post-boot changes.
  • Tagged <VersionBadge type="changed" version="v5.2.0" />.

Where to look

  • The worked example resolves HIGH:!aNULL + CA DEFAULT@SECLEVEL=0 to HIGH:!aNULL@SECLEVEL=0 — matches the resolver's unit tests in core.
  • Version derivation: #1841 merged to main after 5.2.0-alpha.5, so tagged v5.2.0 per AGENTS.md convention — flag if it gets cherry-picked to 5.1 and needs a different badge.

🤖 Generated with Claude Code (Claude Fable 5)

Documents HarperFast/harper#1841 (5.2.0): every configured ciphers source
is honored — composed as suites-from-highest-priority-source plus the
minimum explicit @SECLEVEL — with CA entries scoped to mTLS-verifying
listeners, operationsApi.tls precedence, composition warnings, and the
restart-required caveat for post-boot changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
gemini-code-assist[bot]

This comment was marked as resolved.

@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-598

This preview will update automatically when you push new commits.

@heskew
heskew marked this pull request as ready for review July 20, 2026 16:55
@heskew
heskew requested a review from a team as a code owner July 20, 2026 16:55
Comment thread reference/http/tls.md

<VersionBadge type="changed" version="v5.2.0" /> — every configured `ciphers` source is now honored; previously only `tls.ciphers` (or the first array entry's) took effect and all others were silently ignored.

A TLS listener has a single effective cipher string: OpenSSL applies the cipher list — and any `@SECLEVEL` command in it, which governs client-certificate chain verification — from the configuration the listener was created with. A per-certificate value cannot take effect on its own, so Harper resolves one effective string per listener from every configured source:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SECLEVEL is broader than client-certificate chain verification: OpenSSL applies the level to cipher algorithms, curves, signature algorithms, DH sizes, and certificate key/signature strength for the whole listener. Could we say that here and explicitly warn that selecting the minimum level downgrades every connection on this listener? Otherwise the CA-scoped source rule reads like a CA-scoped relaxation.

Comment thread reference/http/tls.md
ciphers: DEFAULT@SECLEVEL=0
```

resolves to `HIGH:!aNULL@SECLEVEL=0` — the configured suites are preserved while the relaxed security level lets the legacy chains (for example SHA-1-signed client CAs, which otherwise fail verification on modern OpenSSL) verify.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we replace "SHA-1-signed client CAs" with something like "client certificate chains containing SHA-1 signatures (for example, on a leaf or intermediate certificate)"? OpenSSL does not enforce a directly trusted root's own signature algorithm, and the core integration fixture also signs the leaf client certificate with SHA-1. As written, someone with only a SHA-1-self-signed root may unnecessarily set SECLEVEL=0.

Comment thread reference/http/tls.md

## Cipher Suites and Security Level

<VersionBadge type="changed" version="v5.2.0" /> — every configured `ciphers` source is now honored; previously only `tls.ciphers` (or the first array entry's) took effect and all others were silently ignored.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core change deliberately does not apply effective-cipher/@SECLEVEL resolution on the Bun/BoringSSL server path, and its integration test skips Bun. Could we scope "every configured source is now honored" to Node.js/OpenSSL and state the Bun exception? Also, repository convention asks for the <VersionBadge> on its own line with this explanation in a separate paragraph.

Comment thread reference/http/tls.md

A TLS listener has a single effective cipher string: OpenSSL applies the cipher list — and any `@SECLEVEL` command in it, which governs client-certificate chain verification — from the configuration the listener was created with. A per-certificate value cannot take effect on its own, so Harper resolves one effective string per listener from every configured source:

- The listener's own `tls` section, in priority order: `operationsApi.tls` for the Operations API listener, then the root `tls` section (an object's `ciphers` directly; an array's entries individually).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation relevance-filters tls[] entries by uses (and includes CA entries only for mTLS); it does not consume every array entry for every listener. Could this say "relevant array entries" and state that the no-uses / legacy https / matching-listener rules apply here too? Otherwise an Operations-API-only entry can look like it should alter the application listener.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants