Skip to content

TEP-0085: Add design proposal for per-namespace controller configuration#1250

Open
waveywaves wants to merge 1 commit intotektoncd:mainfrom
waveywaves:tep-0085-per-namespace-config-revision
Open

TEP-0085: Add design proposal for per-namespace controller configuration#1250
waveywaves wants to merge 1 commit intotektoncd:mainfrom
waveywaves:tep-0085-per-namespace-config-revision

Conversation

@waveywaves
Copy link
Copy Markdown
Member

@waveywaves waveywaves commented Feb 11, 2026

Summary

This PR revises TEP-0085 from a problem-statement-only document (merged in PR #506) into a full design proposal for per-namespace controller configuration in Tekton Pipelines.

The original design proposal (PR #607) was closed without addressing reviewer feedback from @vdemeester, @chmouel, and @pritidesai. This revision incorporates all that feedback and updates the design to reflect the current Tekton architecture.

/kind tep

Design Overview

Cluster-level changes (new fields in feature-flags ConfigMap):

  • enforced-config-level: cluster (default, off) or namespace (enables per-NS overrides)
  • namespace-config-cache-size: LRU cache cap for the controller (default: 1000)
  • non-overridable-fields: operator lockdown for additional fields beyond built-in cluster-only set

Namespace-level: Namespace admins create labeled ConfigMaps (tekton-config-defaults, tekton-feature-flags) with two required labels:

  • app.kubernetes.io/part-of: tekton-pipelines (Kubernetes standard, identifies as Tekton resource)
  • tekton.dev/config-type: namespace (marks as namespace config override)

Architecture:

  • Controller process: lazy per-namespace NamespaceConfigCache with LRU eviction. Loads namespace ConfigMaps on first reconciliation via direct GET, starts namespace-scoped WATCH for updates. No cluster-wide LIST at startup.
  • Webhook process: stateless direct GET per admission request. No cache, no double-caching.
  • Config merging: raw map[string]string merge before parsing (preserves boolean field disambiguation). Precedence: namespace > cluster > hardcoded defaults.
  • Security: field-by-field categorization (overridable vs cluster-only), stability gating for per-feature flags, non-overridable-fields operator lockdown, system namespace exclusion.

Key Design Decisions

  • Lazy loading over cluster-wide informer: Startup cost scales with active namespaces, not total. No LIST at startup.
  • Controller cache + stateless webhook: Reconciler is the hot path (repeated access). Webhook sees each resource once at CREATE.
  • Raw map merge before parsing: FeatureFlags struct uses raw bool types. Cannot distinguish "set to false" from "not set" after parsing.
  • Label-based discovery: No controller restart needed. Proven pattern in Kubernetes ecosystem.
  • Cache flush on enforcedConfigLevel change: Reduces split-brain window to watch event latency (<1s).

Addresses Prior Feedback

All reviewer feedback from the closed PR #607:

  • @vdemeester: ConfigMap field gate (not env var), no restart needed, label-based discovery
  • @chmouel: Behavior on config change matches cluster-wide behavior (in-flight resources pick up changes on next reconciliation)
  • @pritidesai: Resolved config inspection via annotation, logs, and future tkn CLI

Related

/cc @vdemeester @jerop

@tekton-robot tekton-robot requested a review from jerop February 11, 2026 01:52
@tekton-robot tekton-robot added the kind/tep Categorizes issue or PR as related to a TEP (or needs a TEP). label Feb 11, 2026
@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. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Feb 11, 2026
@waveywaves waveywaves force-pushed the tep-0085-per-namespace-config-revision branch 2 times, most recently from 92d7102 to 03e600d Compare February 11, 2026 02:18
@waveywaves
Copy link
Copy Markdown
Member Author

PR is in draft state right now, so reviews are not necessary as I need to take a few passes through the draft still and present it in the working group call first.

@waveywaves waveywaves force-pushed the tep-0085-per-namespace-config-revision branch from 03e600d to da27ad3 Compare February 16, 2026 11:58
@waveywaves
Copy link
Copy Markdown
Member Author

/test pull-community-teps-lint

@waveywaves waveywaves force-pushed the tep-0085-per-namespace-config-revision branch from da27ad3 to e04d77f Compare February 16, 2026 12:18
@waveywaves
Copy link
Copy Markdown
Member Author

/test pull-community-teps-lint

1 similar comment
@waveywaves
Copy link
Copy Markdown
Member Author

/test pull-community-teps-lint

@tekton-robot tekton-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Feb 16, 2026
Copy link
Copy Markdown
Member

@afrittoli afrittoli left a comment

Choose a reason for hiding this comment

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

Just a small question, looks good to me, thank you for reviving this!
/approve

@tekton-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: afrittoli

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

The pull request process is described 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 approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 16, 2026
@waveywaves
Copy link
Copy Markdown
Member Author

/test pull-community-teps-lint

@tekton-robot tekton-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Feb 16, 2026
@waveywaves waveywaves force-pushed the tep-0085-per-namespace-config-revision branch 8 times, most recently from 4a8d153 to 38b0700 Compare February 16, 2026 21:36
@waveywaves waveywaves force-pushed the tep-0085-per-namespace-config-revision branch from 38b0700 to e55a4be Compare February 16, 2026 21:40
@tekton-robot tekton-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Feb 16, 2026
@waveywaves waveywaves force-pushed the tep-0085-per-namespace-config-revision branch 8 times, most recently from b3e9006 to 0eff574 Compare February 16, 2026 23:28
@waveywaves waveywaves marked this pull request as ready for review February 17, 2026 10:40
@tekton-robot tekton-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 17, 2026
@waveywaves waveywaves force-pushed the tep-0085-per-namespace-config-revision branch from 0eff574 to 507d421 Compare February 17, 2026 10:50
Copy link
Copy Markdown
Member

@vdemeester vdemeester left a comment

Choose a reason for hiding this comment

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

Few comments, overall looks good.

Comment on lines +240 to +248
| Section | Summary |
|---------|---------|
| [Overview](#overview) | Four-component design: ConfigMaps, gate, merging, field categorization |
| [Namespace ConfigMap Discovery](#namespace-configmap-discovery) | Label-based discovery, ConfigMap naming conventions |
| [Operator Control via enforcedConfigLevel](#operator-control-via-enforcedconfiglevel) | Cluster-level gate: `cluster` (default) or `namespace` |
| [Configuration Hierarchy and Merging](#configuration-hierarchy-and-merging) | Three-level precedence, raw map merge before parsing |
| [Overridable Fields](#overridable-fields) | Field-by-field categorization for config-defaults and feature-flags |
| [Security Considerations](#security-considerations) | Six safeguards: opt-in, non-overridable fields, RBAC, system NS exclusion |
| [Displaying Merged Configuration](#displaying-merged-configuration) | Annotation, logs, and future CLI for config inspection |
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.

nit: we usually don't have those summary 🙃

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We don't but I added the summary table to the doc for making this easier to read. It was a mindful addition. Should I remove it ?

@vdemeester vdemeester self-assigned this Feb 17, 2026
Rewrite TEP-0085 with a complete design proposal based on lessons learned
from implementing TEP-0138 and reviewing PR tektoncd#607 feedback. Key changes:

- Label-based namespace ConfigMap discovery (modeled after Tekton Pruner)
- enforcedConfigLevel gate in cluster feature-flags ConfigMap
- Field-by-field merge at raw map level before parsing (boolean disambiguation)
- Explicit overridable/cluster-only field categorization for config-defaults and feature-flags
- Namespace-aware webhook defaulting via shared NamespaceConfigCache (no Knative vendor changes)
- Operator lockdown via non-overridable-fields key
- Security model: opt-in, stability gating, system namespace exclusion
- Six mermaid diagrams illustrating architecture and data flow
- Prior art analysis (ResourceQuota, Prometheus Operator, cert-manager, CoreDNS)
- Six alternatives evaluated with rationale
- Test plan with CI testing matrix
- Implementation milestones

Also updates teps/README.md status from proposed to implementable.

Addresses: tektoncd/pipeline#9153, tektoncd/pipeline#4190
@waveywaves waveywaves force-pushed the tep-0085-per-namespace-config-revision branch from 507d421 to 48b5dfd Compare February 18, 2026 12:33
@waveywaves
Copy link
Copy Markdown
Member Author

Consider changing the name of the tenant configmaps to either be configuratble or have them be more unique

waveywaves added a commit to waveywaves/tekton-pipeline that referenced this pull request Mar 5, 2026
Adds support for namespace-scoped ConfigMap overrides of config-defaults
and feature-flags. When per-namespace-configuration is enabled, ConfigMaps
named tekton-config-defaults and tekton-feature-flags in user namespaces
(labeled with tekton.dev/pipeline-config: "true") override the cluster-level
defaults on a field-by-field basis.

Key features:
- LRU cache for namespace ConfigMaps (configurable size)
- Field-by-field merge with security field protection
- Non-overridable fields cannot be overridden per namespace
- Operators can lock additional fields via non-overridable-fields
- Integrated into TaskRun/PipelineRun reconcilers and webhook defaulting

Part of: tektoncd/community#1250 (TEP-0085)
Fixes: tektoncd#4190

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
waveywaves added a commit to waveywaves/tekton-pipeline that referenced this pull request Mar 5, 2026
Adds support for namespace-scoped ConfigMap overrides of config-defaults
and feature-flags. When per-namespace-configuration is enabled, ConfigMaps
named tekton-config-defaults and tekton-feature-flags in user namespaces
(labeled with tekton.dev/pipeline-config: "true") override the cluster-level
defaults on a field-by-field basis.

Key features:
- LRU cache for namespace ConfigMaps (configurable size)
- Field-by-field merge with security field protection
- Non-overridable fields cannot be overridden per namespace
- Operators can lock additional fields via non-overridable-fields
- Integrated into TaskRun/PipelineRun reconcilers and webhook defaulting

Part of: tektoncd/community#1250 (TEP-0085)
Fixes: tektoncd#4190
waveywaves added a commit to waveywaves/tekton-pipeline that referenced this pull request Mar 5, 2026
Adds support for namespace-scoped ConfigMap overrides of config-defaults
and feature-flags. When per-namespace-configuration is enabled, ConfigMaps
named tekton-config-defaults and tekton-feature-flags in user namespaces
(labeled with tekton.dev/pipeline-config: "true") override the cluster-level
defaults on a field-by-field basis.

Key features:
- LRU cache for namespace ConfigMaps (configurable size)
- Field-by-field merge with security field protection
- Non-overridable fields cannot be overridden per namespace
- Operators can lock additional fields via non-overridable-fields
- Integrated into TaskRun/PipelineRun reconcilers and webhook defaulting

Part of: tektoncd/community#1250 (TEP-0085)
Fixes: tektoncd#4190

Co-Authored-By: Claude <noreply@anthropic.com>
waveywaves added a commit to waveywaves/tekton-pipeline that referenced this pull request Mar 5, 2026
Adds support for namespace-scoped ConfigMap overrides of config-defaults
and feature-flags. When per-namespace-configuration is enabled, ConfigMaps
named tekton-config-defaults and tekton-feature-flags in user namespaces
(labeled with tekton.dev/pipeline-config: "true") override the cluster-level
defaults on a field-by-field basis.

Key features:
- LRU cache for namespace ConfigMaps (configurable size)
- Field-by-field merge with security field protection
- Non-overridable fields cannot be overridden per namespace
- Operators can lock additional fields via non-overridable-fields
- Integrated into TaskRun/PipelineRun reconcilers and webhook defaulting

Part of: tektoncd/community#1250 (TEP-0085)
Fixes: tektoncd#4190

Co-Authored-By: Claude <noreply@anthropic.com>
waveywaves added a commit to waveywaves/tekton-pipeline that referenced this pull request Mar 5, 2026
Adds support for namespace-scoped ConfigMap overrides of config-defaults
and feature-flags. When per-namespace-configuration is enabled, ConfigMaps
named tekton-config-defaults and tekton-feature-flags in user namespaces
(labeled with tekton.dev/pipeline-config: "true") override the cluster-level
defaults on a field-by-field basis.

Key features:
- LRU cache for namespace ConfigMaps (configurable size)
- Field-by-field merge with security field protection
- Non-overridable fields cannot be overridden per namespace
- Operators can lock additional fields via non-overridable-fields
- Integrated into TaskRun/PipelineRun reconcilers and webhook defaulting

Part of: tektoncd/community#1250 (TEP-0085)
Fixes: tektoncd#4190

Co-Authored-By: Claude <noreply@anthropic.com>
waveywaves added a commit to waveywaves/tekton-pipeline that referenced this pull request Mar 5, 2026
Adds support for namespace-scoped ConfigMap overrides of config-defaults
and feature-flags. When per-namespace-configuration is enabled, ConfigMaps
named tekton-config-defaults and tekton-feature-flags in user namespaces
(labeled with tekton.dev/pipeline-config: "true") override the cluster-level
defaults on a field-by-field basis.

Key features:
- LRU cache for namespace ConfigMaps (configurable size)
- Field-by-field merge with security field protection
- Non-overridable fields cannot be overridden per namespace
- Operators can lock additional fields via non-overridable-fields
- Integrated into TaskRun/PipelineRun reconcilers and webhook defaulting

Part of: tektoncd/community#1250 (TEP-0085)
Fixes: tektoncd#4190

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/tep Categorizes issue or PR as related to a TEP (or needs a TEP). 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