kcp-dev / kcp

Kubernetes-like control planes for form-factors and use-cases beyond Kubernetes and container workloads.
https://kcp.io
Apache License 2.0
2.37k stars 382 forks source link

feature: support access reviews through virtual workspaces #1922

Open astefanutti opened 2 years ago

astefanutti commented 2 years ago

Describe the bug

Trying to add permission claims for authorization.k8s.io/selfsubjectaccessreviews or authorization.k8s.io/selfsubjectrulesreviews fail, with the APIBinding reporting the following PermissionClaimsApplied condition:

  message: 'Permission claims have not been fully applied: [error getting informer
      for group="authorization.k8s.io", resource="selfsubjectaccessreviews": unable
      to find informer for authorization.k8s.io.selfsubjectaccessreviews, error getting
      informer for group="authorization.k8s.io", resource="selfsubjectrulesreviews":
      unable to find informer for authorization.k8s.io.selfsubjectrulesreviews]'
  reason: InternalError
  severity: Error
  status: "False"
  type: PermissionClaimsApplied

The use case is to have a controller / operator capable of performing SAR (resp. SRR) requests via an APIExport VW URL. It fails because the authorization.k8s.io/selfsubjectaccessreviews (resp. authorization.k8s.io/selfsubjectrulesreviews) API is not present.

Steps To Reproduce

Create an APIExport with:

apiVersion: apis.kcp.dev/v1alpha1
kind: APIExport
spec:
  permissionClaims:
    - group: "authorization.k8s.io"
      resource: "selfsubjectrulesreviews"
      identityHash: ...
    - group: "authorization.k8s.io"
      resource: "selfsubjectaccessreviews"
      identityHash: ...

And an APIBinding with:

apiVersion: apis.kcp.dev/v1alpha1
kind: APIBinding
spec:
  reference:
    workspace:
      path: ...
      exportName: ...
  permissionClaims:
    - group: "authorization.k8s.io"
      resource: "selfsubjectrulesreviews"
      identityHash: ...
      state: "Accepted"
    - group: "authorization.k8s.io"
      resource: "selfsubjectaccessreviews"
      identityHash: ...
      state: "Accepted"

Expected Behaviour

It should be possible to claim permissions on SAR and SRR resources.

Additional Context

It seems the permissionclaimlabel controller lists claimed resources to apply a label. However SAR, nor SRR, resources cannot be listed, as they only support the create operation.

ncdc commented 2 years ago

It's because the controller uses the dynamic discovery shared informer factory to get an informer, and that only supports a specific list of built-in types (those that support list+watch) - https://github.com/kcp-dev/kcp/blob/e14b8caeb0fb2f693cc33b362a83feb53c1ff0f7/pkg/informer/informer.go#L389-L414

IF we wanted to support claiming types like this, we need to make some adjustments so

  1. we don't try to label these resources (that don't support list+watch)
  2. we hard-code support for them in the apiexport virtual workspace code that processes claimed resources

Otherwise, we need to reject claiming them or at least not make it an error

sttts commented 2 years ago

I don't think these resources should be claimable. It is not clear to me what the semantics would even be.

stevekuznetsov commented 2 years ago

Multi-faceted controllers in k8s today may use SSR to determine which parts of their functionality are turned on - what might be analogous in our case to a specific permission claim being accepted or not. How will they do this flow in kcp?

ncdc commented 2 years ago

We could enable them by default instead of requiring a claim

astefanutti commented 2 years ago

Multi-faceted controllers in k8s today may use SSR to determine which parts of their functionality are turned on - what might be analogous in our case to a specific permission claim being accepted or not. How will they do this flow in kcp?

This 😃!

stevekuznetsov commented 2 years ago

@ncdc that does seem reasonable to me - it's not clear that access to these read-only virtual resources is similar in any way to what PermissionClaims are doing, which is allowing the user a level of control over their own data. Users don't "own" SAR responses in their workspaces.

ncdc commented 2 years ago

Exactly, they're built-in APIs that everyone should be able to use

astefanutti commented 2 years ago

I've amended the description with the above. as I realise I forgot to mention the original use case:

The use case is to have a controller / operator capable of performing SAR (resp. SRR) requests via an APIExport VW URL. It currently fails because the authorization.k8s.io/selfsubjectaccessreviews (resp. authorization.k8s.io/selfsubjectrulesreviews) API is not present.

From that standpoint, whatever mechanism to achieve this is fine to me :)

ncdc commented 2 years ago

From community meeting discussion today: only allow SAR/SRR against resources the APIExport owns or claims

stevekuznetsov commented 2 years ago

@ncdc @sttts interesting questions coming from @alechenninger today - what does it meant to issue a SSR or SAR against a virtual workspace?

Precondition: if a controller/SA has some permission to do something through a virtual workspace, it does not mean they have permissions to do the same request "raw" against the underlying workspaces that the virtual workspace aggregates. In reality, it is almost always to my knowledge the opposite - the virtual workspace route is the only way that this actor would be authorized to make the action.

It seems obvious that if a controller were to issue a SSR in the context of a virtual workspace, then, that the response should tell the controller whether or not they would be authorized to make that request against the virtual workspace.

However, it seems entirely non-obvious how SAR should work - it also seems obvious that if the controller is submitting SAR for some other actor, they want to know if the actor has that permission in the context of the underlying workspace, since presumably there are few actors who have any access to the virtual workspace in the first place. So perhaps we'd say that SAR tells you about the permissions present in the underlying workspace? Is that a security hole? What if you submit a SAR with "yourself" as the subject?

alechenninger commented 2 years ago

Adding on some context for above in case it is helpful.

Hypothesis: If I'm an API provider (e.g. AcmeDB), and I want to let users manage RBAC for my service's (e.g. AcmeDB's) data plane connections & access, users will appreciate being able to manage that with k8s RBAC API and enjoy all the associated tooling, access control (to the RBAC itself), API familiarity, identities, etc, that comes with using k8s RBAC API.

That means possibly adding Roles about resources which aren't otherwise represented in the control plane (you don't see them in kubectl get). Maybe using RBAC like this is just a bad idea to begin, and if so that's useful feedback. But assuming it's not...

Problem: When users use my API, where does it (e.g. AcmeDB running on some other cluster controlled by Acme) issue a SAR to? The virtual workspace the APIExport controller uses? Or to the one of the many possible workspaces which have bound to/are using the control plane API (AcmeDB resources)?