Verify that Chainguard FIPS Containers are Configured to Use FIPS Modules
Learn how to verify that Chainguard FIPS Containers are properly configured to use various FIPS modules.
Before starting, you’ll need:
FIPS containers work on any recent Linux kernel, including:
Chainguard offers 400+ FIPS image variants. Choose based on your use case:
Language runtime images if you’re building applications:
go-fips - For building Go applicationspython-fips - For Python applicationsnode-fips - For Node.js applicationsjdk-fips or jre-fips - For Java applicationsdotnet-runtime-fips - For .NET applicationsApplication images if you need a specific tool or service:
nginx-fips - Web serverpostgres-fips - Databaseprometheus-fips - MonitoringBase images for minimal runtime environments:
glibc-openssl-fips - Minimal glibc-based runtimebusybox-fips - Minimal BusyBox environmentBrowse the complete catalog at images.chainguard.dev/?category=fips.
Let’s start with a Python example to verify FIPS is working.
Replace ORGANIZATION with your organization name in the Chainguard Registry:
docker pull cgr.dev/ORGANIZATION/python-fips:latestCreate a Python script that uses cryptography:
cat > test_fips.py << 'EOF'
import hashlib
import ssl
# Test that we can use cryptographic functions
data = b"Hello, FIPS!"
hash_result = hashlib.sha256(data).hexdigest()
print(f"SHA-256 hash: {hash_result}")
# Check SSL/TLS configuration
print(f"OpenSSL version: {ssl.OPENSSL_VERSION}")
print("FIPS cryptography is active")
EOFRun the script in the FIPS container:
docker run --rm -v $(pwd):/work -w /work \
cgr.dev/ORGANIZATION/python-fips:latest \
python test_fips.pyYou should see output like:
SHA-256 hash: 4a1e3b5c7d9f2a8c6b0e4f3a9d8c7b6a5e4d3c2b1a0f9e8d7c6b5a4e3d2c1b0a
OpenSSL version: OpenSSL 3.4.0 5 Aug 2025
FIPS cryptography is activeThis confirms the container is using OpenSSL for cryptographic operations.
Every Chainguard image includes a Software Bill of Materials (SBOM). Verify FIPS-required packages:
cosign download sbom cgr.dev/ORGANIZATION/python-fips:latest | grep -E "libcrypto|openssl-config"Look for:
libcrypto3 version 3.4.0-r2 or higheropenssl-config-fipshardened version 3.4.0-r3 or higherThese packages indicate kernel-independent FIPS configuration.
Run a container interactively to check OpenSSL configuration:
docker run --rm -it cgr.dev/ORGANIZATION/python-fips:latest shInside the container, verify the FIPS module:
cat /etc/ssl/fipsmodule.cnfYou should see configuration for the FIPS provider. This file’s presence and validity are essential for FIPS operation.
The recommended pattern is to build with a FIPS SDK image and run with a minimal FIPS runtime image.
Example Dockerfile for a Go application:
# Build stage
FROM cgr.dev/ORGANIZATION/go-fips:latest AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o myapp
# Runtime stage
FROM cgr.dev/ORGANIZATION/glibc-openssl-fips:latest
COPY --from=builder /app/myapp /usr/bin/myapp
ENTRYPOINT ["/usr/bin/myapp"]This pattern:
docker build -t myapp-fips .
docker run --rm myapp-fipsThe resulting container runs on any Linux kernel and maintains FIPS validation.
FROM cgr.dev/ORGANIZATION/python-fips:latest
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]FROM cgr.dev/ORGANIZATION/node-fips:latest AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
# Use multi-stage if you want a smaller runtime
FROM cgr.dev/ORGANIZATION/node-fips:latest
WORKDIR /app
COPY --from=builder /app .
CMD ["node", "server.js"]FROM cgr.dev/ORGANIZATION/jdk-fips:latest AS builder
WORKDIR /app
COPY . .
RUN javac MyApp.java
FROM cgr.dev/ORGANIZATION/jre-fips:latest
WORKDIR /app
COPY --from=builder /app/*.class .
CMD ["java", "MyApp"]To verify that FIPS mode is enforced, you can intentionally break the FIPS configuration and confirm the application fails.
Warning: This test should only be done in development environments.
Run a container with access to modify system files:
docker run --rm -it --user root \
cgr.dev/ORGANIZATION/python-fips:latest shInside the container, break the FIPS configuration:
# Backup the config
cp /etc/ssl/fipsmodule.cnf /tmp/fipsmodule.cnf.bak
# Invalidate it
ln -sf /dev/null /etc/ssl/fipsmodule.cnf
# Try to use crypto
python3 -c "import hashlib; print(hashlib.sha256(b'test').hexdigest())"You should see an error indicating FIPS is required but not available. This proves the container enforces FIPS mode and won’t fall back to non-validated cryptography.
Restore the config to fix:
cp /tmp/fipsmodule.cnf.bak /etc/ssl/fipsmodule.cnfFIPS containers work on any kernel, so you can develop and test locally:
Example for Python development:
docker run --rm -it \
-v $(pwd):/app \
-w /app \
-p 8000:8000 \
cgr.dev/ORGANIZATION/python-fips:latest \
bashInside, install development dependencies and run your app.
FIPS containers work in standard CI/CD pipelines without special infrastructure.
GitHub Actions example:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Pull FIPS image
run: docker pull cgr.dev/ORGANIZATION/python-fips:latest
- name: Run tests
run: |
docker run --rm -v $(pwd):/app -w /app \
cgr.dev/ORGANIZATION/python-fips:latest \
python -m pytestNo special runners or kernel configurations required.
Cause: The FIPS provider configuration is missing or invalid.
Solution: Verify you’re using a FIPS-tagged image (e.g., python-fips, not python). Check the SBOM contains required packages.
Cause: The application may be using a cryptographic library that doesn’t support FIPS.
Solution: Ensure your application uses OpenSSL-backed cryptography.
Cause: Likely not FIPS-related. Profile your application first.
Solution: Use standard profiling tools to identify bottlenecks. FIPS cryptography typically adds minimal overhead.
Cause: FIPS images require account access.
Solution: Verify your organization has FIPS access. Contact support if needed.
Now that you’ve deployed your first FIPS container:
Last updated: 2025-10-16 08:00