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

Add disallow interactive tty constraint #305

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4fb9e23
Add a disallow interactive TTY constraint
Mar 20, 2023
f0dd4cd
Add source for disallow interactive
Mar 20, 2023
c8728c9
ci: remove skip for storage class (#300)
sozercan Mar 26, 2023
3e52793
fix: disallowed repos sample test name (#301)
sozercan Mar 26, 2023
05408fb
feat: add HorizontalPodAutoscaler policy (#235)
ctrought Mar 31, 2023
52fe3c3
fix: remove hardcoded kind from replicalimits msg (#309)
apeabody Apr 6, 2023
651c7c4
Run 'make generate generate-website-docs generate-artifacthub-artifacts'
Apr 6, 2023
c4a2a40
Run 'make generate generate-website-docs generate-artifacthub-artifac…
Apr 7, 2023
3085f8d
Revert "Run 'make generate generate-website-docs generate-artifacthub…
Apr 7, 2023
5d0c896
Revert "Run 'make generate generate-website-docs generate-artifacthub…
Apr 7, 2023
0547a50
Run 'make generate generate-website-docs generate-artifacthub-artifacts'
Apr 7, 2023
b2d9eb8
Fix missing libs
Apr 7, 2023
b42a989
Merge branch 'master' into add_disallow_interactive_tty_constraint
ritazh Apr 13, 2023
c7b3e61
Fix CI
Apr 27, 2023
489dc08
Merge branch 'add_disallow_interactive_tty_constraint' of github.com:…
Apr 27, 2023
0d62cc4
Merge branch 'open-policy-agent:master' into add_disallow_interactive…
tspearconquest Apr 27, 2023
9f2d113
Merge branch 'master' into add_disallow_interactive_tty_constraint
apeabody May 4, 2023
73dcffd
Merge branch 'master' into add_disallow_interactive_tty_constraint
apeabody May 15, 2023
6962979
Run make generate generate-website-docs generate-artifacthub-artifacts
May 22, 2023
6486a3e
Merge branch 'master' into add_disallow_interactive_tty_constraint
tspearconquest Jul 19, 2023
c0e1873
Merge branch 'master' into add_disallow_interactive_tty_constraint
tspearconquest Sep 19, 2023
7e14a37
Merge branch 'master' into add_disallow_interactive_tty_constraint
apeabody Sep 25, 2023
a7e7cc8
Merge branch 'master' into add_disallow_interactive_tty_constraint
apeabody Nov 27, 2023
317f82e
Merge branch 'master' into add_disallow_interactive_tty_constraint
tspearconquest Nov 27, 2023
56a24f7
Merge branch 'master' into add_disallow_interactive_tty_constraint
apeabody Dec 6, 2023
53a6534
Merge branch 'master' into add_disallow_interactive_tty_constraint
apeabody Dec 6, 2023
bdb4a90
Merge branch 'master' into add_disallow_interactive_tty_constraint
apeabody Dec 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: 1.0.0
name: k8sdisallowinteractivetty
displayName: Disallow Interactive TTY Containers
createdAt: "2023-04-27T21:41:24Z"
description: Requires that objects have the fields `spec.tty` and `spec.stdin` set to false or unset.
digest: c462c392ee271922f97e53d084646857dbbc97f496382e9b5c117532ccf3b5bc
license: Apache-2.0
homeURL: https://open-policy-agent.github.io/gatekeeper-library/website/disallowinteractive
keywords:
- gatekeeper
- open-policy-agent
- policies
readme: |-
# Disallow Interactive TTY Containers
Requires that objects have the fields `spec.tty` and `spec.stdin` set to false or unset.
install: |-
### Usage
```shell
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/artifacthub/library/general/disallowinteractive/1.0.0/template.yaml
```
provider:
name: Gatekeeper Library
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
resources:
- template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDisallowInteractiveTTY
metadata:
name: no-interactive-tty-containers
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-interactive-tty-allowed
labels:
app: nginx-interactive-tty
spec:
containers:
- name: nginx
image: nginx
stdin: false
tty: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-privilege-escalation-disallowed
labels:
app: nginx-privilege-escalation
spec:
containers:
- name: nginx
image: nginx
stdin: true
tty: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
kind: Suite
apiVersion: test.gatekeeper.sh/v1alpha1
metadata:
name: disallowinteractive
tests:
- name: disallow-interactive
template: template.yaml
constraint: samples/no-interactive-containers/constraint.yaml
cases:
- name: example-allowed
object: samples/no-interactive-containers/example_allowed.yaml
assertions:
- violations: no
- name: example-disallowed
object: samples/no-interactive-containers/example_disallowed.yaml
assertions:
- violations: yes
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sdisallowinteractivetty
annotations:
metadata.gatekeeper.sh/title: "Disallow Interactive TTY Containers"
metadata.gatekeeper.sh/version: 1.0.0
description: >-
Requires that objects have the fields `spec.tty` and `spec.stdin` set to false or unset.
spec:
crd:
spec:
names:
kind: K8sDisallowInteractiveTTY
validation:
# Schema for the `parameters` field
openAPIV3Schema:
type: object
description: >-
Controls use of fields related to gaining an interactive session. Corresponds to the `tty` and
`stdin` fields in the Pod `spec.containers`, `spec.ephemeralContainers`, and `spec.initContainers`.
properties:
exemptImages:
description: >-
Any container that uses an image that matches an entry in this list will be excluded
from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`.

It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name)
in order to avoid unexpectedly exempting images from an untrusted repository.
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sdisallowinteractivetty

import data.lib.exempt_container.is_exempt

violation[{"msg": msg, "details": {}}] {
c := input_containers[_]
not is_exempt(c)
input_allow_interactive_fields(c)
msg := sprintf("Containers using tty or stdin (%v) are not allowed running image: %v", [c.name, c.image])
}

input_allow_interactive_fields(c) {
has_field(c, "stdin")
not c.stdin == false
}
input_allow_interactive_fields(c) {
has_field(c, "tty")
not c.tty == false
}
input_containers[c] {
c := input.review.object.spec.containers[_]
}
input_containers[c] {
c := input.review.object.spec.ephemeralContainers[_]
}
input_containers[c] {
c := input.review.object.spec.initContainers[_]
}
# has_field returns whether an object has a field
has_field(object, field) = true {
object[field]
}
libs:
- |
package lib.exempt_container

is_exempt(container) {
exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", [])
img := container.image
exemption := exempt_images[_]
_matches_exemption(img, exemption)
}

_matches_exemption(img, exemption) {
not endswith(exemption, "*")
exemption == img
}

_matches_exemption(img, exemption) {
endswith(exemption, "*")
prefix := trim_suffix(exemption, "*")
startswith(img, prefix)
}
2 changes: 2 additions & 0 deletions library/general/disallowinteractive/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
resources:
- template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDisallowInteractiveTTY
metadata:
name: no-interactive-tty-containers
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-interactive-tty-allowed
labels:
app: nginx-interactive-tty
spec:
containers:
- name: nginx
image: nginx
stdin: false
tty: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx-privilege-escalation-disallowed
labels:
app: nginx-privilege-escalation
spec:
containers:
- name: nginx
image: nginx
stdin: true
tty: true
17 changes: 17 additions & 0 deletions library/general/disallowinteractive/suite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
kind: Suite
apiVersion: test.gatekeeper.sh/v1alpha1
metadata:
name: disallowinteractive
tests:
- name: disallow-interactive
template: template.yaml
constraint: samples/no-interactive-containers/constraint.yaml
cases:
- name: example-allowed
object: samples/no-interactive-containers/example_allowed.yaml
assertions:
- violations: no
- name: example-disallowed
object: samples/no-interactive-containers/example_disallowed.yaml
assertions:
- violations: yes
88 changes: 88 additions & 0 deletions library/general/disallowinteractive/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sdisallowinteractivetty
annotations:
metadata.gatekeeper.sh/title: "Disallow Interactive TTY Containers"
metadata.gatekeeper.sh/version: 1.0.0
description: >-
Requires that objects have the fields `spec.tty` and `spec.stdin` set to false or unset.
spec:
crd:
spec:
names:
kind: K8sDisallowInteractiveTTY
validation:
# Schema for the `parameters` field
openAPIV3Schema:
type: object
description: >-
Controls use of fields related to gaining an interactive session. Corresponds to the `tty` and
`stdin` fields in the Pod `spec.containers`, `spec.ephemeralContainers`, and `spec.initContainers`.
properties:
exemptImages:
description: >-
Any container that uses an image that matches an entry in this list will be excluded
from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`.

It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name)
in order to avoid unexpectedly exempting images from an untrusted repository.
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sdisallowinteractivetty

import data.lib.exempt_container.is_exempt

violation[{"msg": msg, "details": {}}] {
c := input_containers[_]
not is_exempt(c)
input_allow_interactive_fields(c)
msg := sprintf("Containers using tty or stdin (%v) are not allowed running image: %v", [c.name, c.image])
}

input_allow_interactive_fields(c) {
has_field(c, "stdin")
not c.stdin == false
}
input_allow_interactive_fields(c) {
has_field(c, "tty")
not c.tty == false
}
input_containers[c] {
c := input.review.object.spec.containers[_]
}
input_containers[c] {
c := input.review.object.spec.ephemeralContainers[_]
}
input_containers[c] {
c := input.review.object.spec.initContainers[_]
}
# has_field returns whether an object has a field
has_field(object, field) = true {
object[field]
}
libs:
- |
package lib.exempt_container

is_exempt(container) {
exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", [])
img := container.image
exemption := exempt_images[_]
_matches_exemption(img, exemption)
}

_matches_exemption(img, exemption) {
not endswith(exemption, "*")
exemption == img
}

_matches_exemption(img, exemption) {
endswith(exemption, "*")
prefix := trim_suffix(exemption, "*")
startswith(img, prefix)
}
7 changes: 4 additions & 3 deletions library/general/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ resources:
- containerlimits
- containerrequests
- containerresourceratios
- disallowedrepos
- containerresources
- disallowanonymous
- disallowedrepos
- disallowedtags
- disallowinteractive
- ephemeralstoragelimit
- externalip
- horizontalpodautoscaler
- httpsonly
Expand All @@ -26,6 +29,4 @@ resources:
- uniqueingresshost
- uniqueserviceselector
- verifydeprecatedapi
- containerresources
- storageclass
- ephemeralstoragelimit
39 changes: 39 additions & 0 deletions src/general/disallowinteractive/constraint.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8sdisallowinteractivetty
annotations:
metadata.gatekeeper.sh/title: "Disallow Interactive TTY Containers"
metadata.gatekeeper.sh/version: 1.0.0
description: >-
Requires that objects have the fields `spec.tty` and `spec.stdin` set to false or unset.
spec:
crd:
spec:
names:
kind: K8sDisallowInteractiveTTY
validation:
# Schema for the `parameters` field
openAPIV3Schema:
type: object
description: >-
Controls use of fields related to gaining an interactive session. Corresponds to the `tty` and
`stdin` fields in the Pod `spec.containers`, `spec.ephemeralContainers`, and `spec.initContainers`.
properties:
exemptImages:
description: >-
Any container that uses an image that matches an entry in this list will be excluded
from enforcement. Prefix-matching can be signified with `*`. For example: `my-image-*`.

It is recommended that users use the fully-qualified Docker image name (e.g. start with a domain name)
in order to avoid unexpectedly exempting images from an untrusted repository.
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
{{ file.Read "src/general/disallowinteractive/src.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }}
libs:
- |
{{ file.Read "src/general/disallowinteractive/lib_exempt_container.rego" | strings.Indent 8 | strings.TrimSuffix "\n" }}
19 changes: 19 additions & 0 deletions src/general/disallowinteractive/lib_exempt_container.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package lib.exempt_container

is_exempt(container) {
exempt_images := object.get(object.get(input, "parameters", {}), "exemptImages", [])
img := container.image
exemption := exempt_images[_]
_matches_exemption(img, exemption)
}

_matches_exemption(img, exemption) {
not endswith(exemption, "*")
exemption == img
}

_matches_exemption(img, exemption) {
endswith(exemption, "*")
prefix := trim_suffix(exemption, "*")
startswith(img, prefix)
}
Loading