catalog / docker.io/minio/minio

docker.io/minio/minio

validated  pin current  tags: RELEASE.2025-09-07T16-13-09Z

minio — minimum Linux capabilities, derived by drop-test against the
default single-node invocation (`server /data`). ZERO-cap: cap_drop:[ALL]
with no cap_add — the jellyfin-class story (a single static Go binary
running AS ROOT with no privilege drop, serving the unprivileged :9000,
writing only to its /data VOLUME; the whole Docker default set is
over-grant, residual risk = the root uid, harden further with user:).
Immutable RELEASE.* tag. See criteria/docker.io/minio/minio.md.
filesystem: read_only:true, tmpfs:[]. minio's only writes are to its object
store /data (a persistent VOLUME, not tmpfs); it runs correctly under a
read-only rootfs with no additional tmpfs. /tmp was drop-tested and is NOT
required. Derived by drop-test.

Use it

services:
  minio:
    image: docker.io/minio/minio:RELEASE.2025-09-07T16-13-09Z
    cap_drop: [ALL]
    security_opt: ["no-new-privileges:true"]
    read_only: true

This profile has multiple dimensions and is applied as a unit. Dimensions can interact — a capability can be required only because of a sibling read-only/tmpfs recommendation — so where they do, the minimum was derived under the sibling dimension's context. See the criteria doc and each dimension's recorded invocation below before applying them separately.

Dimension: capabilities

cap_drop: ALL (no cap_add)

toolcontainer-sec-derive 0.7.0
observerdrop-test
validated imagedocker.io/minio/minio@sha256:14cea493d9a3…
validated date2026-07-16
confidencehigh
validated viadrop-test, ci-smoke
workloadprofiles/workloads/minio.sh
workload sha2561e722eac496a…
ig versionv0.51.0

Drop-test evidence

Each candidate removed in turn, the container restarted, and the workload re-verified.

RemovedVerdictObserved
CHOWNremovablecorrect: S3 mb/put/get round-trip ok
DAC_OVERRIDEremovablecorrect: S3 mb/put/get round-trip ok
FSETIDremovablecorrect: S3 mb/put/get round-trip ok
FOWNERremovablecorrect: S3 mb/put/get round-trip ok
MKNODremovablecorrect: S3 mb/put/get round-trip ok
NET_RAWremovablecorrect: S3 mb/put/get round-trip ok
SETGIDremovablecorrect: S3 mb/put/get round-trip ok
SETUIDremovablecorrect: S3 mb/put/get round-trip ok
SETFCAPremovablecorrect: S3 mb/put/get round-trip ok
SETPCAPremovablecorrect: S3 mb/put/get round-trip ok
NET_BIND_SERVICEremovablecorrect: S3 mb/put/get round-trip ok
SYS_CHROOTremovablecorrect: S3 mb/put/get round-trip ok
KILLremovablecorrect: S3 mb/put/get round-trip ok
AUDIT_WRITEremovablecorrect: S3 mb/put/get round-trip ok

Recorded invocation (run_config)

The minimum is valid for this invocation; a different user:, volume state, or entrypoint can change it.

commandserver
/data
security_optno-new-privileges:true
envMINIO_ROOT_USER
MINIO_ROOT_PASSWORD
Workload script (profiles/workloads/minio.sh)
#!/usr/bin/env bash
# Workload exerciser for the minio reference image (single-node
# `server /data`).
#
# A real S3 round-trip via the pinned `mc` client run as a sidecar in the
# target's netns (the server image ships no client): make-bucket, pipe an
# object in, cat it back byte-identical. The MC_HOST_ env alias keeps mc
# config-free — the only writes are the object store's own.
#
# Required env: MINIOCONTAINER (target container name or id). The container
# is expected to run with MINIO_ROOT_USER=csdadmin /
# MINIO_ROOT_PASSWORD=CsdProbe-Pw-12345 (the derivation credentials).
set -euo pipefail

: "${MINIOCONTAINER:?MINIOCONTAINER must be set}"
C="${MINIOCONTAINER}"
MC_IMAGE="${CSD_PROBE_MC_IMAGE:-minio/mc@sha256:a7fe349ef4bd8521fb8497f55c6042871b2ae640607cf99d9bede5e9bdf11727}"
mcx() { docker run --rm --entrypoint /bin/sh --network "container:${C}" \
        -e MC_HOST_csd=http://csdadmin:CsdProbe-Pw-12345@localhost:9000 "$MC_IMAGE" -c "$*"; }

deadline=$((SECONDS + 45))
until mcx 'mc ls csd/ >/dev/null 2>&1'; do
    (( SECONDS >= deadline )) && { echo "minio never answered" >&2; exit 1; }
    sleep 2
done

got="$(mcx 'mc mb -p csd/csdbucket >/dev/null 2>&1; echo csd-payload-42 | mc pipe csd/csdbucket/probe.txt >/dev/null 2>&1 && mc cat csd/csdbucket/probe.txt 2>/dev/null')"
if [ "$got" != "csd-payload-42" ]; then
    echo "S3 round-trip failed (got: ${got:0:60})" >&2
    exit 1
fi

Dimension: filesystem

read_only: true, no tmpfs

toolcontainer-sec-derive 0.7.0
observerdrop-test
validated imagedocker.io/minio/minio@sha256:14cea493d9a3…
validated date2026-07-16
confidencehigh
validated viadrop-test, ci-smoke
workloadprofiles/workloads/minio.sh
workload sha2561e722eac496a…
ig versionv0.51.0

Drop-test evidence

Each candidate removed in turn, the container restarted, and the workload re-verified.

RemovedVerdictObserved
/tmpremovablecorrect: S3 mb/put/get round-trip ok

Recorded invocation (run_config)

The minimum is valid for this invocation; a different user:, volume state, or entrypoint can change it.

commandserver
/data
envMINIO_ROOT_USER
MINIO_ROOT_PASSWORD
Workload script (profiles/workloads/minio.sh)
#!/usr/bin/env bash
# Workload exerciser for the minio reference image (single-node
# `server /data`).
#
# A real S3 round-trip via the pinned `mc` client run as a sidecar in the
# target's netns (the server image ships no client): make-bucket, pipe an
# object in, cat it back byte-identical. The MC_HOST_ env alias keeps mc
# config-free — the only writes are the object store's own.
#
# Required env: MINIOCONTAINER (target container name or id). The container
# is expected to run with MINIO_ROOT_USER=csdadmin /
# MINIO_ROOT_PASSWORD=CsdProbe-Pw-12345 (the derivation credentials).
set -euo pipefail

: "${MINIOCONTAINER:?MINIOCONTAINER must be set}"
C="${MINIOCONTAINER}"
MC_IMAGE="${CSD_PROBE_MC_IMAGE:-minio/mc@sha256:a7fe349ef4bd8521fb8497f55c6042871b2ae640607cf99d9bede5e9bdf11727}"
mcx() { docker run --rm --entrypoint /bin/sh --network "container:${C}" \
        -e MC_HOST_csd=http://csdadmin:CsdProbe-Pw-12345@localhost:9000 "$MC_IMAGE" -c "$*"; }

deadline=$((SECONDS + 45))
until mcx 'mc ls csd/ >/dev/null 2>&1'; do
    (( SECONDS >= deadline )) && { echo "minio never answered" >&2; exit 1; }
    sleep 2
done

got="$(mcx 'mc mb -p csd/csdbucket >/dev/null 2>&1; echo csd-payload-42 | mc pipe csd/csdbucket/probe.txt >/dev/null 2>&1 && mc cat csd/csdbucket/probe.txt 2>/dev/null')"
if [ "$got" != "csd-payload-42" ]; then
    echo "S3 round-trip failed (got: ${got:0:60})" >&2
    exit 1
fi

Evidence & provenance

Raw profile YAML
# minio — minimum Linux capabilities, derived by drop-test against the
# default single-node invocation (`server /data`). ZERO-cap: cap_drop:[ALL]
# with no cap_add — the jellyfin-class story (a single static Go binary
# running AS ROOT with no privilege drop, serving the unprivileged :9000,
# writing only to its /data VOLUME; the whole Docker default set is
# over-grant, residual risk = the root uid, harden further with user:).
# Immutable RELEASE.* tag. See criteria/docker.io/minio/minio.md.
# filesystem: read_only:true, tmpfs:[]. minio's only writes are to its object
# store /data (a persistent VOLUME, not tmpfs); it runs correctly under a
# read-only rootfs with no additional tmpfs. /tmp was drop-tested and is NOT
# required. Derived by drop-test.
#
schema_version: "1.5"
image: docker.io/minio/minio
reference_url: https://tmatens.github.io/container-security-profiles/profiles/docker.io/minio/minio.html
applies_to:
  tags: ["RELEASE.2025-09-07T16-13-09Z"]
status: validated
dimensions:
  capabilities:
    cap_drop: [ALL]
    cap_add: []
    derivation:
      tool: container-sec-derive
      tool_version: "0.7.0"
      sidecar_schema_version: "1.5"
      observer: drop-test
      validated_image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
      validated_date: "2026-07-16"
      duration_seconds: 300
      confidence: high
      workload: profiles/workloads/minio.sh
      workload_sha256: "1e722eac496a234dd1f454b222c25aa486ca57ec995d7f7aa0c7cebf6e897e1b"
      validated_via: [drop-test, ci-smoke]
      observation_backend:
        ig_version: v0.51.0
        gadgets: []
      run_config:
        user: ""
        command: ["server", "/data"]
        entrypoint: ""
        network: ""
        pid: ""
        devices: []
        security_opt: ["no-new-privileges:true"]
        mounts: []
        env: [MINIO_ROOT_USER, MINIO_ROOT_PASSWORD]
      drop_test:
        checks:
          - {removed: CHOWN, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: DAC_OVERRIDE, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: FSETID, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: FOWNER, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: MKNOD, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: NET_RAW, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: SETGID, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: SETUID, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: SETFCAP, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: SETPCAP, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: NET_BIND_SERVICE, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: SYS_CHROOT, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: KILL, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
          - {removed: AUDIT_WRITE, required: false, observed: "correct: S3 mb/put/get round-trip ok"}
  filesystem:
    read_only: true
    tmpfs: []
    derivation:
      tool: container-sec-derive
      tool_version: "0.7.0"
      sidecar_schema_version: "1.5"
      observer: drop-test
      validated_image: docker.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
      validated_date: "2026-07-16"
      duration_seconds: 3
      confidence: high
      workload: profiles/workloads/minio.sh
      workload_sha256: "1e722eac496a234dd1f454b222c25aa486ca57ec995d7f7aa0c7cebf6e897e1b"
      validated_via: [drop-test, ci-smoke]
      observation_backend:
        ig_version: v0.51.0
        gadgets: []
      run_config:
        user: ""
        command: [server, /data]
        entrypoint: ""
        network: ""
        pid: ""
        devices: []
        security_opt: []
        mounts: []
        env: [MINIO_ROOT_USER, MINIO_ROOT_PASSWORD]
      drop_test:
        checks:
          - {removed: /tmp, required: false, observed: "correct: S3 mb/put/get round-trip ok"}