Reflector keeps copies of secrets in sync instead of importing them
Custom Kubernetes controller that can be used to replicate secrets, configmaps and certificates.
At a glance
- What is it?
- Kubernetes Reflector is a C# controller that watches secrets and configmaps and writes their contents into mirror resources in the same or other namespaces. It solves the narrow problem of keeping TLS material consistent across namespaces, and the README stops short of explaining how a resource opts in.
- Who is it for?
- Adopt Reflector when your TLS or application secrets genuinely exist in more than one namespace, since that is the case it covers and nothing wider. Do not adopt it as a secret distribution system across clusters or as a substitute for external secret managers, because it replicates within one cluster.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Star history
- emberstack/kubernetes-reflector1,689 ★ · +4
| Repository | 2026-10-16 | 2026-10-23 |
|---|---|---|
| emberstack/kubernetes-reflector | 1.7k | 1.7k |
4 Stars in the last 7 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
A reflector watches one resource type and writes copies
The README defines the scope in one sentence: Reflector is a Kubernetes addon "designed to monitor changes to resources (secrets and configmaps) and reflect changes to mirror resources in the same or other namespaces."
Three properties of that sentence are load-bearing. First, it watches, so a change to the source propagates rather than being copied once at creation. Second, the targets are mirror resources, which means the copies are first-class objects you can read, mount and delete. Third, and most importantly, the target namespace may differ from the source, which is the whole reason this controller exists. Kubernetes does not let a pod mount a secret from another namespace, so a shared certificate has to be duplicated by something, and this is that something.
The mirror is not a symlink or a projection. It is a real object with its own lifecycle, so anything watching it, a deployment's `envFrom`, a volume mount, an External Secrets style controller, sees an ordinary Secret. That is what makes the approach portable across whatever creates the source.
The repository is a .NET solution, `ES.Kubernetes.Reflector.sln`, with `Directory.Build.props`, `Directory.Packages.props`, `GitVersion.yaml` and `NuGet.config` at the root, and `src/` plus `tests/` alongside. The primary language is C#, and GitVersion explains the tag scheme.
v10.0.x tags and images for amd64, arm and arm64
The release cadence is visible in the tag list. v10.0.63 shipped on 2026-08-04, v10.0.64 on 2026-08-11 and v10.0.65 on 2026-08-14. Patch releases a week apart, all within the 10.0.x line, is what a maintained controller with a versioned chart looks like.
The repository is not archived and its last push was on 2026-10-14, which is after those tags. So development is ahead of the newest release by about two months, and the gap between a tag and the default branch is where unreleased fixes live if you build from source.
Platform support is stated in a single line near the top of the README: "Supports `amd64`, `arm` and `arm64`". That covers the three architectures that matter for cluster nodes, and it also means the published Docker image is multi-arch rather than amd64-only. Images live at `emberstack/kubernetes-reflector` on Docker Hub, with `ghcr.io/emberstack/kubernetes-reflector` offered as an alternative repository in the chart values.
The topics list mentions cert-manager, certificate and configmap alongside secrets and controller, suggesting certificate use cases across namespaces.
Install with the OCI chart or the emberstack Helm repo
Two deployment paths, both Helm. The prerequisites are Kubernetes 1.22 or newer, and Helm 3.8 or newer if you use Helm. The README calls Helm the recommended route, and a manual deployment is mentioned without being documented in the excerpt you can see.
The direct OCI install is one command:
$ helm upgrade --install reflector oci://ghcr.io/emberstack/helm-charts/reflectorThe alternative adds a traditional repository first:
$ helm repo add emberstack https://emberstack.github.io/helm-charts
$ helm repo update
$ helm upgrade --install reflector emberstack/reflectorNeither command sets a namespace or any reflector-specific flag, so the defaults do the work on a fresh install. Both use `upgrade --install`, which means re-running is how you apply a chart change.
The one thing worth deciding before you run either is `configuration.kubernetes.skipTlsVerify`, whose default is `false`. That flag skips TLS verification when connecting to the cluster, and leaving it at `false` means the controller is validating the API server certificate. Setting it to `true` to silence a connection error trades a real security property for a green pod, so treat it as a last resort.
Namespace exclusion uses glob patterns, not prefix matching
The value table has one entry that does real work and is easy to skim past. `configuration.watcher.excludedNamespaces` takes a comma-separated list of namespace glob patterns, and the README spells out that it supports `*` for any characters and `?` for a single character, with the example `"ephie-*,kube-system,*-temp"`.
That example does three different things at once: `ephie-*` drops every namespace with a given prefix, `kube-system` names one namespace exactly, and `*-temp` drops a suffix family. A plain prefix filter could only handle the first of those.
Excluding namespaces is not a minor feature in a reflected cluster. A reflector that mirrors into every namespace will happily propagate a secret into a namespace that was supposed to be isolated, and `kube-system` is the obvious first entry because you rarely want application secrets landing there. The glob form means you can also drop transient namespaces by pattern rather than maintaining a list that grows every time someone creates a sandbox namespace.
The parameter has no default, which is the honest default for a feature that should be set deliberately per cluster. The related `configuration.watcher.timeout` sets a maximum watcher lifetime in seconds and also has no default listed.
The README does not document how a secret opts in
This is the gap to be aware of. Everything about deployment is documented: the chart, the values table with defaults, the probe timings, the RBAC and ServiceAccount toggles. What the README excerpt does not contain is the opt-in mechanism itself, namely which annotation on a Secret or ConfigMap causes Reflector to mirror it, how the mirror's name and namespace are derived, and what happens when a mirror already exists.
That is not a small omission. It is the contract between you and the controller. Two things depend on it: what you must add to the source object, and whether a mirror can be safely hand-edited or would be reverted on the next sync. A controller may overwrite edits during reconciliation, so confirm that behaviour before touching a production mirror.
The same applies to ownership. `rbac.enabled` defaults to `true` and `serviceAccount.create` defaults to `true`, meaning the chart creates a ServiceAccount named after the release. Whether the reflector also annotates mirrored objects to record where they came from, and how it treats a namespace that stops opting in, is not answered in the README.
Read the project's own documentation for the annotation semantics before you deploy, and pin the chart version rather than tracking latest while you work that out.
External Secrets and Sealed Secrets solve the same need differently
Reflector complements tools that generate secrets by distributing resources that already exist within the cluster.
The limitation follows from the design. Replication is within one cluster; the README says the mirror can be in the same or another namespace, and says nothing about federation across clusters. If your workloads span clusters, you still need a source of truth and a distribution mechanism, and Reflector is the wrong layer. Likewise, if nobody has created the source Secret, a reflector has nothing to reflect, so it does not remove the need for whatever provisions that secret in the first place.
Editorial conclusion
Adopt Reflector when your TLS or application secrets genuinely exist in more than one namespace, since that is the case it covers and nothing wider. Do not adopt it as a secret distribution system across clusters or as a substitute for external secret managers, because it replicates within one cluster. Before installing, read the annotation documentation yourself: the README describes what the controller reflects and how to deploy it, but it does not spell out how a secret opts into mirroring, so confirm the opt-in mechanism and its precedence rules against the upstream docs for the version you pin.
Frequently asked questions
What does the Reflector controller do in Kubernetes?
It monitors changes to secrets and configmaps and reflects those changes into mirror resources in the same namespace or in other namespaces, so pods in a namespace that cannot mount the original can consume a copy.
How do I install Reflector with Helm?
Use `helm upgrade --install reflector oci://ghcr.io/emberstack/helm-charts/reflector`, or add the repository with `helm repo add emberstack https://emberstack.github.io/helm-charts` and install from `emberstack/reflector`. Kubernetes 1.22 or newer and Helm 3.8 or newer are required.
Which architectures does the Reflector image support?
The README states that Reflector supports `amd64`, `arm` and `arm64`. Images are published at `emberstack/kubernetes-reflector` on Docker Hub, with `ghcr.io/emberstack/kubernetes-reflector` available as an alternative repository.
Can Reflector be told to ignore namespaces?
Yes, through `configuration.watcher.excludedNamespaces`, which takes a comma-separated list of namespace glob patterns supporting `*` for any characters and `?` for a single character, for example `ephie-*,kube-system,*-temp`. It has no default.
Is Reflector a replacement for cert-manager or External Secrets?
No. Reflector replicates resources that already exist inside one cluster; it does not issue, renew or fetch them. The README also does not describe replication across clusters, so a multi-cluster deployment needs a separate source of truth.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/emberstack-kubernetes-reflector)Star history chart for your README
[](https://hysenlabs.com/projects/emberstack-kubernetes-reflector)Was this useful?