Using a Project Hummingbird container image
Project Hummingbird builds a collection of minimal, hardened, and secure container images with a significantly reduced attack surface. This strong focus on security combined with a highly automated update workflow aims to minimize CVE counts, targeting near-zero vulnerabilities. All images support amd64 and arm64 architectures.
Quick Start
All images are available from the Red Hat Hardened Images registry and work directly with Podman, Docker, or Kubernetes:
# Run a command directly with the curl image
podman run registry.access.redhat.com/hi/curl:latest -v https://example.com
# Start a PostgreSQL database
podman run -e POSTGRES_PASSWORD=mysecret -p 5432:5432 registry.access.redhat.com/hi/postgresql:latest
Example container build using the Hummingbird Python image:
FROM registry.access.redhat.com/hi/python:latest
COPY myapp.py /app/
WORKDIR /app
CMD ["python3", "myapp.py"]
Documentation for each image is available on the Red Hat Hardened Images Catalog.
Contents
- Available Images
- Hardened for Security
- Distroless Containers
- Understanding Image Variants
- Image Verification
- Vulnerability Scanning
- Sharing Host Data
- Custom CA Certificates
- Compatibility
- Reproducible Builds
- Content-Based Layers
- Source Containers
- Roadmap
- Relationship to Fedora
- Contributing
Available Images
Available images span language runtimes, databases, web servers, CLI tools, and base runtime images.
Browse the complete catalog at the Red Hat Hardened Images Catalog.
Hardened for Security
Hummingbird applies several measures to harden container images:
- Minimal Software Footprint: Images include only essential packages required for the workload, significantly reducing the attack surface and CVE count.
- Rapid Update Deployment: Package updates ship as quickly as possible, ensuring fixes are consumed early.
- Non-Root User Default: Containers default to a non-root user (UID 65532) where technically possible, reducing privileges within the container.
- Hermetic Build Environment: All containers are built in a hermetic environment without network access, preventing unintended package drift and maintaining full control over software versions.
- Distroless Security: Shipping only what is strictly necessary for the workload reduces the attack surface and makes certain types of attacks impossible.
- FIPS-Validated Cryptography: FIPS variants provide NIST-validated cryptographic modules for compliance-sensitive workloads.
Distroless Containers
Hummingbird builds distroless containers — images that do not ship with a package manager and most do not even provide a shell.
The distroless design makes the bundled application the container’s entrypoint, offering a streamlined experience. For example, with the curl image, arguments can be passed directly: podman run registry.access.redhat.com/hi/curl:latest -v https://www.redhat.com/en.
Purpose-built containers reduce the burden on users. Instead of building custom container images and managing their vulnerabilities, a Hummingbird image with the needed application avoids CVE management overhead entirely.
Understanding Image Variants
Hummingbird provides different variants to support various use cases while maintaining security by default.
Default Variant (:latest)
- Distroless: no package manager, no shell
- Minimal attack surface
- Recommended for production
- Example:
registry.access.redhat.com/hi/python:latest
Builder Variant (:latest-builder)
- Includes
dnfpackage manager andbash - For installing additional dependencies
- Intended for multi-stage builds and development
- Example:
registry.access.redhat.com/hi/python:latest-builder
Some images provide additional variants such as PHP’s FPM variant.
FIPS Variants (:latest-fips, :latest-fips-builder)
FIPS variants ship FIPS 140-3 validated cryptographic modules for workloads that require certified cryptography. Validation applies only when running on RHEL systems installed in FIPS mode.
Two cryptographic stacks are available depending on the image:
| Stack | Images | FIPS packages |
|---|---|---|
| OpenSSL | Go, Nginx, Node.js, Python, Ruby, curl | openssl-config-fips, crypto-policies-config-fips |
| NSS | OpenJDK | nss-softokn-fips, nss-softokn-freebl-fips |
FIPS is available in both distroless (:latest-fips) and builder (:latest-fips-builder) variants. FIPS variants are available for the Hummingbird distro only (not Rawhide). For implementation details, see the FIPS Variant Guide.
Support Levels
Images are published under two support levels:
- Red Hat supported — the majority of images. Built, tested, and maintained by the Hummingbird team with full CI/CD coverage, security updates, and vulnerability tracking. Available at
registry.access.redhat.com/hi/with official Red Hat signing keys — this is the recommended registry for all users. - Community — images where the upstream project does not follow standard open-source release practices (e.g., MinIO) or where the image is experimental (e.g., bootc-os). Built and tested in the same infrastructure but without the same support commitments. Community also serves as a staging ground for images being evaluated for promotion to Red Hat supported status. Published to
quay.io/hummingbird-community/.
Registry Organizations
| Registry | Description |
|---|---|
registry.access.redhat.com/hi/ |
Red Hat Hardened Container Images (recommended) |
quay.io/hummingbird/ |
Mirror of Red Hat supported images without official signing |
quay.io/hummingbird-community/ |
Community-supported images (e.g., MinIO, bootc-os) |
quay.io/hummingbird-rawhide/ |
Upstream Fedora Rawhide packages directly |
quay.io/hummingbird-ci/ |
Build infrastructure images |
Tool images used by pipelines (e.g., quay.io/hummingbird-ci/gitlab-ci) are published from
the tools repository.
Tagging Strategy
Images follow a version-based tagging scheme:
:latest— most recent version (may change):<version>— specific version (e.g.,:3.11,:16):<version>-builder— builder variant of a specific version:<version>-fips— FIPS variant of a specific version:<version>-fips-builder— FIPS builder variant of a specific version
Use versioned tags in production for reproducible builds. The :latest tag is convenient for development but may introduce unexpected changes.
For best practices on tag selection and digest pinning, see How to name, version, and reference container images.
Multi-version images:
For languages with multiple supported version families (Python, Node.js, .NET, etc.), separate images exist for each major version:
registry.access.redhat.com/hi/python:latest— latest Python (currently 3.14)registry.access.redhat.com/hi/python:3.11— Python 3.11.x (stays on 3.11)registry.access.redhat.com/hi/python:3.13— Python 3.13.x (stays on 3.13)
Version constraints prevent these images from accidentally upgrading to incompatible versions. See version constraints for details.
Multi-Stage Build Pattern
The recommended pattern for compiled languages:
# Build stage: use builder variant to install dependencies and compile
FROM registry.access.redhat.com/hi/go:latest-builder AS builder
RUN dnf install -y <build dependencies>
COPY . /src
WORKDIR /src
RUN go build -o /app .
# Runtime stage: use minimal base image for the compiled binary
FROM registry.access.redhat.com/hi/core-runtime:latest
COPY --from=builder /app /app
ENTRYPOINT ["/app"]
This approach provides build-time flexibility while maintaining a minimal production image.
Image Verification
Hummingbird images are signed and can be verified using cosign:
cosign verify \
--key "https://security.access.redhat.com/data/63405576.txt" \
--insecure-ignore-tlog \
registry.access.redhat.com/hi/<image>:<tag>
Vulnerability Scanning
Use Syft and Grype to locally inspect and scan images. For details on how production SBOMs are generated, see Software Bill of Materials.
To scan an image for vulnerabilities:
grype registry.access.redhat.com/hi/<image>:<tag>
For current vulnerability information across all variants and versions, see the Red Hat Hardened Images Catalog.
Sharing Host Data
By default, containers do not have access to host filesystem content. Volume mounts must be added explicitly:
podman run -v /path/on/host:/path/in/container registry.access.redhat.com/hi/curl:latest ...
SELinux Relabeling
On systems with SELinux enabled (such as Fedora and RHEL), mounted volumes must be relabeled to allow container access. Use the :z or :Z option:
podman run -v /path/on/host:/path/in/container:z registry.access.redhat.com/hi/curl:latest ...
The :z option relabels content to be accessible by any container sharing the mount. The :Z option relabels content to be uniquely accessible to one container.
File Permissions
Most Hummingbird images default to a non-root user. When mounting host directories that the container needs to write to, either make the directory world-writable (within a private directory):
mkdir -m 700 /path/on/host
mkdir -m 777 /path/on/host/mnt
podman run -v /path/on/host/mnt:/path/in/container:z ...
Or run as the root user (recommended only with rootless Podman, where the root user in the container maps to the calling user on the host):
podman run --user root -v /path/on/host:/path/in/container:z ...
For read-only access, no permission changes are needed as long as files are world-readable.
Custom CA Certificates
Hummingbird images can be configured to trust custom Certificate Authority (CA) certificates for TLS connections. The approach depends on the image’s TLS stack.
OpenSSL-Based Images (curl, Nginx, Python, etc.)
Mount a CA bundle to replace or extend the system trust store:
podman run --rm \
-v /path/to/ca.crt:/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem:ro,Z \
registry.access.redhat.com/hi/curl:latest https://internal-server/
For details on building derived images with merged trust stores, see the Custom CA (OpenSSL) guide.
Java-Based Images (OpenJDK, Tomcat)
Java uses its own PKCS12 truststore format. A custom truststore can be created using keytool and mounted at runtime:
podman run --rm \
-v /path/to/cacerts:/etc/pki/ca-trust/extracted/java/cacerts:ro,Z \
registry.access.redhat.com/hi/openjdk:latest java -jar app.jar
For step-by-step truststore creation, see the Custom CA (Java) guide.
Compatibility
Hummingbird images are designed for compatibility with popular images from Docker Hub, Red Hat UBI, and other registries, enabling straightforward migration of existing workloads.
Key difference: Hummingbird images default to a non-root user (UID 65532) where technically possible, while most traditional images run as root. This may require adjusting file permissions on mounted volumes:
# Ensure correct ownership for mounted data
chown -R 65532:65532 /path/to/data
For detailed comparisons (environment variables, ports, sizes, default users), see the compatibility report, also available in machine-readable form.
Reproducible Builds
Reproducible builds ensure that the same inputs and build environment always produce bit-for-bit identical output. This allows independent verification that a published image corresponds to its claimed source materials, making it straightforward to detect if malware was injected during the build process.
Hummingbird images are fully reproducible. Given the signed SLSA provenance attestation that accompanies each image, anyone can rebuild the image from its inputs (this git repo and the RPMs it describes) to verify it matches the published version exactly.
For further background, see Reproducible builds: Project Hummingbird.
Verifying Reproducibility
The cosign and podman tools are required. First, download and verify the SLSA provenance attestation using cosign (see Image Verification for key details):
cosign verify-attestation --key "https://security.access.redhat.com/data/63405576.txt" --insecure-ignore-tlog \
--type slsaprovenance $IMAGE > attestation.json
Then, feed the attestation into the rebuild tool (capture the image ID for comparison):
iid=$(podman run -i --rm --privileged -v /mnt \
quay.io/hummingbird-ci/hummingbird-builder rebuild < attestation.json)
[!NOTE] The
--privilegedflag is required because the build process uses nested containerization. However, this command is expected to be run rootless. A rootless container cannot gain more privileges than the calling user.
To verify reproducibility, pull the published image and compare image IDs:
iid2=$(podman pull $IMAGE)
[ $iid = $iid2 ] && echo "Identical"
[!NOTE] The containers-storage image ID (a hash over the manifest and uncompressed content) is used here, not the repo digest (a hash over compressed content). Comparing uncompressed content avoids depending on the exact compression algorithm or registry format.
To keep the rebuilt image for further inspection, use the DUMP_OCIARCHIVE environment variable:
podman run -i --rm --privileged -e DUMP_OCIARCHIVE=1 -v /mnt \
quay.io/hummingbird-ci/hummingbird-builder rebuild < attestation.json | podman load
Content-Based Layers
Most container images have layers that mirror the Containerfile structure: each RUN or COPY instruction creates a layer. A single package update can invalidate a layer much larger than the package itself, requiring clients to re-pull content that has not changed.
Hummingbird images use chunkah to split images into content-based layers. Instead of layers reflecting the build process, files are grouped by the packages they belong to. This benefits both the network level (only new layers need downloading) and the storage level (common layers are stored once on disk).
Inspect which packages live in which layers using podman history (or docker history):
podman pull registry.access.redhat.com/hi/jq
podman history registry.access.redhat.com/hi/jq
Source Containers
The source code for all Hummingbird containers is available as source containers. A source container includes RPM and non-RPM content shipped in an image, pushed alongside each available tag with the -source suffix.
Inspect source container contents with skopeo:
IMAGE=registry.access.redhat.com/hi/curl:8.19.0-source
cd $(mktemp -d)
mkdir source
skopeo copy --override-os=linux docker://$IMAGE dir:source
cd source
mv version manifest.json ..
for f in $(ls); do tar xvf $f; done
Roadmap
- Image catalog expansion: The catalog of available images will continue to expand significantly.
- Image size optimization: Container-specific package configurations and dependency management to further reduce image sizes.
- Enhanced CVE and SBOM tooling: Improved vulnerability metadata and scanning integration, including methods like cargo-auditable for Rust supply chain transparency.
- Bootable containers: Expanding support for image-based OS deployments and updates.
Relationship to Fedora
Hummingbird builds and maintains its own RPM packages independently. Spec files are derived from Fedora but built in Hummingbird’s own infrastructure, allowing project-specific modifications and optimizations. Key differences from Fedora:
- Use of monorepos — one monorepo for packages and one for containers, simplifying management and automation.
- Heavy reliance on CI/CD — dependency management, testing, and releasing are automated.
- Secure supply chain requirements — container images and packages are built using Konflux, providing SLSA level 3 compliance.
- Greater emphasis on upstream tracking — software closely tracks upstream projects’ lifecycles, including parallel stable versions where offered.
There is a natural affinity between the two projects, and opportunities exist to contribute work from Hummingbird back into Fedora.
Contributing
Interested in contributing? The following resources cover the development workflow:
- Quickstart Guide — building and testing images locally, project structure, CI/CD pipeline
- Adding Images — step-by-step guide for new images and versioned variants
- FIPS Variant Guide — adding FIPS-validated cryptography to an image
- Testing Images — running tests locally
- Development Workflow — local setup and workflow
License
This project is licensed under the MIT License - see the LICENSE.txt file for details.