Skip to content

Commit fd788cc

Browse files
authored
Merge pull request #50364 from sounix000/3306-unprivileged-builds
RHDEVDOCS 3306: Document running image build tasks as unprivileged bu…
2 parents 3b5c511 + ece98d9 commit fd788cc

7 files changed

+373
-2
lines changed

_topic_maps/_topic_map.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,8 @@ Topics:
17051705
File: using-tekton-chains-for-openshift-pipelines-supply-chain-security
17061706
- Name: Viewing pipeline logs using the OpenShift Logging Operator
17071707
File: viewing-pipeline-logs-using-the-openshift-logging-operator
1708+
- Name: Unprivileged building of container images using Buildah
1709+
File: unprivileged-building-of-container-images-using-buildah
17081710
- Name: GitOps
17091711
Dir: gitops
17101712
Distros: openshift-enterprise
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
:_content-type: ASSEMBLY
2+
[id="unprivileged-building-of-container-images-using-buildah"]
3+
= Unprivileged building of container images using Buildah
4+
include::_attributes/common-attributes.adoc[]
5+
:context: unprivileged-building-of-container-images-using-buildah
6+
7+
toc::[]
8+
9+
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:
10+
11+
* Define custom service account (SA) and security context constraint (SCC).
12+
* Configure Buildah to use the `build` user with id `1000`.
13+
* Start a task run with a custom config map, or integrate it with a pipeline run.
14+
15+
include::modules/op-configuring-custom-sa-and-scc.adoc[leveloffset=+1]
16+
include::modules/op-configuring-buildah-to-use-build-user.adoc[leveloffset=+1]
17+
include::modules/op-starting-a-task-run-pipeline-run-build-user.adoc[leveloffset=+1]
18+
include::modules/op-limitations-of-unprivileged-builds.adoc[leveloffset=+1]
19+
20+
21+
.Additional resources
22+
23+
* xref:../../authentication/managing-security-context-constraints.adoc#managing-pod-security-policies[Managing security context constraints (SCCs)]

cicd/pipelines/using-pods-in-a-privileged-security-context.adoc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ include::_attributes/common-attributes.adoc[]
77
toc::[]
88

99
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.
10-
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:
10+
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:
1111

12-
.Example `SecurityContextConstraints` object
12+
.Example `pipelines-scc.yaml` snippet
1313
[source,yaml,subs="attributes+"]
1414
----
1515
apiVersion: security.openshift.io/v1
1616
kind: SecurityContextConstraints
1717
...
18+
allowedCapabilities:
19+
- SETFCAP
20+
...
1821
fsGroup:
1922
type: MustRunAs
2023
...
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc
4+
:_content-type: PROCEDURE
5+
6+
[id="configuring-builah-to-use-build-user_{context}"]
7+
= Configuring Buildah to use `build` user
8+
9+
You can define a Buildah task to use the `build` user with user id `1000`.
10+
11+
.Procedure
12+
13+
. Create a copy of the `buildah` cluster task as an ordinary task.
14+
+
15+
[source,terminal]
16+
----
17+
$ tkn task create --from=buildah
18+
----
19+
20+
. Edit the copied `buildah` task.
21+
+
22+
[source,terminal]
23+
----
24+
$ oc edit task buildah
25+
----
26+
+
27+
.Example: Modified Buildah task with `build` user
28+
[source,yaml]
29+
----
30+
apiVersion: tekton.dev/v1beta1
31+
kind: Task
32+
metadata:
33+
name: buildah-as-user
34+
spec:
35+
description: >-
36+
Buildah task builds source into a container image and
37+
then pushes it to a container registry.
38+
Buildah Task builds source into a container image using Project Atomic's
39+
Buildah build tool.It uses Buildah's support for building from Dockerfiles,
40+
using its buildah bud command.This command executes the directives in the
41+
Dockerfile to assemble a container image, then pushes that image to a
42+
container registry.
43+
params:
44+
- name: IMAGE
45+
description: Reference of the image buildah will produce.
46+
- name: BUILDER_IMAGE
47+
description: The location of the buildah builder image.
48+
default: registry.redhat.io/rhel8/buildah@sha256:99cae35f40c7ec050fed3765b2b27e0b8bbea2aa2da7c16408e2ca13c60ff8ee
49+
- name: STORAGE_DRIVER
50+
description: Set buildah storage driver
51+
default: vfs
52+
- name: DOCKERFILE
53+
description: Path to the Dockerfile to build.
54+
default: ./Dockerfile
55+
- name: CONTEXT
56+
description: Path to the directory to use as context.
57+
default: .
58+
- name: TLSVERIFY
59+
description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS registry)
60+
default: "true"
61+
- name: FORMAT
62+
description: The format of the built container, oci or docker
63+
default: "oci"
64+
- name: BUILD_EXTRA_ARGS
65+
description: Extra parameters passed for the build command when building images.
66+
default: ""
67+
- description: Extra parameters passed for the push command when pushing images.
68+
name: PUSH_EXTRA_ARGS
69+
type: string
70+
default: ""
71+
- description: Skip pushing the built image
72+
name: SKIP_PUSH
73+
type: string
74+
default: "false"
75+
results:
76+
- description: Digest of the image just built.
77+
name: IMAGE_DIGEST
78+
type: string
79+
workspaces:
80+
- name: source
81+
steps:
82+
- name: build
83+
securityContext:
84+
runAsUser: 1000 <1>
85+
image: $(params.BUILDER_IMAGE)
86+
workingDir: $(workspaces.source.path)
87+
script: |
88+
echo "Running as USER ID `id`" <2>
89+
buildah --storage-driver=$(params.STORAGE_DRIVER) bud \
90+
$(params.BUILD_EXTRA_ARGS) --format=$(params.FORMAT) \
91+
--tls-verify=$(params.TLSVERIFY) --no-cache \
92+
-f $(params.DOCKERFILE) -t $(params.IMAGE) $(params.CONTEXT)
93+
[[ "$(params.SKIP_PUSH)" == "true" ]] && echo "Push skipped" && exit 0
94+
buildah --storage-driver=$(params.STORAGE_DRIVER) push \
95+
$(params.PUSH_EXTRA_ARGS) --tls-verify=$(params.TLSVERIFY) \
96+
--digestfile $(workspaces.source.path)/image-digest $(params.IMAGE) \
97+
docker://$(params.IMAGE)
98+
cat $(workspaces.source.path)/image-digest | tee /tekton/results/IMAGE_DIGEST
99+
volumeMounts:
100+
- name: varlibcontainers
101+
mountPath: /home/build/.local/share/containers
102+
volumeMounts:
103+
- name: varlibcontainers
104+
mountPath: /home/build/.local/share/containers
105+
volumes:
106+
- name: varlibcontainers
107+
emptyDir: {}
108+
----
109+
<1> Run the container explicitly as the user id `1000`, which corresponds to the `build` user in the Buildah image.
110+
<2> Display the user id to confirm that the process is running as user id `1000`.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc
4+
:_content-type: PROCEDURE
5+
6+
[id="configuring-custom-sa-and-scc_{context}"]
7+
= Configuring custom service account and security context constraint
8+
9+
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`.
10+
11+
.Procedure
12+
13+
* Create a custom SA and SCC with necessary cluster role and role bindings.
14+
+
15+
.Example: Custom SA and SCC for used id `1000`
16+
[source,yaml]
17+
----
18+
apiVersion: v1
19+
kind: ServiceAccount
20+
metadata:
21+
name: pipelines-sa-userid-1000 <1>
22+
---
23+
kind: SecurityContextConstraints
24+
metadata:
25+
annotations:
26+
name: pipelines-scc-userid-1000 <2>
27+
allowHostDirVolumePlugin: false
28+
allowHostIPC: false
29+
allowHostNetwork: false
30+
allowHostPID: false
31+
allowHostPorts: false
32+
allowPrivilegeEscalation: false
33+
allowPrivilegedContainer: false
34+
allowedCapabilities: null
35+
apiVersion: security.openshift.io/v1
36+
defaultAddCapabilities: null
37+
fsGroup:
38+
type: MustRunAs
39+
groups:
40+
- system:cluster-admins
41+
priority: 10
42+
readOnlyRootFilesystem: false
43+
requiredDropCapabilities:
44+
- MKNOD
45+
runAsUser: <3>
46+
type: MustRunAs
47+
uid: 1000
48+
seLinuxContext:
49+
type: MustRunAs
50+
supplementalGroups:
51+
type: RunAsAny
52+
users: []
53+
volumes:
54+
- configMap
55+
- downwardAPI
56+
- emptyDir
57+
- persistentVolumeClaim
58+
- projected
59+
- secret
60+
---
61+
apiVersion: rbac.authorization.k8s.io/v1
62+
kind: ClusterRole
63+
metadata:
64+
name: pipelines-scc-userid-1000-clusterrole <4>
65+
rules:
66+
- apiGroups:
67+
- security.openshift.io
68+
resourceNames:
69+
- pipelines-scc-userid-1000
70+
resources:
71+
- securitycontextconstraints
72+
verbs:
73+
- use
74+
---
75+
apiVersion: rbac.authorization.k8s.io/v1
76+
kind: RoleBinding
77+
metadata:
78+
name: pipelines-scc-userid-1000-rolebinding <5>
79+
roleRef:
80+
apiGroup: rbac.authorization.k8s.io
81+
kind: ClusterRole
82+
name: pipelines-scc-userid-1000-clusterrole
83+
subjects:
84+
- kind: ServiceAccount
85+
name: pipelines-sa-userid-1000
86+
----
87+
88+
<1> Define a custom SA.
89+
90+
<2> Define a custom SCC created based on restricted privileges, with modified `runAsUser` field.
91+
92+
<3> Restrict any pod that gets attached with the custom SCC through the custom SA to run as user id `1000`.
93+
94+
<4> Define a cluster role that uses the custom SCC.
95+
96+
<5> Bind the cluster role that uses the custom SCC to the custom SA.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * cicd/pipelines/unprivileged-building-of-container-images-using-buildah.adoc
4+
:_content-type: CONCEPT
5+
6+
[id="limitations-of-unprivileged-builds_{context}"]
7+
= Limitations of unprivileged builds
8+
9+
The process for unprivileged builds works with most `Dockerfile` objects. However, there are some known limitations might cause a build to fail:
10+
11+
* 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].
12+
* Using the `--mount=type=secret` option fails because mounting resources requires additionnal capabilities that are not provided by the custom SCC.

0 commit comments

Comments
 (0)