gatekeeper icon indicating copy to clipboard operation
gatekeeper copied to clipboard

Enabled access to UserInfo Struct from Mutation Assign

Open fbalicchia opened this issue 4 years ago • 6 comments

The goal of this issue is to lay the groundwork for a possible extension about Mutation verb: Assign.

As system integration can be useful to use requesting user structure in our mutation phase.

For example when creating a Pod that has a particular label, I can add a sidecar that intercept the request and that be enriched  with requesting users for ulterior authorization. 

apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
  name: assign-sidecar-example
spec:
  applyTo:
    - groups: [""]
      kinds: ["Pod"]
      versions: ["v1"]
  match:
    scope: ""
    excludeNamespaces: ["kube-system"]
  location: "spec.containers[name:oauth]"
  parameters:
   assign:
      value:
        name: "oauth"
        image: "busybox"
        command: ["/bin/sh"]
        args: ["-c", "while true; do echo echo $(date -u) 'Hi I am from Sidecar container 1' >> /tmp/index.html; sleep 5;done"]
        env:
          - name: USERNAME
            value: "req.AdmissionRequest.UserInfo.Username"
          - name: GROUPS
            value: "req.AdmissionRequest.UserInfo.Groups"

Honestly I didn't dig a lot in code than I don't know how difficult or easy to do this feature I'll check better soon

fbalicchia avatar Feb 11 '21 08:02 fbalicchia

There are definitely some caveats around the ability to reference dynamic data during mutation. One way this can go wrong is described in the The ability to reference mutable data section of the mutation dynamics document.

That being said user info is theoretically safe WRT convergence within a request as the username is static. Where we start hitting problems is when we think about the life of the resource over time. Two big questions:

  • What happens when a controller touches the resource? Should the value be replaced by the controller's service account? What about a second user?

If you just want the ID of the original creator, this is trivial, but the rules can get more complex from there.

  • What do we do about other contexts where user ID might not be available?

For instance, mmirecki@ and fpaoline@ have a design for insistent reconciliation, where objects at rest on the cluster are proactively coerced to conform to the mutation output. Since this would be done outside of an admission control context, the user name would not be available.

This same issue may also occur if the mutation code is ported to work in a CI/CD pipeline.

maxsmythe avatar Feb 12 '21 03:02 maxsmythe

Thanks a lot for link and your observations, I'll tried to respond to your questions

  • What happens when a controller touches the resource ? Webhook will listen only to CREATE Pods request and add sidecar if no container with particular pod already exists propagating userInfo is capability is enabled

  • Should the value be replaced by the controller's service account? What about a second user? The case that I've in my mind is that the api server is  behind a system like kube-oidc-proxy than in that case the user arrives from OIDC Provider or with a serviceaccount.

  • What do we do about other contexts where user ID might not be available? Probably is too much simplistic but in that case UserInfo propagation capability is enabled and missing system userinfo raise an error.

Reading the core design goal AFAIK I don't know if this request can generalized enough to be shared among the community.

fbalicchia avatar Feb 13 '21 19:02 fbalicchia

It sounds like the "only on create" aspect of this can be achieved by only setting the field if it is unset. I'm not sure if this always generalizes, but it seems like a good starting point.

WRT other contexts... this is the hardest issue IMO. I'm not sure what a good way forward here would be. I think the basic expectation is that if I apply a mutation system during a precommit pipeline and as a K8s admission controller, then I should see the same result either way. This doesn't seem achievable if we rely on data that exists in one context but not the other, but maybe there are ways to justify relaxing this assumption?

maxsmythe avatar Feb 17 '21 04:02 maxsmythe

Username is available through externaldata today: https://open-policy-agent.github.io/gatekeeper/website/docs/externaldata#api

If there's interest, we can add to core mutation to retrieve username

sozercan avatar Jul 13 '22 21:07 sozercan

Username is available through externaldata today: https://open-policy-agent.github.io/gatekeeper/website/docs/externaldata#api

If there's interest, we can add to core mutation to retrieve username

@sozercan please implement it without asking :) Always good to implement new features :)

abdennour avatar Jun 30 '23 15:06 abdennour

Any updates or any potential workaround?

adabuleanu avatar Dec 14 '23 16:12 adabuleanu