From 2a22fab9633ac2a207e5fc30a0381c5b07c2aae3 Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 19:52:50 +0100 Subject: [PATCH 01/12] Run device agent as non-root user --- docker/Dockerfile | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 5eba8977..fa5f3fc6 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -2,13 +2,19 @@ ARG NODE_VERSION=20 FROM node:${NODE_VERSION}-alpine ARG VERSION=latest +ARG FF_UID=2000 +ARG FF_GID=2000 RUN apk add --no-cache --virtual buildtools build-base linux-headers udev python3 openssl -RUN mkdir -m 777 -p /opt/flowfuse-device -RUN npm config set cache /opt/flowfuse-device/.npm --global -RUN npm install -g @flowfuse/device-agent@${VERSION} --omit=dev -RUN chmod -R 777 /opt/flowfuse-device/.npm +RUN addgroup -g ${FF_GID} -S flowfuse \ + && adduser -u ${FF_UID} -S -G flowfuse -h /opt/flowfuse-device flowfuse \ + && mkdir -p /opt/flowfuse-device \ + && chown -R "${FF_UID}":"${FF_GID}" /opt/flowfuse-device + +RUN npm config set cache /opt/flowfuse-device/.npm --global \ + && npm install -g @flowfuse/device-agent@${VERSION} --omit=dev \ + && chown -R ${FF_UID}:${FF_GID} /opt/flowfuse-device EXPOSE 1880 @@ -21,4 +27,8 @@ LABEL org.label-schema.name="FlowFuse Device Agent" \ authors="FlowFuse Inc." +ENV HOME=/opt/flowfuse-device + +USER ${FF_UID}:${FF_GID} + CMD ["flowfuse-device-agent"] From 0cc63e01c64b9b7b3cdbff7c2622397087ea16a7 Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 19:53:04 +0100 Subject: [PATCH 02/12] Add docker build workflow --- .github/workflows/docker-build.yaml | 33 +++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/docker-build.yaml diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml new file mode 100644 index 00000000..b53ea3ac --- /dev/null +++ b/.github/workflows/docker-build.yaml @@ -0,0 +1,33 @@ +name: Docker build (PR docker changes) + +on: + pull_request: + paths: + - 'docker/**' + - './github/workflows/docker-build.yaml' + +jobs: + docker-build: + runs-on: ubuntu-latest + strategy: + matrix: + node: [18, 20] + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set up QEMU + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + + - name: Build Docker image + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + file: docker/Dockerfile + platforms: linux/amd64, linux/arm64, linux/arm/v7 + push: false + build-args: | + NODE_VERSION=${{ matrix.node }} From ec1b4f15b4babdb4a00348ca20a0ce57c87a86d3 Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 19:54:50 +0100 Subject: [PATCH 03/12] Fix path --- .github/workflows/docker-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index b53ea3ac..d5f692b7 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -4,7 +4,7 @@ on: pull_request: paths: - 'docker/**' - - './github/workflows/docker-build.yaml' + - '.github/workflows/docker-build.yaml' jobs: docker-build: From 0f4f098670586e12370d54465eb899ce96d365ec Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 19:55:08 +0100 Subject: [PATCH 04/12] Adjust workflow name --- .github/workflows/docker-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index d5f692b7..01a9dde5 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -1,4 +1,4 @@ -name: Docker build (PR docker changes) +name: Docker build on: pull_request: From d8b14305309511f7a39a11afded4a46159ebafe5 Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 20:17:30 +0100 Subject: [PATCH 05/12] Add SAST scan for container --- .github/workflows/docker-build.yaml | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 01a9dde5..d52cb00d 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -9,6 +9,9 @@ on: jobs: docker-build: runs-on: ubuntu-latest + permissions: + contents: read + security-events: write strategy: matrix: node: [18, 20] @@ -31,3 +34,35 @@ jobs: push: false build-args: | NODE_VERSION=${{ matrix.node }} + + - name: Build Docker image for SAST scan + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + file: docker/Dockerfile + platforms: linux/amd64 + load: true + tags: flowfuse-device-agent-pr:${{ matrix.node }}-scan + push: false + build-args: | + NODE_VERSION=${{ matrix.node }} + + - name: Cache vulnerability database + uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 + with: + path: ~/.cache/trivy + key: ${{ runner.os }}-trivy-db-${{ github.run_id }} + restore-keys: | + ${{ runner.os }}-trivy-db- + + - name: Perform SAST scan + uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1 + with: + image-ref: flowfuse-device-agent-pr:${{ matrix.node }}-scan + trivy-config: .github/trivy.yaml + output: 'sast-results.sarif' + + - name: Upload scan results + uses: github/codeql-action/upload-sarif@fbcef3fba75224ed6476919775448de80b23cb15 # v3.32.0 + with: + sarif_file: sast-results.sarif From 0d90149ab669c32fda10472d3a66d7999ee4bdd4 Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 20:18:55 +0100 Subject: [PATCH 06/12] Do not build node package on docker-related changed --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a1897c28..4ae2d21b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,11 +6,15 @@ on: paths-ignore: - '.github/workflows/installer-build.yaml' - 'installer/**' + - 'docker/**' + - '.github/workflows/docker-build.yaml' pull_request: branches: [ main ] paths-ignore: - '.github/workflows/installer-build.yaml' - 'installer/**' + - 'docker/**' + - '.github/workflows/docker-build.yaml' jobs: build: From a2a12a4b8ffaec3f4335c0a3b2c547ca39d06d2b Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 20:24:01 +0100 Subject: [PATCH 07/12] Use codeql-action v4 --- .github/workflows/docker-build.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index d52cb00d..c44f3de6 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -9,6 +9,7 @@ on: jobs: docker-build: runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: read security-events: write @@ -63,6 +64,6 @@ jobs: output: 'sast-results.sarif' - name: Upload scan results - uses: github/codeql-action/upload-sarif@fbcef3fba75224ed6476919775448de80b23cb15 # v3.32.0 + uses: github/codeql-action/upload-sarif@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 with: sarif_file: sast-results.sarif From 711c16e1b2a7ce39ccb45d6f7d88adbb8794186b Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 20:32:24 +0100 Subject: [PATCH 08/12] Test multiarch image load --- .github/workflows/docker-build.yaml | 39 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index c44f3de6..5f118f57 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -20,11 +20,22 @@ jobs: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Set up Docker + uses: docker/setup-docker-action@v4 + with: + daemon-config: | + { + "debug": true, + "features": { + "containerd-snapshotter": true + } + } + - name: Set up QEMU uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - name: Build Docker image uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 @@ -32,22 +43,24 @@ jobs: context: . file: docker/Dockerfile platforms: linux/amd64, linux/arm64, linux/arm/v7 - push: false - build-args: | - NODE_VERSION=${{ matrix.node }} - - - name: Build Docker image for SAST scan - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - file: docker/Dockerfile - platforms: linux/amd64 - load: true tags: flowfuse-device-agent-pr:${{ matrix.node }}-scan push: false + load: true build-args: | NODE_VERSION=${{ matrix.node }} + # - name: Build Docker image for SAST scan + # uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + # with: + # context: . + # file: docker/Dockerfile + # platforms: linux/amd64 + # load: true + # tags: flowfuse-device-agent-pr:${{ matrix.node }}-scan + # push: false + # build-args: | + # NODE_VERSION=${{ matrix.node }} + - name: Cache vulnerability database uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 with: From 17d9c58a3f1d84460e460b312e439f37276f37e5 Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 20:41:04 +0100 Subject: [PATCH 09/12] Remove cache step --- .github/workflows/docker-build.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 5f118f57..790aa8ad 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -61,14 +61,6 @@ jobs: # build-args: | # NODE_VERSION=${{ matrix.node }} - - name: Cache vulnerability database - uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1 - with: - path: ~/.cache/trivy - key: ${{ runner.os }}-trivy-db-${{ github.run_id }} - restore-keys: | - ${{ runner.os }}-trivy-db- - - name: Perform SAST scan uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1 with: From 06fef863ddcb38457322065e940e7aedfb6dabab Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 20:42:34 +0100 Subject: [PATCH 10/12] Remove debug log level for docker --- .github/workflows/docker-build.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 790aa8ad..1a25fa34 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -25,7 +25,6 @@ jobs: with: daemon-config: | { - "debug": true, "features": { "containerd-snapshotter": true } From 3103b7c3d2fb4a4d4c27d4c4ed258d7da6c7aa56 Mon Sep 17 00:00:00 2001 From: PPawlowski Date: Wed, 28 Jan 2026 20:46:14 +0100 Subject: [PATCH 11/12] Pin setup-docker-action to commit sha --- .github/workflows/docker-build.yaml | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 1a25fa34..bbc02028 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Docker - uses: docker/setup-docker-action@v4 + uses: docker/setup-docker-action@e43656e248c0bd0647d3f5c195d116aacf6fcaf4 #v4.7.0 with: daemon-config: | { @@ -33,9 +33,6 @@ jobs: - name: Set up QEMU uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - # - name: Set up Docker Buildx - # uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - - name: Build Docker image uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: @@ -48,18 +45,6 @@ jobs: build-args: | NODE_VERSION=${{ matrix.node }} - # - name: Build Docker image for SAST scan - # uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - # with: - # context: . - # file: docker/Dockerfile - # platforms: linux/amd64 - # load: true - # tags: flowfuse-device-agent-pr:${{ matrix.node }}-scan - # push: false - # build-args: | - # NODE_VERSION=${{ matrix.node }} - - name: Perform SAST scan uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1 with: From 2d77a944adbe7257669aa64f6c617c8936cb8886 Mon Sep 17 00:00:00 2001 From: Piotr Pawlowski Date: Fri, 30 Jan 2026 17:53:32 +0100 Subject: [PATCH 12/12] Update docker/Dockerfile Co-authored-by: Ben Hardill --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index fa5f3fc6..4eb2c6a1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -29,6 +29,6 @@ LABEL org.label-schema.name="FlowFuse Device Agent" \ ENV HOME=/opt/flowfuse-device -USER ${FF_UID}:${FF_GID} +USER flowfuse CMD ["flowfuse-device-agent"]