Platform One is the DoD's enterprise DevSecOps platform, and Iron Bank is its container image repository — a curated registry of DISA-approved, hardened container images that DoD programs can use as base layers for their application containers.
For development teams building on IL4/IL5 environments, Iron Bank shifts the compliance burden on base images from each individual program to a centralized hardening team. Your job becomes: build your application on an approved base, add your application code, and demonstrate that you haven't introduced new vulnerabilities or violated the hardening.
This guide covers how Iron Bank works, the pipeline integration that keeps you compliant, and what using hardened images actually requires your team to do differently.
What Iron Bank Provides
Iron Bank is hosted at registry1.dso.mil and contains hardened images for:
- Common base images: RHEL UBI 8/9, Ubuntu, Alpine
- Runtime platforms: Python, Node.js, Java JDK
- Database images: PostgreSQL, Redis
- Middleware: Nginx, HAProxy, Envoy
- Infrastructure tools: Terraform, kubectl, Helm
Each image in Iron Bank has gone through DISA hardening, STIG compliance review, and Anchore/Trivy vulnerability scanning. The hardening findings are documented in the image's Container Approval Record (CAR) — a set of STIG findings, justifications, and any accepted risk items.
Critically: Iron Bank images carry DoD-approved STIGs applied at the image level. When you build your application on an Iron Bank base, you inherit that approved hardening — you don't have to re-harden the base image yourself.
Accessing Iron Bank
Iron Bank access requires:
- A DoD PKI certificate (CAC or software certificate) or an approved username/password
- Registration on repo1.dso.mil (Platform One's GitLab instance)
- Organization approval (your program or company must be registered as an authorized user)
Once registered, pull images using standard Docker/Podman commands with Iron Bank credentials:
docker login registry1.dso.mil -u <username> -p <password>
docker pull registry1.dso.mil/ironbank/redhat/ubi/ubi8:8.9 For CI/CD pipelines, store Iron Bank credentials as pipeline secrets — never hardcode them in the Dockerfile or pipeline configuration.
Building on Iron Bank Base Images
The foundational change when using Iron Bank is your FROM line:
# Commercial / non-approved base (not acceptable for IL4+ programs)
FROM python:3.11-slim
# Iron Bank approved base
FROM registry1.dso.mil/ironbank/opensource/python/python39:3.9.18
# Application layer
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# STIG requirement: run as non-root
USER 1001
EXPOSE 8080
CMD ["python", "app.py"] Key changes from commercial base usage:
USER 1001(or another non-zero UID) is required by STIG — root-user containers fail DoD admission- Package installation is more constrained — Iron Bank bases have restricted package managers; you install only what your application needs
- No package manager caching —
--no-cache-dirfor pip,--no-cachefor apk/yum — reduces image attack surface
Pipeline Integration for Iron Bank Compliance
The CI/CD pipeline must validate that your application image, built on an Iron Bank base, doesn't introduce new vulnerabilities that weren't present in the approved base.
# GitLab CI pipeline for Iron Bank-based application
stages:
- build
- scan
- validate
- deploy
variables:
IRON_BANK_BASE: "registry1.dso.mil/ironbank/opensource/python/python39:3.9.18"
IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
build:
stage: build
script:
- docker login registry1.dso.mil -u $IRON_BANK_USER -p $IRON_BANK_PASSWORD
- docker build --build-arg BASE=$IRON_BANK_BASE -t $IMAGE .
- docker push $IMAGE
scan-vulnerabilities:
stage: scan
image: aquasec/trivy:latest
script:
# Scan only the application layer delta — not the approved base
- trivy image
--severity HIGH,CRITICAL
--exit-code 1
--ignore-unfixed
--skip-files "/usr/lib/*,/usr/local/lib/python3.9/*"
$IMAGE
artifacts:
reports:
container_scanning: trivy-results.json
validate-non-root:
stage: validate
script:
# Verify the container won't run as root
- |
USER_DIRECTIVE=$(docker inspect $IMAGE | jq -r '.[0].Config.User')
if [[ "$USER_DIRECTIVE" == "0" ]] || [[ "$USER_DIRECTIVE" == "root" ]] || [[ -z "$USER_DIRECTIVE" ]]; then
echo "STIG VIOLATION: Container is configured to run as root"
exit 1
fi The --skip-files flag in Trivy excludes the base system libraries from scan (they're already validated in the Iron Bank CAR) and focuses the scan on your application dependencies — where new vulnerabilities would be introduced.
The Container Approval Record (CAR)
Every Iron Bank image has a CAR documenting:
- Which STIG checks were applied
- The status of each check (Open, Closed, Not Applicable, Not a Finding)
- For any "Open" findings: the accepted risk documentation and justification
When building your System Security Plan (SSP), the CAR is your evidence that the container base layer meets DoD requirements. Your team's responsibility is to:
- Reference the CAR for your specific Iron Bank image version
- Document your application-layer additions and their security review
- Demonstrate that no new critical/high findings were introduced above the approved base
This division of responsibility — Iron Bank handles base hardening, your team handles the application layer — is the core value proposition of Platform One.
Helm Charts and Iron Bank Images
When deploying on Kubernetes with Helm, image references in values.yaml should point to Iron Bank:
# values.yaml
image:
repository: registry1.dso.mil/ironbank/opensource/python/python39
tag: "3.9.18"
pullPolicy: IfNotPresent
imagePullSecrets:
- name: iron-bank-registry-credentials The iron-bank-registry-credentials secret must be created in the namespace before deployment — it contains the Iron Bank credentials needed for the node to pull the image.
For more on production Kubernetes patterns for regulated environments, see our guide on Kubernetes in regulated environments.
What This Means for Your ATO Package
Using Iron Bank base images significantly simplifies your container layer documentation in the ATO package:
- Base image STIG compliance is evidenced by the CAR (reference, don't re-document)
- Application layer scan results (Trivy pipeline output) show what you added is clean
- Pipeline CI/CD logs serve as ongoing evidence that every deployment was scanned
For teams building toward continuous ATO automation, this evidence is automatically collected and exportable.
Discuss Platform One and Iron Bank pipeline integration → rutagon.com/contact
Frequently Asked Questions
Is using Iron Bank required for all DoD programs?
Using Iron Bank (or an equivalent DoD-approved container registry) is required for programs running on Platform One and is strongly preferred for programs seeking DoD ATO at IL4+. The specific requirement depends on your program's ATO conditions and the policies of your authorizing official.
Can I use a custom Iron Bank image if the base image I need doesn't exist?
Yes. Iron Bank has a contribution process where program teams can submit new base images for hardening and approval. The process requires submitting the Dockerfile and going through the Iron Bank hardening pipeline — turnaround is typically weeks, not days. Alternatively, programs with a justified need can run a non-Iron Bank image with documented accepted risk.
What is the difference between Platform One and Iron Bank?
Platform One is the DoD's enterprise DevSecOps platform — including CI/CD pipelines, GitLab hosting, and supporting tools. Iron Bank is specifically the hardened container image repository within Platform One. You can use Iron Bank images without using the full Platform One pipeline, though the two are designed to work together.
How often are Iron Bank images updated?
Iron Bank images are typically updated monthly with the latest security patches and STIG updates. Pinning to a specific image tag in production (rather than latest) is required practice — latest can change unexpectedly and introduce new findings mid-sprint.
What happens when an Iron Bank image I'm using gets a new critical CVE?
If a critical CVE is discovered in a base image, Iron Bank typically releases an updated image within days. Your program's response: update the pinned image tag, re-run the pipeline, and document the update in your continuous monitoring records. Automated Dependabot/Renovate-style tools can flag when Iron Bank image updates are available.
Discuss your project with Rutagon
Contact Us →