workshop/scenario_2/security2.yaml (521 lines of code) (raw):

apiVersion: v1 kind: Namespace metadata: labels: control-plane: controller-manager controller-tools.k8s.io: "1.0" name: gatekeeper-system --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: creationTimestamp: null labels: controller-tools.k8s.io: "1.0" name: configs.config.gatekeeper.sh spec: group: config.gatekeeper.sh names: kind: Config plural: configs scope: Namespaced validation: openAPIV3Schema: properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' type: string metadata: type: object spec: properties: sync: description: Configuration for syncing k8s objects properties: syncOnly: description: If non-empty, only entries on this list will be replicated into OPA items: properties: group: type: string kind: type: string version: type: string type: object type: array type: object validation: description: Configuration for validation properties: traces: description: List of requests to trace. Both "user" and "kinds" must be specified items: properties: dump: description: Also dump the state of OPA with the trace. Set to `All` to dump everything. type: string kind: description: Only trace requests of the following GroupVersionKind properties: group: type: string kind: type: string version: type: string type: object user: description: Only trace requests from the specified user type: string type: object type: array type: object type: object status: properties: byPod: description: List of statuses as seen by individual pods items: properties: allFinalizers: description: List of Group/Version/Kinds with finalizers items: properties: group: type: string kind: type: string version: type: string type: object type: array id: description: a unique identifier for the pod that wrote the status type: string type: object type: array type: object version: v1alpha1 status: acceptedNames: kind: "" plural: "" conditions: [] storedVersions: [] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: creationTimestamp: null name: gatekeeper-manager-role rules: - apiGroups: - '*' resources: - '*' verbs: - get - list - watch - update - patch - apiGroups: - config.gatekeeper.sh resources: - configs verbs: - get - list - watch - create - update - patch - delete - apiGroups: - config.gatekeeper.sh resources: - configs/status verbs: - get - update - patch - apiGroups: - constraints.gatekeeper.sh resources: - '*' verbs: - get - list - watch - create - update - patch - delete - apiGroups: - apiextensions.k8s.io resources: - customresourcedefinitions verbs: - get - list - watch - create - update - patch - delete - apiGroups: - templates.gatekeeper.sh resources: - constrainttemplates verbs: - get - list - watch - create - update - patch - delete - apiGroups: - templates.gatekeeper.sh resources: - constrainttemplates/status verbs: - get - update - patch - apiGroups: - constraints.gatekeeper.sh resources: - '*' verbs: - get - list - watch - create - update - patch - delete - apiGroups: - '*' resources: - '*' verbs: - get - list - watch - apiGroups: - "" resources: - configmaps verbs: - get - list - watch - create - update - patch - delete - apiGroups: - admissionregistration.k8s.io resources: - mutatingwebhookconfigurations - validatingwebhookconfigurations verbs: - get - list - watch - create - update - patch - delete - apiGroups: - "" resources: - secrets verbs: - get - list - watch - create - update - patch - delete - apiGroups: - "" resources: - services verbs: - get - list - watch - create - update - patch - delete --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: creationTimestamp: null name: gatekeeper-manager-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: gatekeeper-manager-role subjects: - kind: ServiceAccount name: default namespace: gatekeeper-system --- apiVersion: v1 kind: Secret metadata: name: gatekeeper-webhook-server-secret namespace: gatekeeper-system --- apiVersion: v1 kind: Service metadata: labels: control-plane: controller-manager controller-tools.k8s.io: "1.0" name: gatekeeper-controller-manager-service namespace: gatekeeper-system spec: ports: - port: 443 targetPort: 8443 selector: control-plane: controller-manager controller-tools.k8s.io: "1.0" --- apiVersion: apps/v1 kind: StatefulSet metadata: labels: control-plane: controller-manager controller-tools.k8s.io: "1.0" name: gatekeeper-controller-manager namespace: gatekeeper-system spec: selector: matchLabels: control-plane: controller-manager controller-tools.k8s.io: "1.0" serviceName: gatekeeper-controller-manager-service template: metadata: labels: control-plane: controller-manager controller-tools.k8s.io: "1.0" spec: containers: - args: - --auditInterval=30 - --port=8443 env: - name: POD_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: SECRET_NAME value: gatekeeper-webhook-server-secret image: quay.io/open-policy-agent/gatekeeper:v3.0.4-beta.2 imagePullPolicy: Always name: manager ports: - containerPort: 8443 name: webhook-server protocol: TCP resources: limits: cpu: 100m memory: 512Mi requests: cpu: 100m memory: 256Mi volumeMounts: - mountPath: /certs name: cert readOnly: true terminationGracePeriodSeconds: 60 volumes: - name: cert secret: defaultMode: 420 secretName: gatekeeper-webhook-server-secret --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: creationTimestamp: null labels: controller-tools.k8s.io: "1.0" name: constrainttemplates.templates.gatekeeper.sh spec: group: templates.gatekeeper.sh names: kind: ConstraintTemplate plural: constrainttemplates scope: Cluster validation: openAPIV3Schema: properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' type: string metadata: type: object spec: properties: crd: properties: spec: properties: names: properties: kind: type: string type: object validation: type: object type: object type: object targets: items: properties: rego: type: string target: type: string type: object type: array type: object status: properties: byPod: items: properties: errors: items: properties: code: type: string location: type: string message: type: string required: - code - message type: object type: array id: description: a unique identifier for the pod that wrote the status type: string type: object type: array created: type: boolean type: object version: v1 versions: - name: v1beta1 served: true storage: true - name: v1alpha1 served: true storage: false status: acceptedNames: kind: "" plural: "" conditions: [] storedVersions: [] --- # Disallow privileged containers apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8sprivilegedcontainer spec: crd: spec: names: kind: K8sPrivilegedContainer listKind: K8sPrivilegedContainerList plural: k8sprivilegedcontainer singular: k8sprivilegedcontainer targets: - target: admission.k8s.gatekeeper.sh rego: | package k8spspprivileged violation[{"msg": msg, "details": {}}] { c := input_containers[_] c.securityContext.privileged msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext]) } input_containers[c] { c := input.review.object.spec.containers[_] } input_containers[c] { c := input.review.object.spec.initContainers[_] } --- # Allow whitelisted repos apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8sallowedrepos spec: crd: spec: names: kind: K8sAllowedRepos listKind: K8sAllowedReposList plural: k8sallowedrepos singular: k8sallowedrepos validation: # Schema for the `parameters` field openAPIV3Schema: properties: repos: type: array items: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8sallowedrepos violation[{"msg": msg}] { container := input.review.object.spec.containers[_] satisfied := [good | repo = input.parameters.repos[_] ; good = startswith(container.image, repo)] not any(satisfied) msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos]) } violation[{"msg": msg}] { container := input.review.object.spec.initContainers[_] satisfied := [good | repo = input.parameters.repos[_] ; good = startswith(container.image, repo)] not any(satisfied) msg := sprintf("container <%v> has an invalid image repo <%v>, allowed repos are %v", [container.name, container.image, input.parameters.repos]) }