Skip to content

Commit

Permalink
Converted the policies to gatekeeper naming/structure (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
garethahealy authored Jul 16, 2020
1 parent 24f178f commit 5211f6e
Show file tree
Hide file tree
Showing 155 changed files with 6,400 additions and 4,289 deletions.
19 changes: 18 additions & 1 deletion .github/workflows/conftest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,25 @@ jobs:
- name: Checkout
uses: actions/checkout@v2

- name: Generate konstraint docs
uses: garethahealy/github-actions/confbatstest@conftest-raw
with:
raw: konstraint doc -o POLICIES.md

- name: Check if there are changes to POLICIES.md
id: changes
uses: UnicornGlobal/has-changes-action@master
with:
pathspec: POLICIES.md

- name: Fail if POLICIES.md changes found
if: steps.changes.outputs.changed == 1
run: |
echo "Uncommited changes to POLICIES.md exist. Failing."
exit 1
- name: Conftest
uses: redhat-cop/github-actions/confbatstest@master
with:
tests: _test/conftest.sh
tests: _test/conftest-unittests.sh
policies: '[{"name": "deprek8ion", "url":"github.com/swade1987/deprek8ion.git//policies"}]'
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ local.properties
*.iml

# BATS
test/test_helper/
test/test_helper/

## Gatekeeper
**/template.yaml
**/constraint.yaml
52 changes: 52 additions & 0 deletions POLICIES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Policies

|API Groups|Kinds|Description|
|---|---|---|
|apps, policy|Deployment, PodDisruptionBudget|violation: Check if a Deployment has a matching policy/v1beta1:PodDisruptionBudget, via 'spec.template.metadata.labels'|
|apps, core|Deployment, PersistentVolumeClaim|violation: Check if a Deployment has 'spec.template.spec.volumes.persistentVolumeClaim' set, there is a matching v1:PersistentVolumeClaim|
|apps, core|Deployment, Service|violation: Check if a Deployment has a matching v1:Service, via 'spec.template.metadata.labels'|
|apps, core|Deployment, ServiceAccount|violation: Check if a Deployment has 'spec.serviceAccountName' set, there is a matching v1:ServiceAccount|
|core, networking.k8s.io|Namespace, NetworkPolicy|violation: Check if a Namespace has a networking.k8s.io/v1:NetworkPolicy|
|core, monitoring.coreos.com|Service, ServiceMonitor|violation: Check if a Service has a matching monitoring.coreos.com/v1:ServiceMonitor, via 'spec.selector'|
|apps.openshift.io, apps, core, route.openshift.io|DeploymentConfig, DaemonSet, Deployment, StatefulSet, Service, Route|violation: Check if all workload related kinds contain labels as suggested by https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds have the CONTAINER_MAX_MEMORY env set using the downward api|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds are not using the latest tag for their image|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds do not set the Java Xmx option|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds have consistent key names for their labels|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds have not set their probes to be the same|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds have their liveness prob set|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds have their readiness prob set|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds do not set limits for CPU|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds limits for memory is not greater than an upper bound|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds has set their limits for memory|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds memory limits and requests unit is valid|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds cpu requests unit is valid|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds requests for memory is not greater than an upper bound|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds do not have secrets mounted as envs|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds have consistent paths for their volume mounts|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds does not specify a volume without a corresponding volume mount|
|apps.openshift.io|DeploymentConfig|violation: Check if a DeploymentConfig has 'spec.triggers' set|
|apps.openshift.io, apps|DeploymentConfig, DaemonSet, Deployment, StatefulSet|violation: Check workload kinds has 'spec.hostNetwork' set|
|apps.openshift.io, apps|DeploymentConfig, Deployment|violation: Check workload kinds has replicas <= 1|
|apps.openshift.io, apps|DeploymentConfig, Deployment|violation: Check workload kinds has replicas not odd|
|rbac.authorization.k8s.io|RoleBinding|violation: Check if a RoleBinding has 'roleRef.apiGroup' set|
|rbac.authorization.k8s.io|RoleBinding|violation: Check if a RoleBinding has 'roleRef.kind' set|
|v1|BuildConfig|violation: Check for deprecated v1 apiVersion. OCP4.x expects build.openshift.io/v1|
|v1|DeploymentConfig|violation: Check for deprecated v1 apiVersion. OCP4.x expects apps.openshift.io/v1|
|v1|ImageStream|violation: Check for deprecated v1 apiVersion. OCP4.x expects image.openshift.io/v1|
|v1|ProjectRequest|violation: Check for deprecated v1 apiVersion. OCP4.x expects project.openshift.io/v1|
|v1|RoleBinding|violation: Check for deprecated v1 apiVersion. OCP4.x expects rbac.authorization.k8s.io/v1|
|v1|Route|violation: Check for deprecated v1 apiVersion. OCP4.x expects route.openshift.io/v1|
|v1|SecurityContextConstraints|violation: Check for deprecated v1 apiVersion. OCP4.x expects security.openshift.io/v1|
|v1|Template|violation: Check for deprecated v1 apiVersion. OCP4.x expects template.openshift.io/v1|
|build.openshift.io|BuildConfig|violation: Check if 'exposeDockerSocket' is set on a BuildConfig. See: https://docs.openshift.com/container-platform/4.1/release_notes/ocp-4-1-release-notes.html#ocp-41-deprecated-features|
|authorization.openshift.io|ClusterRole, ClusterRoleBinding, Role, RoleBinding|violation: Check for deprecated authorization.openshift.io apiVersion. >= OCP4.2 expects rbac.authorization.k8s.io/v1. See: https://docs.openshift.com/container-platform/4.2/release_notes/ocp-4-2-release-notes.html#ocp-4-2-deprecated-features|
|automationbroker.io|Bundle, BundleBinding, BundleInstance|violation: Check for deprecated automationbroker.io/v1alpha1 apiVersion. See: https://docs.openshift.com/container-platform/4.2/release_notes/ocp-4-2-release-notes.html#ocp-4-2-deprecated-features|
|operators.coreos.com|CatalogSourceConfigs|violation: Check for deprecated operators.coreos.com/v1 apiVersion. See: https://docs.openshift.com/container-platform/4.2/release_notes/ocp-4-2-release-notes.html#ocp-4-2-deprecated-features|
|operators.coreos.com|CatalogSourceConfigs|violation: Check for deprecated operators.coreos.com/v2 apiVersion. See: https://docs.openshift.com/container-platform/4.2/release_notes/ocp-4-2-release-notes.html#ocp-4-2-deprecated-features|
|operators.coreos.com|OperatorSource|violation: Check for deprecated operators.coreos.com/v1 apiVersion. See: https://docs.openshift.com/container-platform/4.2/release_notes/ocp-4-2-release-notes.html#ocp-4-2-deprecated-features|
|osb.openshift.io|TemplateServiceBroker, AutomationBroker|violation: Check for deprecated osb.openshift.io/v1 apiVersion. See: https://docs.openshift.com/container-platform/4.2/release_notes/ocp-4-2-release-notes.html#ocp-4-2-deprecated-features|
|servicecatalog.k8s.io|ClusterServiceBroker, ClusterServiceClass, ClusterServicePlan, ServiceInstance, ServiceBinding|violation: Check for deprecated servicecatalog.k8s.io/v1beta1 apiVersion. See: https://docs.openshift.com/container-platform/4.2/release_notes/ocp-4-2-release-notes.html#ocp-4-2-deprecated-features|
|build.openshift.io|BuildConfig|violation: Check if 'jenkinsPipelineStrategy' is set on a BuildConfig. See: https://docs.openshift.com/container-platform/4.3/release_notes/ocp-4-3-release-notes.html#ocp-4-3-deprecated-features|
|redhat-cop.github.com|PodmanHistory|violation: Check the image contains a specific SHA in its history|
|redhat-cop.github.com|PodmanImages|violation: Check the image size is not greater than a specific value|
53 changes: 12 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,26 @@
![Validate](https://github.com/redhat-cop/rego-policies/workflows/Validate/badge.svg)

# rego-policies
[Rego](https://www.openpolicyagent.org/docs/latest/policy-language/) policies collection
[Rego](https://www.openpolicyagent.org/docs/latest/policy-language/) policies collection.

## Policies
Current policies in this repo are below. The naming of the policy files follows the below convention:
- {policy-type}-{platform}-{kind}-{other...}
For a full list of policies, see the auto-generated [POLICIES.md](/POLICIES.md)

### Deny Policies
- [deny-ocp42-all-deprecated-apiversions](policy/deny-ocp42-all-deprecated-apiversion.rego)
- [deny rules for OCP 4.2 apiVersion deprecations](https://docs.openshift.com/container-platform/4.2/release_notes/ocp-4-2-release-notes.html#ocp-4-2-deprecated-features)

- [deny-ocp43-all-deprecated-apiversions.rego](policy/deny-ocp43-all-deprecated-apiversions.rego)
- deny rules for OCP 4.3 apiVersion deprecations. Changing OCP specific kinds from v1 to *.openshift.io/v1

- [deny-k8s-rolebinding-roleref.rego](policy/deny-k8s-rolebinding-roleref.rego)
- deny rules to check roleRef.apiGroup and roleRef.kind for rbac.authorization.k8s.io/v1:RoleBinding are set, which were not required in OCP 3.x

### Warn Policies
- [warn-k8s-deployment-conftestcombine-bestpractices.rego](policy/warn-k8s-deployment-conftestcombine-bestpractices.rego)
- warn rules to check Deployments combined with other objects match; i.e.: Deployment -> Service selectors

- [warn-k8s-namespace-conftestcombine-bestpractices.rego](policy/warn-k8s-namespace-conftestcombine-bestpractices.rego)
- warn rules to check Namepaces combined with other objects match; i.e.: Namespace -> NetworkPolicy

- [warn-k8s-service-conftestcombine-bestpractices.rego](policy/warn-k8s-service-conftestcombine-bestpractices.rego)
- warn rules to check Services combined with other objects match; i.e.: Service -> ServiceMonitor

- [warn-k8s_ocp-all-bestpractices.rego](policy/warn-k8s_ocp-all-bestpractices.rego)
- warn rules to check all k8s objects - has a 'kind' and 'metadata.name'; i.e.: metadata.labels are set

- [warn-k8s_ocp-deployment_deploymentconfig-bestpractices.rego](policy/warn-k8s_ocp-deployment_deploymentconfig-bestpractices.rego)
- warn rules to check Deployment/DeploymentConfig conform to standard practices; i.e.: health-check probs are set

- [warn-ocp-deploymentconfig-bestpractices.rego](policy/warn-ocp-deploymentconfig-bestpractices.rego)
- warn rules to check DeploymentConfig conform to standard practices; i.e.: triggers are set

- [warn-podman-history-bestpractices.rego](policy/warn-podman-history-bestpractices.rego)
- warn rules to check a wrapped JSON output of "podman history"; i.e.: expected base layer is found.

- [warn-podman-images-bestpractices.rego](policy/warn-podman-images-bestpractices.rego)
- warn rules to check a wrapped JSON output of "podman images"; i.e.: check image size is within bounds.
The naming of the policies follows the Gatekeeper format, as described [here.](https://github.com/plexsystems/konstraint#how-template-and-constraint-naming-works)

## 3rd Party Policies
A list of git repos that contain rego polices which can be combined with this repo:
- [deprek8ion: Rego policies to monitor Kubernetes APIs deprecations](https://github.com/swade1987/deprek8ion)

## Conftest
## Tools
### Conftest
conftest is a CLI to execute rego policies. It can be used to test locally before pushing to [OPA](https://www.openpolicyagent.org/).
- [https://www.conftest.dev/install/]
- [https://www.conftest.dev/install](https://www.conftest.dev/install/)

## OPA Playground
### OPA Playground
OPA provides a web based playground, which can highlight which lines have been activated. Having issues with your policy? check it out with "Coverage" enabled:
- [https://play.openpolicyagent.org/]
- [https://play.openpolicyagent.org](https://play.openpolicyagent.org)

### Slack for all things
Stuck on a problem?
- [https://slack.openpolicyagent.org/](https://slack.openpolicyagent.org/)
31 changes: 20 additions & 11 deletions TESTING.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
# Testing
This repo uses as a combination of [bats](https://github.com/bats-core/bats-core) and [conftest](https://github.com/open-policy-agent/conftest)
to validate the rego policies.
This repo uses as a combination of [bats](https://github.com/bats-core/bats-core), [conftest](https://github.com/open-policy-agent/conftest) and
[gatekeeper](https://github.com/open-policy-agent/gatekeeper) to validate the rego policies.

## How do i write a test?
Each test is expected to have a directory under [_test](_test) which contains the test input data; typically a yaml file
containing a OCP Template or k8s List. Each block of YAML should match exactly 1 policy, due to the order of the failure output
which needs to be predictable for bats.
## How do I write a policy?
Each policy lives under its own directory, i.e.: [policy/ocp/bestpractices/common-k8s-labels-notset](policy/ocp/bestpractices/common-k8s-labels-notset).
Every policy must have a test_data directory; within that directory, there should be:
- unit: should contain only the YAML needed to execute the policy, i.e.: a cut down version
- integration: should contain valid YAML which can be deployed to a cluster which only triggers the policy under-test

The tests are executed by [_test/conftest.sh](_test/conftest.sh). The test should validate each expected bats output and always
end with the expected success line.
Each policy must have a BATS test executed by its usecase:
- unit test files will be executed by [_test/conftest-unittests.sh].
- integration test files will be executed by [_test/gatekeeper-integrationtests.sh].

## Execute Locally
## Execute unit tests
```bash
rm -rf /tmp/rego-policies; _test/conftest.sh
rm -rf /tmp/rhcop; bats _test/conftest-unittests.sh
```

## Execute integration units
```bash
_test/deploy-gatekeeper.sh
rm -rf /tmp/rhrepo; bats _test/gatekeeper-integrationtests.sh
```

## Tools used for testing
The following tools are required:
The following tools must be installed locally:

- [conftest](https://www.conftest.dev/install)
- [konstraint](https://github.com/plexsystems/konstraint#installation)
- [jq](https://stedolan.github.io/jq/download)
- [yq](https://pypi.org/project/yq)
140 changes: 140 additions & 0 deletions _test/all-namespaces/ocp/bestpractices/all.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
apiVersion: v1
kind: Template
metadata:
name: bar
objects:
- apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: Foo
app.kubernetes.io/instance: Bar
app.kubernetes.io/component: FooBar
app.kubernetes.io/part-of: Foo
app.kubernetes.io/managed-by: Bar
name: shouldneverfire${NAME}
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: Foo
app.kubernetes.io/instance: Bar
app.kubernetes.io/component: FooBar
app.kubernetes.io/part-of: Foo
app.kubernetes.io/managed-by: Bar
template:
metadata:
labels:
app.kubernetes.io/name: Foo
app.kubernetes.io/instance: Bar
app.kubernetes.io/component: FooBar
app.kubernetes.io/part-of: Foo
app.kubernetes.io/managed-by: Bar
spec:
containers:
- name: bar
image: quay.io/redhat-cop/openshift-applier@sha256:8a99a0105f85e350bff43802b204b5ce2a501cad1aa7df5253638ced1d108957
command: ["ansible-playbook"]
args: ["-i .applier/", "cluster-seed.yml"]
env:
- name: CONTAINER_MAX_MEMORY
valueFrom:
resourceFieldRef:
resource: limits.memory
livenessProbe:
exec:
command:
- /bin/bash
- '-c'
- /opt/eap/bin/livenessProbe.sh
failureThreshold: 3
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
exec:
command:
- /bin/bash
- '-c'
- /opt/eap/bin/readinessProbe.sh
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
memory: 100Mi
cpu: 100m
limits:
memory: 2Gi
- apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
labels:
app.kubernetes.io/name: Foo
app.kubernetes.io/instance: Bar
app.kubernetes.io/component: FooBar
app.kubernetes.io/part-of: Foo
app.kubernetes.io/managed-by: Bar
name: shouldneverfire${NAME}
spec:
replicas: 3
template:
metadata:
labels:
app.kubernetes.io/name: Foo
app.kubernetes.io/instance: Bar
app.kubernetes.io/component: FooBar
app.kubernetes.io/part-of: Foo
app.kubernetes.io/managed-by: Bar
spec:
containers:
- name: bar
image: quay.io/redhat-cop/openshift-applier@sha256:8a99a0105f85e350bff43802b204b5ce2a501cad1aa7df5253638ced1d108957
command: ["ansible-playbook"]
args: ["-i .applier/", "cluster-seed.yml"]
env:
- name: CONTAINER_MAX_MEMORY
valueFrom:
resourceFieldRef:
resource: limits.memory
livenessProbe:
exec:
command:
- /bin/bash
- '-c'
- /opt/eap/bin/livenessProbe.sh
failureThreshold: 3
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
exec:
command:
- /bin/bash
- '-c'
- /opt/eap/bin/readinessProbe.sh
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
memory: ${REQUESTS_MEMORY}
cpu: ${REQUESTS_CPU}
limits:
memory: ${LIMITS_MEMORY}
triggers:
- type: ConfigChange
parameters:
- name: NAME
generate: expression
from: "[a-z]{6}"
- name: REQUESTS_MEMORY
value: "100Mi"
- name: REQUESTS_CPU
value: "100m"
- name: LIMITS_MEMORY
value: "2Gi"
Loading

0 comments on commit 5211f6e

Please sign in to comment.