feature: Specify Which Objects Of A Resource A PermissionClaim Applies To
Feature Description
Today, and API provider can only request permissions on all objects of a given GR. Similarly, the future reverse permission claims in #1840 will have the same limitation. We need to allow both of these mechanisms to select some small subset of objects.
Proposed Solution
As an API provider, I want to specify exactly which objects I need access to in a user's workspace, So that I can minimize my permissions footprint in their workspace
Alternative Solutions
No response
Want to contribute?
- [ ] I would like to work on this issue.
Additional Context
We need to do a user survey to determine the best approaches here. Obvious selection mechanisms are:
- object names
- label selectors (#2921)
- CEL or JSONPath
However, other options are also possible - "all Secrets that are mounted in a Pod" - but we need to understand better the use-cases of service providers to know if we need to provide those options. A minimal, extensible solution may suffice for this card.
A draft question for the survey:
If you are operating a service in a user's workspace, what access do you need to objects from other API objects?
For example, "I need to manage all
Deploymentsfor<label selector>and allSecretsmounted into pods forDeploymentsI create"
I think that covers what we're looking for, but before I send something out I'd like input from @sttts and @ncdc to see if there's anything else we should ask.
I need to manage secrets with tls secrets in them that are referenced from an ingress (they also share a label and annotations)
For the JVM build service we need to be able to
- Create a deployment with a specific name (this may be handled by an external service, although if we can have create/edit permission just for a single object that might give us a lot more flexibility and allow our operator to handle it rather than an external service)
- Some named config maps and secrets (ATM jvm-build-service-filter and jvm-build-secrets)
We also have some 'singleton' objects, where we expect only a single one to be present with a well known name (e.g. UserConfig), so it would be nice to be able to enforce this via permissions.
Our controller needs to create and update different kind of resources, like Ingress, Route, KnativeService, KEDA's ScaleObject etc., but should only be able to update / patch / delete these resources if it "owns" them.
These resources have one of our controller API resource in their owning references ancestors, so this would be a way to express the permission claim subset.
Two corollaries:
- This generalises to "grant update / patch / delete permissions to the resource creator", but that may be more difficult to express or implement (creator identity is not currently persisted);
- This could be approximated with label selectors.
Today, permission claims are API provider driven but there are cases where you want a mix of provider/consumer rules.
As example, an API provider can add a permission claim on secrets and eventually in the future, to some specific secrets i.e. by label selection or name however, it may be useful to let the consumer to define what secrets the service has access to so I would add to the Proposed Solutions something like:
As an API consumer, I want to specify exactly which objects the service provider
can access in my workspace,
So that I can minimize my permissions footprint in their workspace
Something like (pseudo yaml)
apiVersion: apis.kcp.dev/v1alpha1
kind: APIBinding
metadata:
name: camel-kcp
spec:
reference:
workspace:
path: root:camel-k:camel-kcp
exportName: camel-kcp
permissionClaims:
- group: ""
resource: "secrets"
selectors:
# access granted to any secret matching label selector
byLabel:
foo: bar
# access granted to any secret matching name
byName:
- mysecret
state: "Accepted"
This is particular useful for cross-workspace service where some resources are not created in the user namespace but may be projected from other services/workspaces/orgs.
An example you may have an "tenant admin" that provision a kafka instance and want to make it available to other people in the org hence, the CR is likely needed to be projected read only to other workspaces. I such case is is difficult for the tenant admin to define labels or names to make other services accessing the shared instance because the tenant admin is not aware of what other people would need/do. In such case, it would then be nice to make the service consumer be able to define the selector so it can allow access to resources not directly owned.
I just ran into into use case where I tried to automate SyncTarget rbac permissions models. And I have to specify this:
- group: ""
resource: "serviceaccounts"
all: true
Which would be very nice if I could:
- group: ""
resource: "serviceaccounts"
byPrefix:
- my-sync-target-sa-
This way for cases where I'm creator of the object and there is no selector I could limit the blast radius too. Maybe we can do regexp, as it would cover byName too on 1 field.
@mjudeikis Thanks - would using a label selector work for you in this case?
https://github.com/kcp-dev/kcp/pull/2456 covers explicitly listing namespaces/names, but label selectors will come later.
Adding regex/wildcards for namespaces/names is certainly doable, though I think it will be in a separate PR once this initial implementation is merged.