Skip to content

WIP: Centralized TLS config#3225

Open
enarha wants to merge 2 commits intotektoncd:mainfrom
enarha:central-tls-config
Open

WIP: Centralized TLS config#3225
enarha wants to merge 2 commits intotektoncd:mainfrom
enarha:central-tls-config

Conversation

@enarha
Copy link
Contributor

@enarha enarha commented Feb 17, 2026

Changes

Submitter Checklist

These are the criteria that every PR should meet, please check them off as you
review them:

See the contribution guide for more details.

Release Notes

NONE

@tekton-robot tekton-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. release-note-none Denotes a PR that doesnt merit a release note. labels Feb 17, 2026
@tekton-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please assign piyush-garg after the PR has been reviewed.
You can assign the PR to them by writing /assign @piyush-garg in a comment when ready.

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

@tekton-robot tekton-robot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Feb 17, 2026
@enarha enarha mentioned this pull request Feb 17, 2026
4 tasks
@enarha
Copy link
Contributor Author

enarha commented Feb 17, 2026

This is still missing documentation, maybe add few more tests, but in general it's tested working and ready for review.

@enarha enarha force-pushed the central-tls-config branch 2 times, most recently from c641544 to bded46d Compare February 17, 2026 16:45
@jkhelil
Copy link
Member

jkhelil commented Feb 18, 2026

@enarha Please add PR deescrtipion with changes, architecture diagram,

@@ -0,0 +1,229 @@
/*
Copyright 2024 The Tekton Authors

Choose a reason for hiding this comment

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

Question: Should it not be 2026?

@@ -0,0 +1,167 @@
/*
Copyright 2024 The Tekton Authors

Choose a reason for hiding this comment

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

Same here.

@@ -0,0 +1,229 @@
/*
Copyright 2024 The Tekton Authors
Copy link
Member

Choose a reason for hiding this comment

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

s/2024/2026

@@ -0,0 +1,167 @@
/*
Copyright 2024 The Tekton Authors
Copy link
Member

Choose a reason for hiding this comment

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

s/2024/2026

// GetTLSEnvVarsFromAPIServer fetches the TLS security profile from the OpenShift APIServer
// resource and converts it to environment variable values that can be used by Tekton components.
// Returns nil if the APIServer has no TLS profile configured or if the shared lister is not initialized.
func GetTLSEnvVarsFromAPIServer(ctx context.Context, _ *rest.Config) (*TLSEnvVars, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Can we return tls.config here from crypto/tls
We Could need other configration in the future
We could use then func TLSEnvVarsFromConfig(cfg *tls.Config) *TLSEnvVars to turn it to envvars

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can. But we'll need to do the conversation twice APIServer string -> tls.Config -> env var strings instead of APIServer string -> env var strings. If you think we can immediately use the tls.Config with a specific consumer in mind (webhooks, nginx or whatever), then I'll follow your suggestion. If we do not have specific case immediately waiting for that, then I'll suggest we add this when we need it.
Please let me know what do you think.

recorder := events.NewLoggingEventRecorder("tekton-operator")
observedConfig, errs := apiserver.ObserveTLSSecurityProfile(listers, recorder, existingConfig)
if len(errs) > 0 {
logger.Warnf("Errors observing TLS security profile: %v", errs)
Copy link
Member

Choose a reason for hiding this comment

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

should we return error here

Copy link
Contributor Author

@enarha enarha Feb 24, 2026

Choose a reason for hiding this comment

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

Good question. It is a matter of policy - what do we want to happen in the case of a failure. I encountered two types of errors. In the first case we are able to read the APIServer, but failed to populate the map existingConfig with values. It was a bug in the way library-go handles this case in the older version we use, which I fixed, thus we have that two level check. The second case is we fail to read the APIServer resource. If we return an error and bubble it up, we'll break the reconciliation of the operands (e.g. TektonResult). The current behavior is to log a warning, degrade the TLS funcitonality (centralized TLS configuration does not have an effect), but operands continue working. The question is if we prefer that harder or softer form of failure. I believe with the hard failure, the Tekton administrator can still disable the centralized TLS configuration by disabling it through the TektonConfig and if that's the case I'm inclined to agree with a hard failure. WDYT?


// If no TLS configuration is present, return nil
if minVersion == "" && len(cipherSuites) == 0 {
return nil, nil
Copy link
Member

Choose a reason for hiding this comment

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

should we log and return error ?

return &TLSEnvVars{
MinVersion: convertTLSVersionToEnvFormat(minVersion),
CipherSuites: strings.Join(cipherSuites, ","),
CurvePreferences: "", // Will be populated once openshift/api#2583 is merged
Copy link
Member

Choose a reason for hiding this comment

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

can we mention this in PR description openshift/api#2583
because empty curve preferences means go defaults


// convertTLSVersionToEnvFormat converts library-go TLS version format (VersionTLSxx) to
// the format expected by Go's crypto/tls (1.x)
func convertTLSVersionToEnvFormat(version string) string {
Copy link
Member

Choose a reason for hiding this comment

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

We should consider parse TLSVversion to go format, webhook for example are expecting this in go native constant , I suppose the same thing for go apis using tls
https://github.com/knative/pkg/blob/main/webhook/webhook.go#L53

A conversion in this format feels more suitable to error prone constant
func parseTLSVersion(version string) (uint16, error) {
switch version {
case "VersionTLS10", "TLSv1.0":
return tls.VersionTLS10, nil
case "VersionTLS11", "TLSv1.1":
return tls.VersionTLS11, nil
case "VersionTLS12", "TLSv1.2":
return tls.VersionTLS12, nil
case "VersionTLS13", "TLSv1.3":
return tls.VersionTLS13, nil
default:
return 0, fmt.Errorf("unknown TLS version: %s", version)
}
}

if oe.resolvedTLSConfig == nil {
return ""
}
return fmt.Sprintf("%s:%s:%s", oe.resolvedTLSConfig.MinVersion, oe.resolvedTLSConfig.CipherSuites, oe.resolvedTLSConfig.CurvePreferences)
Copy link
Member

Choose a reason for hiding this comment

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

can we use a real hash function for the fingerprint like sha256, the ":" thingy cna be present in ciphers ro curves

Copy link
Member

Choose a reason for hiding this comment

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

Ok first look, thaught that this function is calculating a hash, but hte hash is calculted in isntallerset code
mm I think the name is misleading here, could we called GetPlatformData rather than GetHash Data

}
}

// injectTLSConfig injects the TLS configuration as environment variables into the Results API deployment
Copy link
Member

Choose a reason for hiding this comment

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

this should be common i think

if err := setupAPIServerTLSWatch(ctx, ctrl); err != nil {
// On OpenShift clusters the APIServer resource should always exist.
// This env var is an escape hatch for edge cases and must be explicitly enabled.
if os.Getenv("SKIP_APISERVER_TLS_WATCH") == "true" {
Copy link
Member

Choose a reason for hiding this comment

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

may be move this to a constant

@enarha enarha force-pushed the central-tls-config branch from bded46d to 2de7f83 Compare February 18, 2026 12:07
// and check with annotation, if they are same then we skip updating the object
// otherwise we update the manifest
specHash, err := hash.Compute(tr.Spec)
hashInput := struct {
Copy link
Member

Choose a reason for hiding this comment

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

This seems redudant and duplciate for all component
Can we have a common function that computes Hash give spec and common extension

Would make thing clear when redaing

if oe.resolvedTLSConfig == nil {
return ""
}
return fmt.Sprintf("%s:%s:%s", oe.resolvedTLSConfig.MinVersion, oe.resolvedTLSConfig.CipherSuites, oe.resolvedTLSConfig.CurvePreferences)
Copy link
Member

Choose a reason for hiding this comment

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

Ok first look, thaught that this function is calculating a hash, but hte hash is calculted in isntallerset code
mm I think the name is misleading here, could we called GetPlatformData rather than GetHash Data

@enarha enarha force-pushed the central-tls-config branch from 2de7f83 to b744aba Compare February 25, 2026 15:20
Add support for centralized TLS configuration derived from the
OpenShift APIServer TLS security profile. This enables Tekton
components to inherit cluster-wide TLS settings (minimum version,
cipher suites) via the TektonConfig CR.

Key changes:
- Watch the APIServer resource for TLS profile changes and enqueue
  TektonConfig for reconciliation
- Add GetTLSProfileFromAPIServer and TLSEnvVarsFromProfile to extract
  and convert TLS profiles to environment variables
- Add ResolveCentralTLSToEnvVars and InjectTLSEnvVars as reusable
  helpers for component extensions
- Add EnableCentralTLSConfig flag in TektonConfig OpenShift platform
  spec (opt-in, default false)
- Add GetPlatformData to the Extension interface for platform-specific
  hash data (e.g., TLS config fingerprint)
- Add RBAC permissions for reading the APIServer resource

Note: curve preferences (CurvePreferences) are currently omitted and
default to Go's standard library values until openshift/api#2583 is
merged.

Assisted-by: Cursor
Activate the centralized TLS configuration infrastructure for the
TektonResult component:

- Resolve TLS config from APIServer via ResolveCentralTLSToEnvVars in PreReconcile
- Inject TLS env vars into the results-api deployment using the generic
  InjectTLSEnvVars transformer
- Include TLS config fingerprint in GetPlatformData for installer set
  hash computation, triggering updates on TLS profile changes
- Log injected TLS config at Info level for observability

Assisted-by: Cursor
@enarha enarha force-pushed the central-tls-config branch from b744aba to 63a684f Compare February 26, 2026 15:59
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. release-note-none Denotes a PR that doesnt merit a release note. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants