Repository navigation
Conversation
b4b7be9 to
f6b2b19
Compare
rhuss
left a comment
There was a problem hiding this comment.
cc-review summary
Reviewed at f6b2b199e with a 6-dimension agent pass plus CodeRabbit. The feature is well-scoped and security-careful: client-cert auth is enforced with no fail-open, an incomplete TLS config fails closed with no plaintext fallback, the reload machinery is reused cleanly and tolerates bad reloads, and plaintext stays the default. The standout is the trust-boundary design: keeping the metrics client CA independent from the gateway client CA, and rejecting Helm configs that reuse it, correctly avoids widening the gateway client CA's authority to metrics scraping. All eight goals are delivered. No correctness or security defect.
Two non-blocking Production recommendations below, the first worth addressing before merge. Test-depth, Helm-maintainability, and naming/doc findings are omitted here to keep this focused; happy to share them.
Source: cc-review (6 agents + CodeRabbit)
f6b2b19 to
68274d2
Compare
|
Rebased onto current
Focused Rust, Helm, documentation, and Kubernetes validation are recorded in the PR description. @rhuss, when you have a moment, could uou take another look? Thanks!! |
68274d2 to
d42b91d
Compare
There was a problem hiding this comment.
Written by Claude Code, reviewed by @krishicks
The overall shape looks good: a separate config type, partial input fails instead of falling back, and the listener never drops to plaintext. Inline comments below; the two Helm items are the most important.
d42b91d to
75d54e1
Compare
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
The chart rejected only a metrics.tls.clientCaSecretName that matched the gateway client CA Secret by name. In the default pkiInitJob mode, certgen also writes the gateway CA as ca.crt into the sandbox client TLS Secret (server.tls.clientTlsSecretName), which sandbox workloads mount for control-plane mTLS. Pointing the metrics client CA at that Secret passed the existing check and would have trusted every sandbox client certificate on the metrics listener. Reject server.tls.clientTlsSecretName as well, document in values.yaml, the chart README, the gateway configuration docs, and the debug skill that both checks compare Secret names only and cannot detect a different Secret holding the same CA, and cover the default and custom Secret names with rendering tests. Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
The secure metrics scraping docs said a missing or malformed metrics TLS Secret leaves the metrics listener disabled while the gateway keeps serving. On Helm that is only true for a Secret that exists with malformed contents. The metrics TLS volumes are non-optional Secret mounts, so a Secret that is missing entirely, or a client CA Secret without a ca.crt key, fails the mount and the gateway pod never starts. State both outcomes in the chart README, the gateway configuration docs, and the cluster debugging skill. A loud FailedMount is preferable to a quietly missing scrape target, so the mounts stay non-optional. Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
The man page synopsis implied --metrics-require-client-auth accepts a space-separated BOOL, but the flag is declared with require_equals, so only the bare flag and the =VALUE forms parse. Document the synopsis as [--metrics-require-client-auth[=BOOL]], spell out the accepted forms in the description, and pin them with a CLI parsing test so the synopsis and the parser cannot drift apart. Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Handshake rejections and timeouts shared a single rate limiter, so the periodic WARN reported combined suppressed/total counts under the message of whichever event happened to trigger it. During a burst of untrusted client certificates, an operator could see the timeout message with a count made up mostly of certificate rejections. Give each event type its own limiter so warnings and counts stay attributable, and pin the behavior with a test where a timeout during a rejection burst still warns immediately. Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
The listener identification change retagged the gateway reload OCSF message from 'TLS certificate config reloaded successfully' to 'gateway TLS certificate config reloaded successfully', but the pre-existing ocsf_log test that pins the JSONL message was not updated, so the openshell-server suite failed deterministically. The test's intent is exactly that a gateway reload reaches JSONL, so pin the listener-tagged message. Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
The chart README stated the sandbox client TLS Secret is seeded with the gateway CA as a general fact. certgen only writes that CA when the chart manages PKI; with cert-manager the Secret is operator-provided. The reuse rejection applies in every mode, so state the seeding claim only for chart-managed PKI. Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
The tests module already imports command, so the super:: prefix tripped the unused-qualifications lint. Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
The metrics TLS flag resolution rejected key-without-cert, cert-without-key, and a lone client CA with actionable errors, but no test pinned those boundaries. Cover all three so a future refactor of the partial-input validation cannot silently drop them. Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Preparing a server configuration with metrics TLS material but no enabled metrics listener errors out, but no test pinned that boundary. Cover it through prepare_server_config_with_drivers so the validation cannot be silently dropped. Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
75d54e1 to
5e17b77
Compare
|
@krishicks could you please re-assess the latest updates (and maybe add an |
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Signed-off-by: Gaizka Menendez Hernandez <gmenende@redhat.com>
Summary
Add opt-in TLS and mutual TLS support for OpenShell's dedicated metrics listener while preserving plaintext metrics as the default for compatibility.
This is the first implementation PR for #3664. It intentionally focuses on the runtime listener, operator-provided Secrets, and the metrics trust boundary; chart-managed metrics PKI, monitoring resources, and metrics ingress policy configuration remain follow-up work.
Related Issue
Fixes #3664
Changes
/metricsover HTTPS when metrics TLS is configured, with optional client-certificate authentication.server.tls.clientTlsSecretName, which certgen seeds with the gateway CA); the comparison is by Secret name only.FailedMount) and malformed contents in an existing Secret (only the metrics listener is disabled).Validation
cargo fmt --checkcargo test -p openshell-core metrics_tls --libcargo test -p openshell-server metrics_tls --libcargo test -p openshell-server --features test-support(full suite)cargo test -p openshell-server tls_metrics_listener_serves_https_and_rejects_plaintext --libcargo test -p openshell-server metrics_mtls_trusts_only_the_metrics_client_ca --libcargo test -p openshell-server test_reload_invalid_preserves_old --libmise run helm:test(415 tests)mise run helm:lintmise run helm:docs:checkmise run docsgo build ./...andgo test ./...insdk/gomis-aligned LINKEDIT string pool, fixed in Rust 1.99). It runs locally withCARGO_PROFILE_RELEASE_BUILD_OVERRIDE_STRIP=none.mise run ciis not marked successful: its concurrently launched Go tasks use incompatible local compiler-cache artifacts (go1.26.7versusgo1.26.2). The same Go build and test commands pass when run directly after clearing the local Go cache; this branch does not modify Go code.The required Strix scan could not run in this environment because Docker could not pull
usestrix/strix:latest(registry access denied).Checklist