docs(api): decline impersonation and shrink the source-scope surface, and decide where CRDs come from - #324
Conversation
… and decide where CRDs come from Two design decisions that ride the same breaking release as the GitTarget field move, kept out of the layout review because they are their own argument. **Source scope.** Declines the design review's proposal to adopt Flux-style service-account impersonation: it buys several identities behind one credential against one source cluster, which nobody has asked for. Deletes `GitTarget.spec.allowedSourceNamespaces` and its selector machinery on an API reading rather than a security one — the chain from a Git folder back to the object that fills it never leaves one namespace, so ordinary RBAC on `watchrules` already answers the destination question. The structural finding is that the complexity is in the matcher, not the fence: the selector half reads Namespace labels in another cluster, and that one choice produces the three-valued verdict, the SourceScopeUnavailable path, the five condition reasons and the cross-cluster Namespace watch. Measured at 4,569 lines. Keeps `allowedNamespaces` (renamed `accessFrom`), reversing an earlier draft: the permissive chart value covers the chart-owned `default` provider only, and source RBAC bounds what a credential may read, never which control-plane tenant may wield it. Redefines `sourceNamespace: "*"` as one cluster-wide list and watch, which is also the largest efficiency win here. Names what is lost: source-side label selectors, and a declared policy that can today deny a rule's own namespace. **CRD handling.** Where a mirrored folder's custom-resource definitions come from, given that a Widget cannot exist in a cluster that never heard of its CRD. Recommends default `None` with opt-in `Referenced` — a manifest of names, versions, sources and digests, never schemas — and `Vendored` as an escape hatch. Two verified facts carry it: Helm's ownership metadata survives sanitize, so a vendored CRD arrives in Git still claiming another cluster's release, while Flux's labels do not, so provenance must be captured live. Worked both ways in the crd-closure example. Also restores the source-scope member to the wave document: it is the only member that makes the API smaller, and TooManyStreams is sized by the `*` decision rather than by today's fan-out. Docs-only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Superseded by #325, which folds this work into a single PR on a smaller design: the two placement enums became two optional booleans ( |
Two design decisions that ride the same breaking release as the GitTarget field move, split out of the layout review because each is its own argument.
Source scope
Declines the design review's proposal to adopt Flux-style service-account impersonation: it buys several identities behind one credential against one source cluster, which nobody has asked for.
Deletes
GitTarget.spec.allowedSourceNamespacesand its selector machinery on an API reading rather than a security one —WatchRule.spec.targetRefandGitTarget.spec.providerRefare both local andspec.pathis immutable, so the chain from a Git folder back to the object that fills it never leaves one namespace, and ordinary RBAC onwatchrulesthere already answers the destination question.The structural finding: the complexity is in the matcher, not the fence.
NamespaceMatcher's selector half readsNamespacelabels in another cluster, and that one choice produces the three-valued verdict, theSourceScopeUnavailablepath, the five condition reasons and the cross-clusterNamespaceget/list/watch. Measured at 4,569 lines in files that exist for nothing else.Keeps
allowedNamespaces(renamedaccessFrom), reversing an earlier draft: the permissive chart value covers the chart-owneddefaultprovider only, so every user-authoredClusterProvideris still deny-by-default, and source RBAC bounds what a credential may read, never which control-plane tenant may wield it.Redefines
sourceNamespace: "*"as one cluster-wide list and watch — the largest efficiency win here — and names what is lost rather than claiming continuity: source-side label selectors, and a declared policy that can today deny a rule's own namespace.CRD handling
Where a mirrored folder's custom-resource definitions come from, given that a
Widgetcannot exist in a cluster that never heard of its CRD. Two consumers want different things: applicability wants the definition in the repository, while the per-branch editing cluster only needs it installable at spin-up, which a reference serves better than a copy.Recommends default
None, opt-inReferenced(names, versions, sources, digests — never schemas),Vendoredas an escape hatch. Two verified facts carry it: Helm'smeta.helm.sh/*ownership metadata survivessanitize, so a vendored CRD arrives in Git still claiming another cluster's release; Flux's labels do not, so provenance must be captured live. Worked both ways in thecrd-closureexample.Also
Restores the source-scope member to the wave document — the only member that makes the API smaller — and sizes
TooManyStreamsagainst the*decision rather than today's fan-out.Docs-only;
task lint-docspasses.🤖 Generated with Claude Code