Skip to content

[WIP] OCPBUGS-85705: Add client certificate authentication for HCP metrics#3864

Open
rashmigottipati wants to merge 2 commits into
operator-framework:masterfrom
rashmigottipati:OCPBUGS-85705-hcp-metrics-dual-auth
Open

[WIP] OCPBUGS-85705: Add client certificate authentication for HCP metrics#3864
rashmigottipati wants to merge 2 commits into
operator-framework:masterfrom
rashmigottipati:OCPBUGS-85705-hcp-metrics-dual-auth

Conversation

@rashmigottipati

Copy link
Copy Markdown
Member

Description of the change:

Implement dual authentication support for OLM metrics endpoints in pkg/lib/server/server.go:

  1. Client certificate authentication (HCP): Check r.TLS.PeerCertificates -and if present, the TLS layer already verified it via --client-ca flag, accept as authenticated and serve metrics
  2. Bearer token authentication (standalone OCP): If no client cert, fall back to existing filters.WithAuthenticationAndAuthorization() which validates tokens via TokenReview API
  3. Rejection: Return 401 if neither authentication method is present

Client certificate is checked first as an optimization to avoid unnecessary TokenReview API calls when cert is already validated.

Motivation for the change:

In HCP deployments, OLM metrics endpoints return 401 Unauthorized errors when Prometheus scrapes them.

The root cause: HCP Prometheus authenticates using client certificates (configured via tlsConfig.cert/keySecret in ServiceMonitors), but OLM's existing metrics authentication only supported bearer token validation. The controller-runtime filter filters.WithAuthenticationAndAuthorization() only has TokenAccessReviewClient configured, with no ClientCertificateCAContentProvider, so it cannot authenticate client certificates.This breaks metrics collection in HCP.

Reviewer Checklist

  • Implementation matches the proposed design, or proposal is updated to match implementation
  • Sufficient unit test coverage
  • Sufficient end-to-end test coverage
  • Bug fixes are accompanied by regression test(s)
  • e2e tests and flake fixes are accompanied evidence of flake testing, e.g. executing the test 100(0) times
  • tech debt/todo is accompanied by issue link(s) in comments in the surrounding code
  • Tests are comprehensible, e.g. Ginkgo DSL is being used appropriately
  • Docs updated or added to /doc
  • Commit messages sensible and descriptive
  • Tests marked as [FLAKE] are truly flaky and have an issue
  • Code is properly formatted

…HCP metrics

In HCP, Prometheus uses client certificates (tlsConfig.cert/keySecret) instead
   of bearer tokens. OLM only supported bearer token auth via TokenReview API,
   causing 401 errors.

   This adds dual authentication:
   - Client cert path: Check r.TLS.PeerCertificates (TLS already verified it)
   - Bearer token path: Validate via existing TokenReview (standalone OCP)

   Client cert checked first to avoid unnecessary API calls when cert present.

   Testing: Unit tests pass, verified on HCP cluster (targets now UP).
   Backwards compatible: standalone OCP bearer tokens unchanged.

   Fixes: https://issues.redhat.com/browse/OCPBUGS-85705

Signed-off-by: Rashmi Gottipati <rgottipa@redhat.com>
Copilot AI review requested due to automatic review settings July 9, 2026 19:35
@openshift-ci openshift-ci Bot requested review from joelanford and oceanc80 July 9, 2026 19:35
@openshift-ci

openshift-ci Bot commented Jul 9, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign oceanc80 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates OLM’s metrics server to support dual authentication on the /metrics endpoint—accepting either a verified client certificate (HCP Prometheus scrape path) or falling back to delegated bearer-token auth via controller-runtime (standalone OCP path).

Changes:

  • Add a dual-auth /metrics handler that prefers client certificate authentication and otherwise performs bearer token authentication.
  • Add new unit tests intended to cover the dual-auth behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
pkg/lib/server/server.go Implements dual auth for /metrics by checking TLS client certs first, then delegating to controller-runtime auth for bearer tokens.
pkg/lib/server/dual_auth_test.go Adds tests intended to validate client-cert, bearer-token, and unauthenticated request handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/lib/server/server.go
Comment on lines +141 to +151
// Check if client presented a verified certificate (HCP)
if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
// Client cert was verified by TLS layer via --client-ca
// Accept it as authenticated and serve metrics
if sc.debug {
sc.logger.Infof("Metrics request authenticated via client certificate from %s, CN: %s",
r.RemoteAddr, r.TLS.PeerCertificates[0].Subject.CommonName)
}
promhttp.Handler().ServeHTTP(w, r)
return
}
Comment thread pkg/lib/server/server.go Outdated
Comment on lines +161 to +169
// Validate bearer token via controller-runtime
httpClient, err := rest.HTTPClientFor(sc.kubeConfig)
if err != nil {
sc.logger.WithError(err).Error("Failed to create HTTP client for bearer token auth")
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}

filter, err := filters.WithAuthenticationAndAuthorization(sc.kubeConfig, httpClient)
Comment on lines +38 to +42
req.TLS = &tls.ConnectionState{
PeerCertificates: []*x509.Certificate{
{}, // Just need a non-nil cert for the test
},
}
Comment on lines +126 to +130
req.TLS = &tls.ConnectionState{
PeerCertificates: []*x509.Certificate{
{}, // Just need a non-nil cert for the test
},
}
Comment on lines +16 to +34
// Create a test handler that mimics our dual auth logic
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Check for client cert (HCP path)
if r.TLS != nil && len(r.TLS.PeerCertificates) > 0 {
w.WriteHeader(http.StatusOK)
w.Write([]byte("# metrics"))
return
}

// No client cert and no bearer token
if r.Header.Get("Authorization") == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}

// Bearer token path would validate here
w.WriteHeader(http.StatusOK)
w.Write([]byte("# metrics"))
})
Signed-off-by: Rashmi Gottipati <rgottipa@redhat.com>
Copilot AI review requested due to automatic review settings July 9, 2026 19:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment thread pkg/lib/server/server.go
Comment on lines +145 to +149
bearerTokenHandler, err := filter(logger, promhttp.Handler())
if err != nil {
return nil, fmt.Errorf("failed to wrap metrics handler with authentication: %w", err)
}
// Add request logging for debugging if debug mode is enabled
if sc.debug {
debugAuthHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
sc.logger.Infof("Metrics request from %s, Auth header present: %v, User-Agent: %s",
r.RemoteAddr, r.Header.Get("Authorization") != "", r.Header.Get("User-Agent"))
authenticatedMetricsHandler.ServeHTTP(w, r)
})
mux.Handle("/metrics", debugAuthHandler)
} else {
mux.Handle("/metrics", authenticatedMetricsHandler)
}
sc.logger.Info("Metrics endpoint configured with authentication and authorization")

Comment on lines +16 to +19
// Create a test handler that mimics our dual auth logic
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Check for client cert (HCP path)
if r.TLS != nil && len(r.TLS.VerifiedChains) > 0 {
@rashmigottipati rashmigottipati changed the title OCPBUGS-85705: Add client certificate authentication for HCP metrics [WIP] OCPBUGS-85705: Add client certificate authentication for HCP metrics Jul 9, 2026
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants