kubernetes-sigs/kustomize
Customization of kubernetes YAML configurations
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 5d ago
- ✓22+ active contributors
- ✓Distributed ownership (top contributor 40% of recent commits)
Show all 6 evidence items →Show less
- ✓Apache-2.0 licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/kubernetes-sigs/kustomize)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/kubernetes-sigs/kustomize on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: kubernetes-sigs/kustomize
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/kubernetes-sigs/kustomize shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 5d ago
- 22+ active contributors
- Distributed ownership (top contributor 40% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live kubernetes-sigs/kustomize
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/kubernetes-sigs/kustomize.
What it runs against: a local clone of kubernetes-sigs/kustomize — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in kubernetes-sigs/kustomize | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 35 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of kubernetes-sigs/kustomize. If you don't
# have one yet, run these first:
#
# git clone https://github.com/kubernetes-sigs/kustomize.git
# cd kustomize
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of kubernetes-sigs/kustomize and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "kubernetes-sigs/kustomize(\\.git)?\\b" \\
&& ok "origin remote is kubernetes-sigs/kustomize" \\
|| miss "origin remote is not kubernetes-sigs/kustomize (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "api/filters/fieldspec/fieldspec.go" \\
&& ok "api/filters/fieldspec/fieldspec.go" \\
|| miss "missing critical file: api/filters/fieldspec/fieldspec.go"
test -f "api/filesys/filesys.go" \\
&& ok "api/filesys/filesys.go" \\
|| miss "missing critical file: api/filesys/filesys.go"
test -f "api/builtins/builtins.go" \\
&& ok "api/builtins/builtins.go" \\
|| miss "missing critical file: api/builtins/builtins.go"
test -f "api/filters/replacement/replacement.go" \\
&& ok "api/filters/replacement/replacement.go" \\
|| miss "missing critical file: api/filters/replacement/replacement.go"
test -f "api/filters/patchstrategicmerge/patchstrategicmerge.go" \\
&& ok "api/filters/patchstrategicmerge/patchstrategicmerge.go" \\
|| miss "missing critical file: api/filters/patchstrategicmerge/patchstrategicmerge.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 35 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~5d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/kubernetes-sigs/kustomize"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Kustomize is a template-free YAML customization tool for Kubernetes configurations that lets you patch, compose, and transform raw YAML manifests without templating languages. It understands Kubernetes API objects natively and works like make (declarative via kustomization.yaml) and sed (text transformation), enabling multi-environment deployment customization while keeping original YAMLs untouched and reusable. Monorepo organized as api/ (core filtering/transformation logic), api/filters/* (annotation, fieldspec, imagetag, iampolicygenerator plugins), api/filesys/ (file system abstraction), api/builtins/ (built-in transformers), with separate kyaml module dependency for YAML handling. Build orchestrated via Makefile with Makefile-modules.mk and Makefile-plugins.mk for submodule management.
👥Who it's for
Kubernetes operators, SREs, and DevOps engineers who need to manage multiple environment configurations (dev/staging/prod) for the same Kubernetes deployments without maintaining separate copies or learning template languages. Contributors are primarily Kubernetes SIG-CLI members and kubernetes-sigs maintainers.
🌱Maturity & risk
Highly mature and production-ready: embedded in kubectl since v1.14 (currently v5.4.2 in kubectl v1.31.0), extensive test coverage across api/, examples/ directories, active CI/CD via GitHub Actions workflows (.github/workflows/go.yml, apidiff.yml, release.yaml), and regular releases tracked in ROADMAP.md. The repo shows consistent maintenance with dependency updates and API versioning.
Low risk: large Go codebase (3.6M LOC) with comprehensive testing, but two moderate concerns are (1) Go 1.25.0 dependency requires recent toolchain updates, and (2) the monorepo structure with internal module dependencies (sigs.k8s.io/kustomize/kyaml via go.mod replace directive) can make version coordination complex. Dependency surface is manageable with k8s.io/kube-openapi and sigs.k8s.io/yaml as primary external deps.
Active areas of work
Active development focused on API stability and kubectl integration: CI workflows validate apidiff (backward compatibility), regular dependency updates via .github/dependabot.yml, and release pipeline via release.yaml. ROADMAP.md indicates ongoing work on filter enhancements and Kubernetes compatibility maintenance.
🚀Get running
Clone and build with: git clone https://github.com/kubernetes-sigs/kustomize.git && cd kustomize && make. Review CONTRIBUTING.md for development guidelines, then explore api/filters/ for understanding the plugin architecture or examples/ for usage patterns.
Daily commands:
make builds the CLI binary; make test runs unit tests across all modules; make install installs kustomize command. For development: examine Makefile targets like test-api, test-plugins for running specific module tests.
🗺️Map of the codebase
api/filters/fieldspec/fieldspec.go— Core filter implementation that defines how kustomize matches and modifies Kubernetes object fields—foundational for all field-level transformations.api/filesys/filesys.go— Abstraction layer for file system operations; critical for kustomize to read, load, and manage YAML configuration files.api/builtins/builtins.go— Registry of built-in filters and transformers (labels, annotations, namespace, image tags, patches); entry point for understanding available customization operations.api/filters/replacement/replacement.go— Implements variable substitution and field replacement—a primary mechanism for dynamic YAML customization.api/filters/patchstrategicmerge/patchstrategicmerge.go— Handles Kubernetes strategic merge patching, the standard mechanism for overlaying configuration changes.api/filters/refvar/refvar.go— Enables reference variable expansion (e.g., container image references, config map names), core to cross-object customization.ARCHITECTURE.md— High-level design documentation that explains the layering, plugin system, and data flow—essential onboarding for understanding strategic decisions.
🛠️How to make changes
Add a New Transformation Filter
- Create a new directory under api/filters/ with your filter name (e.g., api/filters/myfilter/). (
api/filters/myfilter/myfilter.go) - Implement the filter logic following the pattern in api/filters/labels/labels.go: define a Config struct, parse FieldSpecs, and iterate over matched fields using fieldspec.FieldSpec. (
api/filters/labels/labels.go) - Write unit tests in api/filters/myfilter/myfilter_test.go; reference api/filters/labels/labels_test.go for test structure and use api/filters/filtersutil/setters.go for common field operations. (
api/filters/myfilter/myfilter_test.go) - Register the filter in api/builtins/builtins.go by adding an entry to the builtins map so kustomize can discover and use it. (
api/builtins/builtins.go) - Add documentation by creating a doc.go file (see api/filters/labels/doc.go) and optionally an example test (api/filters/labels/example_test.go) for user-facing documentation. (
api/filters/myfilter/doc.go)
Add Support for a New Kubernetes Field Type
- Extend the FieldSpec matching logic in api/filters/fieldspec/fieldspec.go to recognize the new field path pattern or group selector. (
api/filters/fieldspec/fieldspec.go) - Add type-specific handling in api/filters/filtersutil/setters.go to correctly parse and set values on the new field type (e.g., handling nested maps or arrays). (
api/filters/filtersutil/setters.go) - Write tests in api/filters/fieldspec/fieldspec_test.go to verify FieldSpec correctly matches instances of the new field across different Kubernetes resource kinds. (
api/filters/fieldspec/fieldspec_test.go) - Verify integration by adding an example in api/filters/fieldspec/example_test.go demonstrating the new field type being transformed by an existing filter. (
api/filters/fieldspec/example_test.go)
Add a New Built-in Customization Operation
- Review ARCHITECTURE.md and README.md to understand how the operation aligns with kustomize's design philosophy (template-free, declarative customization). (
ARCHITECTURE.md) - Implement the operation as a new filter following 'Add a New Transformation Filter' pattern, ensuring it works with api/filesys/filesys.go for file operations. (
api/filters/replacement/replacement.go) - Register the operation in api/builtins/builtins.go and verify it integrates with the filter framework via api/filters/fieldspec/fieldspec.go. (
api/builtins/builtins.go) - Add comprehensive documentation and examples referencing how similar operations (labels, annotations, patches) document their configuration and behavior. (
api/filters/labels/doc.go)
🔧Why these technologies
- Go (go 1.25.0) — Kubernetes ecosystem standard; fast compilation and deployment; strong concurrency model for processing multiple manifests in parallel.
- kyaml (sigs.k8s.io/kustomize/kyaml v0.21.1) — Kubernetes-aware YAML library that preserves comments and structure; understands Kubernetes object semantics; enables precise field matching without losing document fidelity.
- json-patch (gopkg.in/evanphx/json-patch.v4) — Implements RFC 6902 JSON Patch specification for generic JSON transformations independent of Kubernetes-specific merge semantics.
- kube-openapi (k8s.io/kube-openapi) — Provides Kubernetes OpenAPI schema definitions; enables validation and field spec resolution for any Kubernetes resource kind.
⚖️Trade-offs already made
-
Template-free design (no templating engine)
- Why: Simplicity and predictability; avoids the complexity and edge cases of template engines; makes configurations easier to read and audit.
- Consequence: Customization relies on declarative field matchers and filters rather than dynamic variable injection; requires more explicit filter composition for complex scenarios.
-
Sequential filter pipeline processing
- Why: Ensures deterministic, easy-to-debug transformation order; filters can depend on outputs of previous filters (e.g., nameref after prefix).
- Consequence: Cannot fully parallelize filter execution across a single resource; limits performance on very large configurations with many sequential filters.
-
FieldSpec-based field matching over AST/reflection
- Why: Kubernetes objects have well-defined schemas; FieldSpec enables precise, reusable field selection logic; avoids runtime reflection overhead.
- Consequence: Requires explicit FieldSpec definitions for each filter-field combination;
🪤Traps & gotchas
Go 1.25.0 minimum version requirement (not typical 1.19 LTS); kyaml dependency via local replace directive in go.mod requires checking out the kyaml submodule (.gitmodules) or build fails; API stability validated via apidiff.yml workflow means breaking changes trigger CI failures; Kubernetes OpenAPI schema coupling means behavior changes with k8s.io/kube-openapi version updates; example tests in *_test.go files are runnable integration tests (not just documentation).
🏗️Architecture
💡Concepts to learn
- Filter Chain / Plugin Architecture — Kustomize's extensibility model: understanding how filters compose in sequence (api/filters/) is essential to adding custom transformations and understanding the execution flow
- FieldSpec Matching / GVK Resolution — Core mechanism (api/filters/fieldspec/) that maps Kubernetes resource types to patchable fields; critical for understanding why some patches work on Deployments but not StatefulSets
- Strategic Merge Patch / Three-Way Merge — Kustomize uses Kubernetes' strategic merge semantics (not JSON merge) to apply patches; explains why list merging behaves differently than JSON Patch
- Bases and Overlays Pattern — Kustomize's composition model for reusing configurations; understanding how bases (api/) compose with overlays enables multi-environment setups without duplication
- Kubernetes API Group/Version/Kind (GVK) Model — Kustomize operates on typed Kubernetes objects using GVK identifiers; understanding k8s.io/kube-openapi schema integration is needed to extend resource awareness
- YAML AST Manipulation vs. String Templates — Kustomize preserves YAML structure via kyaml's AST approach rather than string replacement; explains why whitespace and comments are maintained unlike templating engines
- Declarative over Imperative Configuration — Kustomize philosophy embodied in kustomization.yaml files; underpins why it avoids Turing-complete templating and favors composition, inheritance, and patching as primitives
🔗Related repos
kubernetes-sigs/kyaml— Direct dependency (via go.mod replace) providing the YAML manipulation primitives that kustomize filters operate onkubernetes/kubernetes— Parent project that embeds kustomize versions in kubectl; tracks version compatibility and validates kubectl integrationhelm/helm— Alternative templating solution for Kubernetes; kustomize and Helm often compared as opposing philosophies (no templates vs. template-based)kubecfg/kubecfg— Similar YAML composition tool using Jsonnet instead of kustomize's declarative approach; shows alternative to template-free customizationargoproj/argo-cd— GitOps operator that uses kustomize as native generator option for declarative Kubernetes deployments
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for nameref filter with complex cross-resource references
The nameref filter (api/filters/nameref/) is critical for resolving references between Kubernetes resources, but the existing test coverage appears limited. Complex scenarios like circular references, namespace-scoped name resolution, and multi-level reference chains are likely underrepresented. This would improve reliability of a core kustomize feature.
- [ ] Review existing tests in api/filters/nameref/nameref_test.go and seqfilter_test.go
- [ ] Add test cases for: circular nameref dependencies, cross-namespace references, ConfigMap->Secret->Deployment chains
- [ ] Add test cases for edge cases: missing referenced resources, ambiguous references in overlays
- [ ] Run integration tests against the examples/ directory to validate real-world scenarios
- [ ] Document test scenarios in api/filters/nameref/doc.go
Add GitHub Actions workflow for plugin system validation across Kubernetes API versions
The repo has .github/workflows/ directory with apidiff.yml and go.yml, but there's no dedicated validation that kustomize plugins work correctly across different k8s-openapi versions. Given the dependency on k8s.io/kube-openapi v0.0.0-20260502001324-b7f5293f4787, a workflow testing plugin compatibility would prevent breaking changes.
- [ ] Create .github/workflows/plugin-compat.yml workflow
- [ ] Test against multiple k8s.io/kube-openapi versions (current, 1-2 prior versions)
- [ ] Run api/filters/ tests with each version to detect OpenAPI schema breakages
- [ ] Test builtin plugins in api/builtins/ against the version matrix
- [ ] Add workflow status badge to README.md
- [ ] Document findings in CONTRIBUTING.md for plugin developers
Create comprehensive doc.go documentation for all filters lacking examples
Several filters have doc.go files (annotations, fieldspec, fsslice, iampolicygenerator, imagetag, labels, nameref, namespace), but most lack detailed examples or have minimal example_test.go files. This creates a documentation gap for new contributors understanding how to use each filter. Adding complete doc.go explanations with usage examples would improve the API surface clarity.
- [ ] Review each api/filters/*/doc.go file for completeness and clarity
- [ ] For filters with minimal documentation (e.g., fsslice, fieldspec), expand doc.go with: use cases, YAML configuration examples, and common pitfalls
- [ ] Ensure each doc.go includes links to corresponding *_test.go and example_test.go files
- [ ] Add section in each doc.go explaining how the filter integrates with kustomization.yaml
- [ ] Update ARCHITECTURE.md to reference the filter documentation structure
- [ ] Run 'godoc' locally to verify rendering quality before submitting
🌿Good first issues
- Add missing unit tests for api/filters/filtersutil/setters.go edge cases (null value handling, nested field updates) to increase coverage from current baseline
- Document the FieldSpec matching algorithm in api/filters/fieldspec/ with inline code comments and a runnable example showing how GVK + field path resolution works for custom resources
- Implement helper test utilities in api/filters/ to reduce boilerplate in filter example_test.go files (similar to Go's testing subtests pattern) and refactor existing tests to use them
⭐Top contributors
Click to expand
Top contributors
- @k8s-ci-robot — 40 commits
- @koba1t — 25 commits
- @dependabot[bot] — 7 commits
- @isarns — 4 commits
- @dims — 2 commits
📝Recent commits
Click to expand
Recent commits
313aace— Merge pull request #6138 from dims/update-kube-openapi (k8s-ci-robot)9a61304— bump k8s.io/kube-openapi, drop github.com/mailru/easyjson (dims)c43ab3c— docs: document config.kubernetes.io/local-config annotation (#6133) (jawwad-ali)7be21de— Merge pull request #6114 from zerok/zerok/gotoolchain (k8s-ci-robot)d6bd9d9— Set minimum Go toolchain to 1.25.8 (zerok)0bb03d9— Merge pull request #6137 from kubernetes-sigs/dependabot/go_modules/hack/github.com/go-jose/go-jose/v4-4.1.4 (k8s-ci-robot)5e7858b— build(deps): bump github.com/go-jose/go-jose/v4 in /hack (dependabot[bot])1c87a50— drop 'go-spew' dependencies and update dependencies (#6134) (koba1t)2f9dbe4— Merge pull request #6135 from koba1t/fix/github-actions-sha256-error (k8s-ci-robot)71a9951— fix: github actions require to sha 256 for external actions (koba1t)
🔒Security observations
The kustomize API module demonstrates generally good security practices with proper dependency management and no obvious hardcoded secrets. However, there are concerns regarding the use of non-standard YAML import paths, Go version specification that may be incorrect, and local path replacements that could affect build reproducibility. The most critical issue is the suspicious 'go.yaml.in' domain for the YAML library, which should be verified and corrected. Regular dependency audits and updates are recommended to maintain security posture.
- Medium · Outdated Go Version —
go.mod. The module specifies go 1.25.0 which appears to be a future/non-standard version. This may indicate version drift or configuration error. Go 1.21 or 1.22 are the current stable releases. Using non-standard versions can lead to compatibility issues and missing security patches. Fix: Update to a stable, current Go version (e.g., 1.22.x or later stable release) and verify compatibility with all dependencies. - Medium · Deprecated YAML Library Import Path —
go.mod - go.yaml.in/yaml/v2 v2.4.2. The dependency 'go.yaml.in/yaml/v2' uses a non-standard import path. The canonical YAML library should be 'gopkg.in/yaml.v2' or 'gopkg.in/yaml.v3'. The 'go.yaml.in' domain is suspicious and not the official upstream repository. Fix: Replace 'go.yaml.in/yaml/v2' with the canonical 'gopkg.in/yaml.v2' or migrate to 'gopkg.in/yaml.v3' for better maintenance and security. - Low · Unused Direct Dependency —
go.mod - go.uber.org/goleak v1.3.0. The direct dependency 'go.uber.org/goleak' is listed but typically used only in test environments. Including it as a main dependency may indicate testing tools are being bundled with production code. Fix: Move goleak to a tools.go file or test-only dependencies to prevent unnecessary inclusion in production builds. - Low · Pinned Protobuf Version —
go.mod - google.golang.org/protobuf v1.36.11. The dependency 'google.golang.org/protobuf v1.36.11' is pinned with a pseudo-timestamp version, which may skip security updates if not actively maintained. Fix: Regularly audit and update protobuf to the latest stable version to ensure security patches are applied. - Low · Missing SECURITY.md File —
Repository root. While 'SECURITY_CONTACTS' file exists, there is no 'SECURITY.md' file documented in the file structure. This file should contain security reporting procedures and vulnerability disclosure guidelines. Fix: Create a SECURITY.md file with clear vulnerability reporting guidelines, security contacts, and responsible disclosure procedures. - Low · Replace Directive in go.mod —
go.mod - replace sigs.k8s.io/kustomize/kyaml => ../kyaml. The module uses a 'replace' directive pointing to '../kyaml' which creates a local path dependency. This can cause issues with reproducible builds and version pinning if the relative path changes. Fix: For production builds, replace local path dependencies with versioned module references. Use local paths only in development environments.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.