Methodology

ARMORRED employs a systematic approach to building security-hardened container images with complete transparency into the hardening process. Every image is built from source using reproducible builds, scanned with industry-standard tools, and signed cryptographically. The methodology ensures that users can verify what protections are applied, audit the changes made, and trust the supply chain.

Build Pipeline

ARMORRED images are built using NixOS, a purely functional package manager that enables fully reproducible builds. Unlike traditional container builds that inherit uncertainty from base images and package repositories, Nix builds are deterministic and reproducible from source.

Reproducible Builds from Scratch

Each ARMORRED image is built FROM scratch rather than inheriting from Debian, Alpine, or other distribution base images. This eliminates inherited vulnerabilities and reduces the attack surface to only the components explicitly required for the application to function.

The Nix build process:

  1. Declares all dependencies explicitly with cryptographic hashes
  2. Compiles software from source with hardening flags enabled
  3. Produces bit-for-bit reproducible artifacts
  4. Creates minimal filesystem hierarchies containing only required components
  5. Generates OCI-compliant container images

This approach aligns with SLSA (Supply-chain Levels for Software Artifacts) Level 3 requirements for build platform integrity and reproducibility.1

Hardening Compilation

During the build phase, C/C++ software is compiled with comprehensive hardening flags:

FlagPurpose
-fstack-protector-strongStack canary protection against buffer overflows
-fPIE -piePosition Independent Executable for ASLR
-Wl,-z,relro,-z,nowFull RELRO (Read-Only Relocations)
-D_FORTIFY_SOURCE=2Fortified libc functions with runtime bounds checking
-fsanitize=safe-stackSafeStack separation of safe and unsafe stack objects
-fsanitize=cfiControl Flow Integrity (locked tier only)

These flags are applied systematically across all compiled components, providing defense-in-depth against memory corruption vulnerabilities.

Scanning and Analysis

Each built image undergoes comprehensive security analysis before publication. The scanning pipeline uses open source tools maintained by Anchore, OWASP, and the security community.

SBOM Generation with Syft

Syft analyzes the container image and generates a complete Software Bill of Materials in CycloneDX 1.6 format:


$ syft packages localhost/nginx:1.26.3-hardened -o cyclonedx-json
[+] Cataloging image... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%
[+] Cataloger: nix-cataloger
[+] Found 19 packages
[+] SBOM written to stdout

Syft identifies all packages, libraries, and dependencies with their versions, package URLs (purls), and cryptographic checksums. The SBOM enables vulnerability correlation, license compliance verification, and incident response.2

Vulnerability Scanning with Grype

Grype consumes the generated SBOM and cross-references components against multiple vulnerability databases:


$ grype sbom:nginx-hardened.sbom.json
[+] Scanning SBOM for vulnerabilities
[+] Matched 19 packages against 5 vulnerability databases
[+] Severity distribution: Critical (0), High (1), Medium (0), Low (0)

Vulnerability sources include:

  • National Vulnerability Database (NVD)
  • GitHub Security Advisories
  • OSV (Open Source Vulnerabilities)
  • Vendor-specific security feeds

This multi-source approach reduces false negatives by ensuring coverage across ecosystems.

Binary Security Analysis with checksec

The checksec tool verifies that compiled binaries have hardening features enabled:


$ checksec --file=/nix/store/...-nginx-1.26.3/bin/nginx
RELRO STACK CANARY NX PIE RPATH RUNPATH
Full RELRO Canary found NX enabled PIE enabled No RPATH RUN path

checksec output confirms the presence of:

  • Full RELRO: prevents GOT (Global Offset Table) overwrite attacks
  • Stack canaries: detects buffer overflows before exploitation
  • NX (No eXecute): prevents code execution on the stack
  • PIE: enables ASLR for the executable itself

For advanced hardening, checksec also detects SafeStack and Control Flow Integrity when enabled (locked tier).

Dual-SBOM Comparison

ARMORRED provides transparency into the hardening process by generating SBOMs for both the hardened image and the upstream reference image. This dual-SBOM approach enables users to audit exactly what changed during hardening.

Upstream SBOM

The upstream SBOM documents the official container image from Docker Hub or the vendor's registry as it exists before ARMORRED modifications:


$ syft packages nginx:1.26.3 -o cyclonedx-json > upstream.sbom.json
[+] Found 150 packages

Comparison Metrics

The build pipeline calculates reduction metrics by comparing the hardened image against upstream:

MetricCalculation
Size reduction(upstream_bytes - armorred_bytes) / upstream_bytes
Component reduction(upstream_packages - armorred_packages) / upstream_packages
Vulnerability reduction(upstream_vulns - armorred_vulns) / upstream_vulns

For nginx 1.26, the hardened tier achieves:

  • 38.5% size reduction (196 MB to 121 MB)
  • 87.3% component reduction (150 to 19 packages)
  • 99.1% vulnerability reduction (117 to 1 CVE)

The locked tier achieves even greater reductions:

  • 63.1% size reduction (196 MB to 72 MB)
  • 86.7% component reduction (150 to 20 packages)
  • 99.1% vulnerability reduction (117 to 1 CVE)

Cryptographic Signing

After building and scanning, images are signed using Sigstore cosign.3 This provides:

  • Authenticity: Images are cryptographically bound to the ARMORRED project
  • Integrity: Any tampering after signing is detected during verification
  • Verification: Users verify signatures using the public key published at https://armorred.org/cosign.pub

The signing process integrates with the container registry to attach signatures as OCI artifacts alongside the image:


$ cosign sign --key cosign.key ghcr.io/armorred/nginx:1.26-hardened
[+] Signing image
[+] Pushing signature to ghcr.io/armorred/nginx

Users verify signatures before deployment using the public key:


$ cosign verify --key https://armorred.org/cosign.pub \
ghcr.io/armorred/nginx:1.26-hardened

Verification for ghcr.io/armorred/nginx:1.26-hardened --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key

Continuous Monitoring

Images are rescanned daily against updated vulnerability databases. When new CVEs are published:

  1. The scanning pipeline automatically detects affected components
  2. Impact assessment determines if the vulnerability is exploitable in the ARMORRED context
  3. If exploitable, a new hardened build is published within 24 hours
  4. Users are notified through GitHub releases and security advisories

This continuous monitoring ensures that ARMORRED images remain protected against emerging threats.

References


1

SLSA (Supply-chain Levels for Software Artifacts). https://slsa.dev/spec/v1.0/

2

Anchore. "Syft SBOM Generator." https://github.com/anchore/syft

3

Sigstore. "Cosign: Container Signing." https://docs.sigstore.dev/signing/overview/