From 9cbaec6ebea13aa6c7e2a975bcbfee3ac3aeaf9a Mon Sep 17 00:00:00 2001 From: Souvik Sarkar Date: Wed, 14 Sep 2022 16:27:49 +0530 Subject: [PATCH] RHDEVDOCS 3306: Document running image build tasks as unprivileged builds intermediate content minor tidbits additional reference configs update content for non-root build user within container SME review comments incorporated pee review comments pavol's comments corrected typo revised sample SCC custom scc more corrections reding content based on Vincent's draft minor tweaks editorial updates Pipeline run example module name change peer review comments from Jake incorporated --- _topic_maps/_topic_map.yml | 2 + ...ing-of-container-images-using-buildah.adoc | 23 ++++ ...pods-in-a-privileged-security-context.adoc | 7 +- ...configuring-buildah-to-use-build-user.adoc | 110 +++++++++++++++ modules/op-configuring-custom-sa-and-scc.adoc | 96 ++++++++++++++ ...op-limitations-of-unprivileged-builds.adoc | 12 ++ ...ng-a-task-run-pipeline-run-build-user.adoc | 125 ++++++++++++++++++ 7 files changed, 373 insertions(+), 2 deletions(-) create mode 100644 cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc create mode 100644 modules/op-configuring-buildah-to-use-build-user.adoc create mode 100644 modules/op-configuring-custom-sa-and-scc.adoc create mode 100644 modules/op-limitations-of-unprivileged-builds.adoc create mode 100644 modules/op-starting-a-task-run-pipeline-run-build-user.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index 0caa0d693e..4587ee6db8 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -1706,6 +1706,8 @@ Topics: File: using-tekton-chains-for-openshift-pipelines-supply-chain-security - Name: Viewing pipeline logs using the OpenShift Logging Operator File: viewing-pipeline-logs-using-the-openshift-logging-operator + - Name: Unprivileged building of container images using Buildah + File: unprivileged-building-of-container-images-using-buildah - Name: GitOps Dir: gitops Distros: openshift-enterprise diff --git a/cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc b/cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc new file mode 100644 index 0000000000..adfa98a156 --- /dev/null +++ b/cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc @@ -0,0 +1,23 @@ +:_content-type: ASSEMBLY +[id="unprivileged-building-of-container-images-using-buildah"] += Unprivileged building of container images using Buildah +include::_attributes/common-attributes.adoc[] +:context: unprivileged-building-of-container-images-using-buildah + +toc::[] + +Running {pipelines-shortname} as the root user on a container can expose the container processes and the host to other potentially malicious resources. You can reduce this type of exposure by running the workload as a specific non-root user in the container. For secure unprivileged builds of container images using Buildah, you can perform the following steps: + +* Define custom service account (SA) and security context constraint (SCC). +* Configure Buildah to use the `build` user with id `1000`. +* Start a task run with a custom config map, or integrate it with a pipeline run. + +include::modules/op-configuring-custom-sa-and-scc.adoc[leveloffset=+1] +include::modules/op-configuring-buildah-to-use-build-user.adoc[leveloffset=+1] +include::modules/op-starting-a-task-run-pipeline-run-build-user.adoc[leveloffset=+1] +include::modules/op-limitations-of-unprivileged-builds.adoc[leveloffset=+1] + + +.Additional resources + +* xref:../../authentication/managing-security-context-constraints.adoc#managing-pod-security-policies[Managing security context constraints (SCCs)] \ No newline at end of file diff --git a/cicd/pipelines/using-pods-in-a-privileged-security-context.adoc b/cicd/pipelines/using-pods-in-a-privileged-security-context.adoc index 9ab0eb890c..13544851df 100644 --- a/cicd/pipelines/using-pods-in-a-privileged-security-context.adoc +++ b/cicd/pipelines/using-pods-in-a-privileged-security-context.adoc @@ -7,14 +7,17 @@ include::_attributes/common-attributes.adoc[] toc::[] The default configuration of OpenShift Pipelines 1.3.x and later versions does not allow you to run pods with privileged security context, if the pods result from pipeline run or task run. -For such pods, the default service account is `pipeline`, and the security context constraint (SCC) associated with the `pipelines` service account is `pipelines-scc`. The `pipelines-scc` SCC is similar to the `anyuid` SCC, but with a minor difference as defined in the YAML file for the SCC of pipelines: +For such pods, the default service account is `pipeline`, and the security context constraint (SCC) associated with the `pipeline` service account is `pipelines-scc`. The `pipelines-scc` SCC is similar to the `anyuid` SCC, but with minor differences as defined in the YAML file for the SCC of pipelines: -.Example `SecurityContextConstraints` object +.Example `pipelines-scc.yaml` snippet [source,yaml,subs="attributes+"] ---- apiVersion: security.openshift.io/v1 kind: SecurityContextConstraints ... +allowedCapabilities: + - SETFCAP +... fsGroup: type: MustRunAs ... diff --git a/modules/op-configuring-buildah-to-use-build-user.adoc b/modules/op-configuring-buildah-to-use-build-user.adoc new file mode 100644 index 0000000000..c4bd894ba7 --- /dev/null +++ b/modules/op-configuring-buildah-to-use-build-user.adoc @@ -0,0 +1,110 @@ +// Module included in the following assemblies: +// +// * cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc +:_content-type: PROCEDURE + +[id="configuring-builah-to-use-build-user_{context}"] += Configuring Buildah to use `build` user + +You can define a Buildah task to use the `build` user with user id `1000`. + +.Procedure + +. Create a copy of the `buildah` cluster task as an ordinary task. ++ +[source,terminal] +---- +$ tkn task create --from=buildah +---- + +. Edit the copied `buildah` task. ++ +[source,terminal] +---- +$ oc edit task buildah +---- ++ +.Example: Modified Buildah task with `build` user +[source,yaml] +---- +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: buildah-as-user +spec: + description: >- + Buildah task builds source into a container image and + then pushes it to a container registry. + Buildah Task builds source into a container image using Project Atomic's + Buildah build tool.It uses Buildah's support for building from Dockerfiles, + using its buildah bud command.This command executes the directives in the + Dockerfile to assemble a container image, then pushes that image to a + container registry. + params: + - name: IMAGE + description: Reference of the image buildah will produce. + - name: BUILDER_IMAGE + description: The location of the buildah builder image. + default: registry.redhat.io/rhel8/buildah@sha256:99cae35f40c7ec050fed3765b2b27e0b8bbea2aa2da7c16408e2ca13c60ff8ee + - name: STORAGE_DRIVER + description: Set buildah storage driver + default: vfs + - name: DOCKERFILE + description: Path to the Dockerfile to build. + default: ./Dockerfile + - name: CONTEXT + description: Path to the directory to use as context. + default: . + - name: TLSVERIFY + description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry) + default: "true" + - name: FORMAT + description: The format of the built container, oci or docker + default: "oci" + - name: BUILD_EXTRA_ARGS + description: Extra parameters passed for the build command when building images. + default: "" + - description: Extra parameters passed for the push command when pushing images. + name: PUSH_EXTRA_ARGS + type: string + default: "" + - description: Skip pushing the built image + name: SKIP_PUSH + type: string + default: "false" + results: + - description: Digest of the image just built. + name: IMAGE_DIGEST + type: string + workspaces: + - name: source + steps: + - name: build + securityContext: + runAsUser: 1000 <1> + image: $(params.BUILDER_IMAGE) + workingDir: $(workspaces.source.path) + script: | + echo "Running as USER ID `id`" <2> + buildah --storage-driver=$(params.STORAGE_DRIVER) bud \ + $(params.BUILD_EXTRA_ARGS) --format=$(params.FORMAT) \ + --tls-verify=$(params.TLSVERIFY) --no-cache \ + -f $(params.DOCKERFILE) -t $(params.IMAGE) $(params.CONTEXT) + [[ "$(params.SKIP_PUSH)" == "true" ]] && echo "Push skipped" && exit 0 + buildah --storage-driver=$(params.STORAGE_DRIVER) push \ + $(params.PUSH_EXTRA_ARGS) --tls-verify=$(params.TLSVERIFY) \ + --digestfile $(workspaces.source.path)/image-digest $(params.IMAGE) \ + docker://$(params.IMAGE) + cat $(workspaces.source.path)/image-digest | tee /tekton/results/IMAGE_DIGEST + volumeMounts: + - name: varlibcontainers + mountPath: /home/build/.local/share/containers + volumeMounts: + - name: varlibcontainers + mountPath: /home/build/.local/share/containers + volumes: + - name: varlibcontainers + emptyDir: {} +---- +<1> Run the container explicitly as the user id `1000`, which corresponds to the `build` user in the Buildah image. +<2> Display the user id to confirm that the process is running as user id `1000`. \ No newline at end of file diff --git a/modules/op-configuring-custom-sa-and-scc.adoc b/modules/op-configuring-custom-sa-and-scc.adoc new file mode 100644 index 0000000000..459f6ff864 --- /dev/null +++ b/modules/op-configuring-custom-sa-and-scc.adoc @@ -0,0 +1,96 @@ +// Module included in the following assemblies: +// +// * cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc +:_content-type: PROCEDURE + +[id="configuring-custom-sa-and-scc_{context}"] += Configuring custom service account and security context constraint + +The default `pipeline` SA allows using a user id outside of the namespace range. To reduce dependency on the default SA, you can define a custom SA and SCC with necessary cluster role and role bindings for the `build` user with user id `1000`. + +.Procedure + +* Create a custom SA and SCC with necessary cluster role and role bindings. ++ +.Example: Custom SA and SCC for used id `1000` +[source,yaml] +---- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: pipelines-sa-userid-1000 <1> +--- +kind: SecurityContextConstraints +metadata: + annotations: + name: pipelines-scc-userid-1000 <2> +allowHostDirVolumePlugin: false +allowHostIPC: false +allowHostNetwork: false +allowHostPID: false +allowHostPorts: false +allowPrivilegeEscalation: false +allowPrivilegedContainer: false +allowedCapabilities: null +apiVersion: security.openshift.io/v1 +defaultAddCapabilities: null +fsGroup: + type: MustRunAs +groups: +- system:cluster-admins +priority: 10 +readOnlyRootFilesystem: false +requiredDropCapabilities: +- MKNOD +runAsUser: <3> + type: MustRunAs + uid: 1000 +seLinuxContext: + type: MustRunAs +supplementalGroups: + type: RunAsAny +users: [] +volumes: +- configMap +- downwardAPI +- emptyDir +- persistentVolumeClaim +- projected +- secret +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pipelines-scc-userid-1000-clusterrole <4> +rules: +- apiGroups: + - security.openshift.io + resourceNames: + - pipelines-scc-userid-1000 + resources: + - securitycontextconstraints + verbs: + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: pipelines-scc-userid-1000-rolebinding <5> +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: pipelines-scc-userid-1000-clusterrole +subjects: +- kind: ServiceAccount + name: pipelines-sa-userid-1000 +---- + +<1> Define a custom SA. + +<2> Define a custom SCC created based on restricted privileges, with modified `runAsUser` field. + +<3> Restrict any pod that gets attached with the custom SCC through the custom SA to run as user id `1000`. + +<4> Define a cluster role that uses the custom SCC. + +<5> Bind the cluster role that uses the custom SCC to the custom SA. \ No newline at end of file diff --git a/modules/op-limitations-of-unprivileged-builds.adoc b/modules/op-limitations-of-unprivileged-builds.adoc new file mode 100644 index 0000000000..68bee1c5d1 --- /dev/null +++ b/modules/op-limitations-of-unprivileged-builds.adoc @@ -0,0 +1,12 @@ +// Module included in the following assemblies: +// +// * cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc +:_content-type: CONCEPT + +[id="limitations-of-unprivileged-builds_{context}"] += Limitations of unprivileged builds + +The process for unprivileged builds works with most `Dockerfile` objects. However, there are some known limitations might cause a build to fail: + +* Using the `--mount=type=cache` option might fail due to lack of necessay permissions issues. For more information, see this link:https://access.redhat.com/solutions/6969529[article]. +* Using the `--mount=type=secret` option fails because mounting resources requires additionnal capabilities that are not provided by the custom SCC. \ No newline at end of file diff --git a/modules/op-starting-a-task-run-pipeline-run-build-user.adoc b/modules/op-starting-a-task-run-pipeline-run-build-user.adoc new file mode 100644 index 0000000000..8942efd9fc --- /dev/null +++ b/modules/op-starting-a-task-run-pipeline-run-build-user.adoc @@ -0,0 +1,125 @@ +// Module included in the following assemblies: +// +// * cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc +:_content-type: PROCEDURE + +[id="starting-a-task-run-with-custom-config-map-or-a-pipeline-run_{context}"] += Starting a task run with custom config map, or a pipeline run + +After defining the custom Buildah cluster task, you can create a `TaskRun` object that builds an image as a `build` user with user id `1000`. In addition, you can integrate the `TaskRun` object as part of a `PipelineRun` object. + +.Procedure + +. Create a `TaskRun` object with a custom `ConfigMap` and `Dockerfile` objects. ++ +.Example: A task run that runs Buildah as user id `1000` +[source,yaml] +---- +apiVersion: v1 +data: + Dockerfile: | + ARG BASE_IMG=registry.access.redhat.com/ubi8/ubi + FROM $BASE_IMG AS buildah-runner + RUN dnf -y update && \ + dnf -y install git && \ + dnf clean all + CMD git +kind: ConfigMap +metadata: + name: dockerfile <1> +--- +apiVersion: tekton.dev/v1beta1 +kind: TaskRun +metadata: + name: buildah-as-user-1000 +spec: + serviceAccountName: pipelines-sa-userid-1000 + params: + - name: IMAGE + value: image-registry.openshift-image-registry.svc:5000/test/buildahuser + taskRef: + kind: Task + name: buildah-as-user + workspaces: + - configMap: + name: dockerfile <2> + name: source +---- +<1> Use a config map because the focus is on the task run, without any prior task that fetches some sources with a Dockerfile. +<2> Mount a config map as the source workspace for the `buildah-as-user` task. + +. (Optional) Create a pipeline and a corresponding pipeline run. ++ +.Example: A pipeline and corresponding pipeline run +[source,yaml] +---- +apiVersion: tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: pipeline-buildah-as-user-1000 +spec: + params: + - name: IMAGE + - name: URL + workspaces: + - name: shared-workspace + - name: sslcertdir + optional: true + tasks: + - name: fetch-repository <1> + taskRef: + name: git-clone + kind: ClusterTask + workspaces: + - name: output + workspace: shared-workspace + params: + - name: url + value: $(params.URL) + - name: subdirectory + value: "" + - name: deleteExisting + value: "true" + - name: buildah + taskRef: + name: buildah-as-user <2> + runAfter: + - fetch-repository + workspaces: + - name: source + workspace: shared-workspace + - name: sslcertdir + workspace: sslcertdir + params: + - name: IMAGE + value: $(params.IMAGE) +--- +apiVersion: tekton.dev/v1beta1 +kind: PipelineRun +metadata: + name: pipelinerun-buildah-as-user-1000 +spec: + serviceAccountName: pipelines-sa-userid-1000 + params: + - name: URL + value: https://github.com/openshift/pipelines-vote-api + - name: IMAGE + value: image-registry.openshift-image-registry.svc:5000/test/buildahuser + taskRef: + kind: Pipeline + name: pipeline-buildah-as-user-1000 + workspaces: + - name: shared-workspace <3> + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi +---- +<1> Use the `git-clone` cluster task to fetch the source containing a Dockerfile and build it using the modified Buildah task. +<2> Refer to the modified Buildah task. +<3> Share data between the `git-clone` task and the modified Buildah task using a persistent volume claim (PVC) created automatically by the controller. + +. Start the task run or the pipeline run. \ No newline at end of file