Skip to content

Document how to harden security #363

@qdii

Description

@qdii

Here are some instructions to improve the security posture of the chart. Namely, they:

  • Turn the filesystem read-only
  • Drop privileges
  • Run the app with UID 1001 and GID 1001.

This is not trivial to do because the container image is built as root, so simply changing the running user to 1001 runs into issues when trying to read files shipped as part of the container image.

Ideally this should be part of a wiki, or included in the README. I'm not sure where to add them, hence opening it as issue to let the maintainers decide.

First, we need to add two volumes. The base will contain all the files present in the container image, but changed to belong to user/group 1001/1001. The tmp allows the app to write to /tmp.

volumes:
  - name: "tmp"
    emptyDir: {}
  - name: "base"
    emptyDir: {}

Then we need two initContainers:

  • cp-image will simply copy all files from the Docker image into base
  • fix-permissions will change UID/GID to all files in base and all files in the persistent volume data.
extraInitContainers:
  # The app relies on finding files that are present on the image
  # however, those are written as root (https://github.com/open-webui/open-webui/blob/main/Dockerfile#L22)
  # So we copy all files to an emptyDir, then chown them to 1001, then mount that as the base
  - name: cp-image
    image: ghcr.io/open-webui/open-webui:main
    command: ["sh", "-c", "ls -la /app; cp -Rv /app/* /base"]
    volumeMounts:
      - name: base
        mountPath: /base
  - name: fix-permissions
    image: busybox:latest
    command: ["sh", "-c", "chown -R 1001:1001 /data /base"]
    volumeMounts:
      - name: data
        mountPath: /data
      - name: base
        mountPath: /base

We then tell the app to mount base and tmp where the app expects them:

volumeMounts:
  container:
    - name: "base"
      mountPath: "/app"
      readOnly: false
    - name: "tmp"
      mountPath: "/tmp"

And with that we can apply propery security policies:

podSecurityContext:
  fsGroupChangePolicy: Always
  fsGroup: 1001

containerSecurityContext:
  runAsUser: 1001
  runAsGroup: 1001
  runAsNonRoot: true
  privileged: false
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  capabilities:
    drop:
      - ALL
  seccompProfile:
    type: "RuntimeDefault"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions