-
Notifications
You must be signed in to change notification settings - Fork 602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Access control for cross-namespace source refs #2092
Changes from all commits
a46f4e3
43372a9
e5635d0
c312816
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
# RFC-0002 Access control for source references | ||
|
||
**Status:** provisional | ||
|
||
**Creation date:** 2021-11-16 | ||
|
||
**Last update:** 2022-02-03 | ||
|
||
## Summary | ||
|
||
Cross-namespace references to Flux sources should be subject to | ||
Access Control Lists (ACLs) as defined by the owner of a particular source. | ||
|
||
Similar to [Kubernetes Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/), | ||
Flux ACLs define policies for restricting the access to the source artifact server based on the | ||
caller's namespace. | ||
|
||
## Motivation | ||
|
||
As of [version 0.26](https://github.com/fluxcd/flux2/releases/tag/v0.26.0) (Feb 2022), | ||
Flux allows for `Kustomizations`, `HelmReleases` and `ImageUpdateAutomations` to reference sources in different namespaces. | ||
On multi-tenant clusters, platform admins can disable this behaviour with the `--no-cross-namespace-refs` flag | ||
as described in the [multi-tenancy lockdown documentation](https://fluxcd.io/docs/installation/#multi-tenancy-lockdown). | ||
|
||
This proposal tries to solve the "cross-namespace references side-step namespace isolation" issue (explained in | ||
[RFC-0001](https://github.com/fluxcd/flux2/tree/main/rfcs/0001-authorization#cross-namespace-references-side-step-namespace-isolation)) | ||
for when platform admins want to allow tenants to share sources. | ||
|
||
### Goals | ||
|
||
- Allow source owners to choose which sources are shared and with which namespaces. | ||
- Allow cluster admins to enforce source ACLs. | ||
|
||
### Non-Goals | ||
|
||
- Enforce source ACLs by default. | ||
|
||
## Proposal | ||
|
||
Extend the current Image Policy/Repository ACL implementation to all the others Flux resources | ||
as described in [flux2#1704](https://github.com/fluxcd/flux2/issues/1704). | ||
|
||
When a Flux resource (`Kustomization`, `HelmRelease` or `ImageUpdateAutomation`) | ||
stefanprodan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
refers to a source (`GitRepository`, `HelmRepository` or `Bucket`) in a different namespace, | ||
access is granted based on the source ACL. | ||
|
||
The ACL check is performed only if `--enable-source-acl` flag is set to `true` for the following controllers: | ||
|
||
- kustomize-controller | ||
- helm-controller | ||
- image-automation-controller | ||
makkes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### User Stories | ||
|
||
#### Story 1 | ||
stefanprodan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
> As a cluster admin, I want to share Helm Repositories approved by the platform team with all tenants. | ||
|
||
If the owner of a Flux `HelmRepository` wants to grant access to the repository for all namespaces in a cluster, | ||
an empty `matchLabels` can be used: | ||
|
||
```yaml | ||
apiVersion: source.toolkit.fluxcd.io/v1beta1 | ||
kind: HelmRepository | ||
metadata: | ||
name: bitnami | ||
namespace: flux-system | ||
spec: | ||
url: https://charts.bitnami.com/bitnami | ||
accessFrom: | ||
namespaceSelectors: | ||
- matchLabels: {} | ||
``` | ||
|
||
If the `accessFrom` field is not present and `--enable-source-acl` is set to `true`, | ||
means that a source can't be accessed from any other namespace but the one where it currently resides. | ||
|
||
#### Story 2 | ||
|
||
> As a tenant, I want to share my app repository with another tenant | ||
> so that they can deploy the application in their own namespace. | ||
|
||
If `dev-team1` wants to grant read access to their repository to `dev-team2`, | ||
a `matchLabels` that selects the namespace owned by `dev-team2` can be used: | ||
|
||
```yaml | ||
apiVersion: source.toolkit.fluxcd.io/v1beta1 | ||
kind: GitRepository | ||
metadata: | ||
name: app1 | ||
namespace: dev-team1 | ||
spec: | ||
url: ssh://[email protected]/<org>/app1-deploy | ||
secretRef: | ||
name: app1-ro-ssh-key | ||
accessFrom: | ||
namespaceSelectors: | ||
- matchLabels: | ||
kubernetes.io/metadata.name: dev-team2 | ||
``` | ||
|
||
#### Story 3 | ||
|
||
> As a cluster admin, I want to let tenants configure image automation in their namespaces by | ||
> referring to a Git repository managed by the platform team. | ||
|
||
If the owner of a Flux `GitRepository` wants to grant write access to `ImageUpdateAutomations` in a different namespace, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be good to lay out the list of possible access... If as a user I grant access to another namespace, depending on the running controllers on that NS I might re-consider. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The level of access to the underlying Git repository depends on how you've configured the SSH key or token, if it has write access to just read. |
||
a `matchLabels` that selects the image automation namespace can be used: | ||
|
||
```yaml | ||
apiVersion: source.toolkit.fluxcd.io/v1beta1 | ||
kind: GitRepository | ||
metadata: | ||
name: cluster-config | ||
namespace: flux-system | ||
spec: | ||
url: ssh://[email protected]/<org>/cluster-config | ||
secretRef: | ||
name: read-write-ssh-key | ||
accessFrom: | ||
namespaceSelectors: | ||
- matchLabels: | ||
kubernetes.io/metadata.name: dev-team1 | ||
Comment on lines
+120
to
+123
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This pattern is very flexible for resource discovery and I can easily understand the benefits of using it in this use case. The main challenge I can think of using this as part of flux's authorisation model in addition to the built-in RBAC is that a cluster admin who is unaware of flux's inner workings may be blindsided by this behaviour, leading to less secure flux deployments. Given that RBAC will stop being the single source of truth from an authorisation perspective, it may be useful to also provide a sub-command on |
||
``` | ||
|
||
The `dev-team1` can refer to the `cluster-config` repository in their image automation config: | ||
|
||
```yaml | ||
apiVersion: image.toolkit.fluxcd.io/v1beta1 | ||
kind: ImageUpdateAutomation | ||
metadata: | ||
name: app1 | ||
namespace: dev-team1 | ||
spec: | ||
sourceRef: | ||
kind: GitRepository | ||
name: cluster-config | ||
namespace: flux-system | ||
``` | ||
|
||
### Alternatives | ||
stefanprodan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
#### Admission controllers | ||
|
||
An alternative solution to source ACLs is to use an admission controller such as Kyverno or OPA Gatekeeper | ||
and allow/disallow cross-namespace access to specific source. | ||
|
||
The current proposal offers the same feature but without the need to manage yet another controller to guard | ||
sources. | ||
|
||
#### Kubernetes RBAC | ||
|
||
Another alternative is to rely on impersonation and create a `ClusterRoleBinding` per named source and tenant account | ||
as described in [fluxcd/flux2#582](https://github.com/fluxcd/flux2/pull/582). | ||
|
||
The current proposal is more flexible than RBAC and implies less work for Flux users. ALCs act more like | ||
Kubernetes Network Policies where access is defined based on labels, with RBAC every time a namespace is added, | ||
the platform admins have to create new RBAC rules to target that namespace. | ||
|
||
#### Source reflection CRD | ||
|
||
Yet another alternative is to introduce a new API kind `SourceReflection` as described in | ||
[fluxcd/flux2#582-821027543](https://github.com/fluxcd/flux2/pull/582#issuecomment-821027543). | ||
|
||
The current proposal allows the owner to define the access control list on the source object, instead | ||
of creating objects in namespaces where it has no control over. | ||
|
||
#### Remove cross-namespace refs | ||
|
||
An alternative is to simply remove cross-namespace references from the Flux API. | ||
|
||
This would break with current behavior, and users would have to make substantial changes to their | ||
repository structure and workflow. In cases where e.g. a resource is common (across many namespaces), | ||
this would mean the source-controller would use way more memory and network bandwidth that grows with | ||
each namespace that uses the same Git or Helm repository due to the requirement of having to duplicate | ||
"common" resources. | ||
|
||
## Implementation History | ||
|
||
- ACL support for allowing cross-namespace access to `ImageRepositories` was first released in flux2 **v0.23.0**. | ||
- Disabling cross-namespace access to sources was first released in flux2 **v0.26.0**. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will maintain backwards compatibility as far as I understand. Let's be explicit about that here, too: This RFC doesn't introduce backwards-incompatible changes.