-
Notifications
You must be signed in to change notification settings - Fork 614
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RFC-0002] Access control for cross-namespace source refs
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
- Loading branch information
1 parent
aed7341
commit 1588bab
Showing
1 changed file
with
157 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
# RFC-0002 Access control for source references | ||
|
||
## Summary | ||
|
||
Cross-namespace references to Flux sources should be subject to | ||
Access Control Lists (ACLs) as defined by the owner of a particular source. | ||
|
||
## Motivation | ||
|
||
As of v0.23.0, Flux allows for `Kustomizations` and `HelmReleases` to reference sources in different namespaces. | ||
This poses a serious security risk for multi-tenant environments as Flux does not prevent tenants from accessing | ||
known sources outside of their namespaces. | ||
|
||
Flux does not allow for an `ImageUpdateAutomation` to reference a `GitRepository` in a different namespace. | ||
This means users have to copy the Git auth secret and the `GitRepository` object in all namespaces | ||
where `ImageUpdateAutomations` are used. This poses a serious security risk for multi-tenant environments, | ||
as tenants could use the Git secret to push changes to repositories by impersonating Flux. | ||
|
||
Flux allows for `ImagePolicies` to reference `ImageRepositories` in a different namespace only | ||
if the ACL present on the `ImageRepository` grants access to the namespace where the `ImagePolicy` is. | ||
This has been implemented in | ||
[fluxcd/image-reflector-controller#162](https://github.com/fluxcd/image-reflector-controller/pull/162). | ||
|
||
Flux should be consistent when dealing with cross-namespace references by extending the | ||
Image Policy/Repository approach to all the other APIs. | ||
|
||
### 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`) | ||
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 | ||
|
||
### User Stories | ||
|
||
#### Story 1 | ||
|
||
> 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://git@github.com/<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, | ||
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://git@github.com/<org>/cluster-config | ||
secretRef: | ||
name: read-write-ssh-key | ||
accessFrom: | ||
namespaceSelectors: | ||
- matchLabels: | ||
kubernetes.io/metadata.name: dev-team1 | ||
``` | ||
|
||
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 | ||
|
||
An alternative solution to source ACLs is showcased in the current multi-tenancy example, where an | ||
admission controller such as Kyverno or OPA Gatekeeper is used to block cross-namespace access to sources. | ||
|
||
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). | ||
|
||
Yes 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). | ||
|
||
And finally, this is more of an improvement of the current proposal, is for source-controller to compile the ACLs | ||
to Kubernetes RBAC and dynamically create `ClusterRoleBindings` for all tenants accounts | ||
every time a source or namespace changes as described in | ||
[fluxcd/flux2#582-821388906](https://github.com/fluxcd/flux2/pull/582#issuecomment-821388906). | ||
|
||
## Implementation History | ||
|
||
- ACL support for allowing cross-namespace access to `ImageRepositories` was first released in flux2 **v0.23.0**. |