Skip to content
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

Enrich the PSP templates with template and field-level descriptions #109

Merged

Conversation

julianKatz
Copy link
Contributor

No description provided.

Copy link
Contributor

@maxsmythe maxsmythe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added some starting comments, but couldn't get through the whole thing yet

library/pod-security-policy/apparmor/template.yaml Outdated Show resolved Hide resolved
library/pod-security-policy/capabilities/template.yaml Outdated Show resolved Hide resolved
@@ -3,7 +3,7 @@ kind: ConstraintTemplate
metadata:
name: k8spspfsgroup
annotations:
description: Controls allocating an FSGroup that owns the Pod's volumes.
description: "Controls allocating an FSGroup that owns the Pod's volumes. Corresponds to the `fsGroup` field in a PodSecurityPolicy."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish there could be an "extended discription", so we can have a blurb and then more detailed instructions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea I was thinking about that. Particularly something that would allow for some nice markdown syntax.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, interesting to think how it would interact with shorter descriptions and examples...

File an issue for a feature request?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this feature request go? Isn't this part of JSONSchema? Or are you talking about extended description for the whole resource? Couldn't we just add another annotation for that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second (another annotation), just an FR against the library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue created: #112

items:
type: object
properties:
readOnly:
type: boolean
description: "when set to true, will allow host volumes matching the pathPrefix only if all volume mounts are readOnly."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all volume mounts or all matching volume mounts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, hilariously, I copied this from the k8s libraries themselves.

all volume mounts or all matching volume mounts?

So this would be all of the volume mounts that match that prefix. So, if you had another allowed prefix with readOnly: false the mounts matching that prefix would not be required to be readOnly.


Another version of that description could be:

When set to true, all mounts covered by the pathPrefix must be mounted readOnly.

Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, def. don't just use PSP words:

  1. Because we should at least cite them if we do
  2. Because the Rego may not be written exactly like the PSP Go code... particularly if the behavior isn't documented as part of the API

Looking at the template, here's what it seems like is happening:

  • It's possible to use paths on the host node as volumes that can be mounted to the pods (spec.volumes)
    • in order to do this, you must specify that the volume is a host path type, and which host path you want to use as a volume, this path is what pathPrefix matches against
  • A volume can be mounted to one or more paths in the pod
    • Each volume mount must reference a volume defined in spec.volumes
    • Each volume mount specifies where that volume gets mounted inside the pod (this value is not checked)
    • Each volume mount can be mounted as read only

It appears that the readOnly parameter allows users to say "for every volume mount that references this volume must mount it as read only"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about:

when set to true, any container volumeMounts matching the pathPrefix must include `readOnly: true`

Copy link
Contributor

@maxsmythe maxsmythe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finished the review, added some more comments.

@@ -3,7 +3,7 @@ kind: ConstraintTemplate
metadata:
name: k8spspselinuxv2
annotations:
description: Controls the SELinux context of the container.
description: "Defines an allow-list of seLinuxOptions configurations for pod containers. Corresponds to a PodSecurityPolicy with SELinux rule `MustRunAs` enabled and specific `seLinuxOptions` specified."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make these longer descriptions multi-lined via the | operator (like the rego field below). This should help readability for people using vim (or GitHub code review)

WRT text...

"and specific seLinuxOptions specified."

"specific" isn't very descriptive. Do you mean the options as provided to the parameters of the CT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will change all of the templates to use the | operator. It's definitely cleaner and more readable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r.e. "specific, the idea I'm going for is the following:

If you use this template, you configure at least one set of seLinuxOptions that is defined as a legal configuration of options for a container to run with. Were you to apply a container with a different set of Linux Options, that container would be rejected by g8r.

To achieve the same effect with a PSP, you'd have to create an seLinux entry with rule MustRunAs and the specific set of allowed SELinux options included under it. That would look like:

spec:
  seLinux:
    rule: RunAsAny
    seLinuxOptions:
      [values]

So I'm really just trying to say that you'd have to configure that field with some specific values of your choosing. So I'm not being particularly specific when I say specific. I'm just trying to say that you have to configure.

How could I say it better?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I forgot about is newlines... I think > is the correct character if you want to have newlines for readability but not for content:

https://yaml.org/spec/1.2.1/#style/block/folded

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: specific... TBH I wouldn't mention it. It's enough to say that it is "requiring SELinux configs"

Referencing the PSP policy could be helpful for users already familiar with PSP, to help guide them when choosing replacement policies, but we shouldn't do it to the point where it confuses anyone unfamiliar with PSP and reading the docs for the first time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying I should get rid of the "Corresponds to a PodSecurityPolicy" parts of all the descriptions? @mkorfgoogle told me he liked those.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, newest version:

      Defines an allow-list of seLinuxOptions configurations for pod
      containers.  Corresponds to a PodSecurityPolicy requiring SELinux configs.

library/pod-security-policy/users/template.yaml Outdated Show resolved Hide resolved
properties:
min:
type: integer
max:
type: integer
supplementalGroups:
type: object
description: "Controls which groups are applied to the first process run in any pod container, in addition to the container's primary GID."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we're calling out the "first process"?

Copy link
Contributor Author

@julianKatz julianKatz Sep 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess "main process" would be a better way to describe this.

I adapted this from the kubernetes core code.

My understanding is that other processes are forked off of that first process, so they can only have groups that it would have? Is that right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please reword anything inspired from others' work.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I do like "main process" better. You can do escalation via methods like su, so it's not strictly true that it's an inheritance tree, but I do think that's the default behavior.

Copy link
Contributor Author

@julianKatz julianKatz Sep 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New version:

description: "Controls which additional groups are applied to a pod container's main process beyond its primary GID."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reading other comments, I think it's better to go a simpler route, where we don't try to teach the feature in the CT. Rather, we should say specifically what policy the CT enforces and no more.

properties:
min:
type: integer
max:
type: integer
fsGroup:
type: object
description: "Controls the supplemental group applied to some volumes."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"some volumes": which volumes?

Copy link
Contributor Author

@julianKatz julianKatz Sep 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also adapted from k8s docs.

Based on this blogpost and these docs, it looks like it sets both the volume mounted to the contianer AND any files created within it by the Pod containers have this GID.

This is complicated, and I'm not sure how to think about ROI on figuring out how it works in detail. Is there something that's kind of vague but not wrong that we could say? It seems like the k8s docs punted as well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please reword anything inspired from others' work.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we should be documenting these things based of the Rego written, for accuracy.

Finally, I'm asking "which volumes", because as a user, that would be my first question when I read something like "some volumes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you make a good point in another comment that we shouldn't try to teach people these features, but rather how to restrict them via the CT.

That being said, I think it makes sense to change the descriptions in this CT to things like:

fsGroup:
  type: object
  description: "Controls the fsGroup values allowed in a Pod or container level SecurityContext."

This is simpler and is actually what we validate in the rego.

Going to go ahead and change these, let me know if I should revert.

library/pod-security-policy/volumes/template.yaml Outdated Show resolved Hide resolved
@julianKatz julianKatz force-pushed the psp-field-descriptions branch 2 times, most recently from 0c8328b to 63a047c Compare September 16, 2021 22:48
Copy link
Contributor

@maxsmythe maxsmythe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a few nits!

library/pod-security-policy/users/template.yaml Outdated Show resolved Hide resolved
description: Controls restricting escalation to root privileges.
description: >-
Controls restricting escalation to root privileges. Corresponds to the
`allowPrivilegeEscalation` field in a PodSecurityPolicy.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about using fully-qualified paths in comments? My preference is to use the longer ones to make the structure clearer to the people consuming the templates.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For PSP specifically, the main purpose is to provide guidance for people who are referencing the PSP fields/ documentation.

The PSP documentation references its fields by non-fully-qualified name:

https://kubernetes.io/docs/concepts/policy/pod-security-policy/

So we should follow their conventions.

Since PSP is deprecated, we may choose to remove these references entirely once most/all users are no longer in a transitional phase.

If we are talking about related fields within the same constraint template, that seems reasonable to me, though I'd be a bit concerned about verbosity. Maybe make all paths relative to parameters?

Copy link
Contributor Author

@julianKatz julianKatz Sep 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @willbeason is talking about saying:

Corresponds to the `spec.allowPrivilegeEscalation` field in a PodSecurityPolicy

in the description.

Personally, I'm down either way. My first move when using a PSP Constraint Template would be to look at an example PSP, so the full paths wouldn't be a huge difference maker (they're basically all spec.[fieldname]). That said, adding them requires little effort so I'm happy to do so if you feel strongly @willbeason . Are you against this, @maxsmythe ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I lean more towards matching the PSP docs (meaning what's written is fine as-is)

library/pod-security-policy/selinux/template.yaml Outdated Show resolved Hide resolved
Signed-off-by: juliankatz <juliankatz@google.com>
@julianKatz julianKatz force-pushed the psp-field-descriptions branch from dcdd096 to 8dad32d Compare September 28, 2021 02:22
Signed-off-by: juliankatz <juliankatz@google.com>
@julianKatz julianKatz changed the title First stab at field descriptions for the PSP templates Enrich the PSP templates with template and field-level descriptions Sep 28, 2021
…ary into psp-field-descriptions

Signed-off-by: juliankatz <juliankatz@google.com>
…ileged-containers

Signed-off-by: juliankatz <juliankatz@google.com>
Copy link
Member

@sozercan sozercan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@julianKatz julianKatz merged commit 8be1fcf into open-policy-agent:master Oct 6, 2021
@julianKatz julianKatz deleted the psp-field-descriptions branch October 6, 2021 18:27
mvanholsteijn pushed a commit to binxio/gatekeeper-library that referenced this pull request Oct 14, 2021
…pen-policy-agent#109)

Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: Mark van Holsteijn <mark.van.holsteijn@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants