---
title: "FIPS 140 Compliance: Validated Cryptography, FIPS-Enabled Runtimes, and Kubernetes Deployment"
description: "Implementing FIPS 140-2/140-3 compliant cryptography in applications and infrastructure — understanding the standard, using FIPS-validated modules in Go, Python, and Node.js, building FIPS container images, and running FIPS-compliant Kubernetes clusters."
url: https://agent-zone.ai/knowledge/security/fips-140-compliance/
section: knowledge
date: 2026-02-22
categories: ["security"]
tags: ["fips","fips-140","cryptography","compliance","federal","encryption","fedramp"]
skills: ["fips-compliance","cryptographic-configuration","compliant-container-builds"]
tools: ["openssl","go","python","nodejs","kubernetes","red-hat-ubi"]
levels: ["intermediate"]
word_count: 1699
formats:
  json: https://agent-zone.ai/knowledge/security/fips-140-compliance/index.json
  html: https://agent-zone.ai/knowledge/security/fips-140-compliance/?format=html
  api: https://api.agent-zone.ai/api/v1/knowledge/search?q=FIPS+140+Compliance%3A+Validated+Cryptography%2C+FIPS-Enabled+Runtimes%2C+and+Kubernetes+Deployment
---


# FIPS 140 Compliance

FIPS 140 (Federal Information Processing Standard 140) is a US and Canadian government standard for cryptographic modules. If you sell software to US federal agencies, process federal data, or operate under FedRAMP, you must use FIPS 140-validated cryptographic modules. Many regulated industries (finance, healthcare, defense) also require or strongly prefer FIPS compliance.

FIPS 140 does not tell you which algorithms to use — it validates that a specific implementation of those algorithms has been tested and certified by an accredited lab (CMVP — Cryptographic Module Validation Program).

## FIPS 140-2 vs FIPS 140-3

FIPS 140-2 was the standard from 2001 to 2022. FIPS 140-3 replaced it. Key differences:

| Aspect | FIPS 140-2 | FIPS 140-3 |
|---|---|---|
| Status | No new validations accepted after 2022 | Current standard |
| Basis | Standalone spec | Based on ISO/IEC 19790 and 24759 |
| Security levels | 1-4 | 1-4 (aligned with ISO) |
| Testing | CMVP labs | Same CMVP labs, updated test requirements |
| Transition | Existing validations remain valid until sunset | New submissions must target 140-3 |

Most existing FIPS-validated modules were certified under 140-2. These remain valid until their certificate's sunset date. New modules must target 140-3.

For practical purposes as a developer: you need to use a cryptographic module that has an active CMVP validation certificate. Whether it is 140-2 or 140-3 depends on when it was validated.

## What FIPS Compliance Means in Practice

FIPS compliance is not about your application code directly. It is about the cryptographic library your application uses. Specifically:

1. **All cryptographic operations** (encryption, hashing, signing, key generation, random number generation, TLS handshakes) must go through a FIPS-validated module.
2. **The module must operate in FIPS mode**, which disables non-approved algorithms.
3. **You must be able to demonstrate** that your application uses the validated module and does not bypass it.

### Approved Algorithms (FIPS Mode)

When a cryptographic module runs in FIPS mode, only approved algorithms are available:

| Function | Approved | Not Approved in FIPS |
|---|---|---|
| Symmetric encryption | AES-128, AES-192, AES-256 (GCM, CBC, CTR) | Blowfish, DES, 3DES (deprecated), RC4, ChaCha20 |
| Hashing | SHA-256, SHA-384, SHA-512, SHA-3 | MD5, SHA-1 (signing only deprecated) |
| Asymmetric encryption | RSA (2048+), ECDSA (P-256, P-384, P-521) | RSA < 2048, Ed25519, X25519 |
| Key exchange | ECDH (P-256, P-384), DH (2048+) | X25519, X448 |
| MAC | HMAC-SHA-256, CMAC-AES | Poly1305 |
| RNG | SP 800-90A DRBG (CTR_DRBG, Hash_DRBG, HMAC_DRBG) | /dev/urandom directly (must seed DRBG) |
| TLS | TLS 1.2, TLS 1.3 (with approved cipher suites) | TLS 1.0, TLS 1.1 |

**Important:** Ed25519 and ChaCha20-Poly1305 are widely used in modern systems (WireGuard, SSH, etc.) but are not currently FIPS-approved. This is a common source of compliance failures.

### FIPS TLS Cipher Suites

In FIPS mode, only these TLS cipher suites are available:

```
# TLS 1.2 (FIPS-approved)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

# TLS 1.3 (FIPS-approved)
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
```

TLS 1.3's `TLS_CHACHA20_POLY1305_SHA256` is not FIPS-approved.

## FIPS in Go

Go's standard `crypto` package is not FIPS-validated. For FIPS compliance, you have two options:

### Microsoft Go (go-crypto-fips)

Microsoft maintains a Go fork that uses BoringCrypto (Google's FIPS-validated module) for all cryptographic operations:

```bash
# Use Microsoft's Go toolchain
go install golang.org/dl/gotip@latest
# Or use the microsoft/go fork directly
```

When built with the `goexperiment` tag for BoringCrypto, Go uses BoringSSL's FIPS-validated module instead of the standard Go crypto:

```bash
# Build with BoringCrypto
GOEXPERIMENT=boringcrypto go build -o myapp ./cmd/myapp
```

Verify FIPS mode is active:

```go
import "crypto/boring"

func init() {
    if !boring.Enabled() {
        log.Fatal("FIPS mode (BoringCrypto) is not enabled")
    }
}
```

When BoringCrypto is enabled, the standard Go `crypto` packages automatically delegate to BoringSSL. Your application code does not need to change — `crypto/tls`, `crypto/aes`, `crypto/sha256` all use the FIPS-validated module transparently.

### Red Hat Go Toolset

Red Hat provides a Go toolchain with OpenSSL FIPS integration:

```dockerfile
FROM registry.access.redhat.com/ubi9/go-toolset:latest AS builder
COPY . .
RUN go build -tags strictfipsruntime -o /app ./cmd/myapp
```

This links against the FIPS-validated OpenSSL module on the RHEL/UBI base image.

## FIPS in Python

Python's standard `hashlib` and `ssl` modules use OpenSSL under the hood. FIPS compliance depends on the underlying OpenSSL library being FIPS-validated and running in FIPS mode.

### Using OpenSSL FIPS Provider (OpenSSL 3.x)

OpenSSL 3.x has a modular architecture with a FIPS provider:

```python
import ssl
import hashlib

# Verify OpenSSL version and FIPS support
print(ssl.OPENSSL_VERSION)

# On a FIPS-enabled system, non-approved algorithms raise errors:
try:
    hashlib.md5(b"test")  # Will raise if FIPS mode enforced at OS level
except ValueError as e:
    print(f"FIPS mode active: {e}")
```

### RHEL/UBI with FIPS Mode

The simplest path is running Python on a FIPS-enabled RHEL or UBI system:

```dockerfile
FROM registry.access.redhat.com/ubi9/python-311:latest

# FIPS mode is controlled at the OS level
# When the host runs in FIPS mode, OpenSSL inside the container uses FIPS
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
```

Enable FIPS on the host:

```bash
# RHEL 9
sudo fips-mode-setup --enable
sudo reboot
# Verify
fips-mode-setup --check
```

### Python Libraries to Audit

Some Python packages bundle their own crypto instead of using OpenSSL:

| Library | FIPS Concern |
|---|---|
| `cryptography` | Uses OpenSSL by default — FIPS-compatible on FIPS-enabled systems |
| `pynacl` / `libnacl` | Uses libsodium (Ed25519, ChaCha20) — NOT FIPS-approved algorithms |
| `pycryptodome` | Standalone crypto implementation — NOT FIPS-validated |
| `paramiko` | Uses `cryptography` — check that it does not negotiate non-FIPS ciphers |
| `bcrypt` | bcrypt is not a FIPS-approved algorithm |

Audit all dependencies that perform cryptographic operations. A single non-FIPS library in your dependency tree breaks compliance.

## FIPS in Node.js

Node.js uses OpenSSL for its `crypto` module. Enable FIPS mode:

```javascript
// Enable FIPS at startup
const crypto = require('crypto');
crypto.setFips(1);

// Or via environment variable
// NODE_OPTIONS=--enable-fips node app.js

// Verify
console.log('FIPS mode:', crypto.getFips() === 1);
```

When FIPS is enabled, Node.js rejects non-approved algorithms:

```javascript
// This will throw in FIPS mode
try {
    crypto.createHash('md5').update('test').digest('hex');
} catch (e) {
    console.error('MD5 blocked in FIPS mode:', e.message);
}

// This works
crypto.createHash('sha256').update('test').digest('hex');
```

**Node.js must be built against a FIPS-validated OpenSSL.** The standard Node.js binary from nodejs.org uses OpenSSL but is not FIPS-validated. Use Red Hat's Node.js distribution or build Node.js against a FIPS-validated OpenSSL library.

## FIPS Container Images

### Red Hat Universal Base Image (UBI)

UBI images include FIPS-validated OpenSSL:

```dockerfile
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest

# OpenSSL on UBI 9 is FIPS-validated (certificate #4282 or newer)
# FIPS mode is inherited from the host kernel

RUN microdnf install -y openssl && microdnf clean all

# Verify FIPS-validated OpenSSL
RUN openssl version && openssl list -providers
```

### Alpine Is Not FIPS-Compatible

Alpine Linux uses musl libc and links against LibreSSL or OpenSSL builds that are not FIPS-validated. Do not use Alpine base images for FIPS workloads.

### Ubuntu FIPS

Ubuntu Pro includes FIPS-validated packages:

```dockerfile
FROM ubuntu:22.04

# Ubuntu FIPS requires Ubuntu Pro subscription
# Packages: libssl3-fips, openssl-fips-provider
RUN apt-get update && apt-get install -y libssl3 openssl
```

### Verifying FIPS in a Container

```bash
# Check if FIPS mode is active
cat /proc/sys/crypto/fips_enabled
# Returns 1 if FIPS mode is on, 0 if off

# Check OpenSSL FIPS provider
openssl list -providers
# Should show "fips" provider

# Test that non-approved algorithms are blocked
openssl md5 /dev/null 2>&1 || echo "MD5 blocked (FIPS active)"
```

## FIPS-Compliant Kubernetes

### Node-Level FIPS

FIPS starts at the OS level. Kubernetes nodes must run a FIPS-enabled operating system:

- **RHEL 9 with FIPS mode** — `fips-mode-setup --enable`
- **Ubuntu Pro FIPS** — FIPS-certified kernel and crypto modules
- **Amazon Linux 2023** — FIPS mode available via configuration

When the host kernel has FIPS enabled (`/proc/sys/crypto/fips_enabled = 1`), containers inherit FIPS mode. The kernel blocks non-approved crypto operations system-wide.

### Managed Kubernetes with FIPS

| Provider | FIPS Support |
|---|---|
| **EKS** | Use Amazon Linux 2023 AMI with FIPS; or Bottlerocket FIPS variant |
| **AKS** | FIPS-enabled node pools available (`--enable-fips-image`) |
| **GKE** | Use Container-Optimized OS with FIPS boot option; or Ubuntu FIPS nodes |
| **OpenShift** | FIPS mode enabled at install time; all components use FIPS-validated crypto |

```bash
# AKS: create a FIPS node pool
az aks nodepool add \
  --resource-group mygroup \
  --cluster-name mycluster \
  --name fipspool \
  --enable-fips-image \
  --node-count 3
```

### etcd Encryption

etcd stores all Kubernetes state. FIPS requires that encryption at rest uses approved algorithms:

```yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
      - configmaps
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-32-byte-key>  # AES-256
      - identity: {}
```

Use `aescbc` (AES-CBC) or `aesgcm` (AES-GCM). Do not use `secretbox` — it uses XSalsa20-Poly1305, which is not FIPS-approved.

### Service Mesh TLS

If using Istio or Linkerd for mTLS, verify the sidecar proxy uses FIPS-approved cipher suites:

```yaml
# Istio: restrict to FIPS cipher suites
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: fips-tls
spec:
  host: "*.my-app.svc.cluster.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
      # Envoy uses BoringSSL which is FIPS-validated
      # Configure cipher suites if needed
```

Istio's Envoy proxy uses BoringSSL, which has FIPS-validated builds. Use Istio's FIPS-enabled images for strict compliance.

## FIPS Validation vs FIPS Compliance

These are different things:

- **FIPS validation** means a cryptographic module has been tested and certified by a CMVP-accredited lab. The module has a validation certificate number. Only the exact version tested is validated.
- **FIPS compliance** means your application uses FIPS-validated modules in FIPS mode and does not bypass them. Your application itself is not "FIPS-validated" — the crypto library it uses is.

You do not validate your application with CMVP. You demonstrate that your application uses validated modules and that those modules operate in FIPS mode.

### How to Document FIPS Compliance

For auditors and procurement reviews, document:

1. **Which FIPS-validated module** your application uses (name, version, CMVP certificate number).
2. **How FIPS mode is enforced** (OS-level, application-level, build flags).
3. **Which cryptographic operations** your application performs and that they all use approved algorithms.
4. **Dependency audit** showing no non-FIPS crypto libraries in the dependency tree.
5. **Test evidence** showing non-approved algorithms are rejected (MD5 fails, ChaCha20 fails, etc.).

CMVP certificates are searchable at https://csrc.nist.gov/projects/cryptographic-module-validation-program/validated-modules.

## Common Mistakes

1. **Assuming OpenSSL means FIPS.** OpenSSL has a FIPS provider, but it must be explicitly enabled and the specific build must be validated. Stock OpenSSL from most Linux distributions is not FIPS-validated without additional configuration.
2. **Using Alpine base images for FIPS workloads.** Alpine does not include FIPS-validated crypto libraries. Use UBI, RHEL, or Ubuntu FIPS images.
3. **Forgetting Ed25519 is not FIPS-approved.** Ed25519 is excellent cryptography but is not on the approved algorithms list. SSH keys, WireGuard, and many modern tools default to Ed25519. Switch to ECDSA P-256 or RSA 2048+ for FIPS environments.
4. **Not auditing transitive dependencies.** Your application may use a FIPS OpenSSL, but a dependency deep in your tree might bundle its own crypto. Audit the full dependency graph.
5. **Enabling FIPS mode only in production.** If development and CI environments are not in FIPS mode, you will discover FIPS-incompatible code at deployment time. Enable FIPS mode in all environments.

