Janus FIPS edition
The separate build whose cryptography runs in a FIPS 140-3 validated module, what it changes, and how to prove which edition is running.
What it is
The Janus FIPS edition is a separate build of the same Janus source. Its cryptography runs in the Go Cryptographic Module v1.0.0, FIPS 140-3 validated under CMVP certificate #5247, operating in approved mode. It ships as the ghcr.io/torvanis/janus:<version>-fips image (linux/amd64 and arm64) and as janus-fips standalone binaries and offline image archives for Linux, from the same commit and release as the default edition.
The module is what is validated. Janus itself is not “FIPS validated” or “FIPS certified”, and an authorization to operate belongs to your authorizing official for your system.
Run the FIPS edition when you need cryptography in a FIPS 140-3 validated module: U.S. federal, DoW (DoD) or FedRAMP-style environments, or a contract that requires it. Everyone else runs the default edition.
License and database
The FIPS edition is a Business feature: Business, Enterprise and trial keys include it, Community does not. It refuses to start unless the installed key verifies and is a business or enterprise edition key (trial keys are). With no key, a Community key, or a key that fails verification, it exits with one line saying what is required and “Start a free trial at https://janusedge.com/pricing”.
An expired Business key, even past its grace period, keeps the gateway running: expiry never disrupts a running deployment. The check reads the key’s edition, not its feature list, so Business keys issued before the fips_edition feature existed qualify. It needs no network: mount the key and set JANUS_LICENSE_FILE, which also works for a first install in an air-gapped enclave.
The FIPS edition runs on PostgreSQL only. It refuses to start on SQLite, including the embedded default when JANUS_DATABASE_URL is unset. For the documented STIG configuration, also set JANUS_STIG_PROFILE=true (see the STIG configuration profile page).
What is the same
Both editions protect Janus’s own data with the same approved algorithms: AES-256-GCM with a module-generated random nonce for secrets at rest, HKDF-SHA-256 for subkeys, PBKDF2-HMAC-SHA-512 (400,000 iterations) for passwords, HMAC-SHA-256 for recovery codes and token digests, and TLS 1.2 or newer for direct TLS. Stored data has one format, so moving between editions needs no database migration.
What the FIPS edition switches off
Authenticator codes with HMAC-SHA-1 (the common default): new enrollments use HMAC-SHA-256 and the QR code says so. Apps that honor the setting work, for example 1Password, Bitwarden, Aegis, 2FAS, FreeOTP and Yubico Authenticator; some apps ignore it, and then the first code is not accepted during setup. Existing SHA-1 enrollments are refused with a message asking the person to set up two-factor again; recovery codes still sign them in. For DoW deployments, rely on your identity provider for MFA (CAC/PIV) and keep local accounts as break-glass.
Passwords and recovery codes stored as bcrypt by releases before PBKDF2: bcrypt is not compiled in, so these accounts need an administrator password reset. Accounts that signed in once on a recent default-edition release are already on PBKDF2.
Report export as PDF (the PDF library needs SHA-1, MD5 and RC4): use Excel, CSV or JSON. Reading encrypted PDF attachments in Janus Chat: attach an unencrypted copy.
JANUS_DEV_AUTH is not compiled in; setting it stops startup. LDAP skip_verify and an upstream’s Allow untrusted certificate are refused; trust the CA under Administration → Settings → Certificates (or JANUS_CA_DIR). The DoD PKI root CAs are trusted by default (JANUS_TRUST_DOD_ROOTS).
Administration → Settings → System status → Cryptography lists all of this at runtime, with the module version, the certificate, FIPS 140-3 mode, and how many local accounts still need a password reset or a new authenticator.
Proving which edition is running
Every binary answers --fips-status with its edition, module version, FIPS 140-3 mode and restricted features, and exits non-zero when the FIPS edition would refuse to start. The FIPS edition refuses to start unless it runs the validated module in FIPS mode (for example, GODEBUG=fips140=off stops it). The startup log carries one “cryptography” line with the same facts, and the image contains the build-time output at /fips-status.json.
CI runs the whole test suite a second time as the FIPS edition in Go’s strict fips140=only mode, where any non-approved algorithm fails the build. Government audit artifacts (STIG checklist, FIPS statement, scan reports) describe the FIPS edition and name the exact image tag and digest they were produced against.
docker run --rm ghcr.io/torvanis/janus:<version>-fips --fips-status
# "edition": "fips", "module_version": "v1.0.0",
# "validated_module": true, "cmvp_certificate": "#5247", "fips140_enabled": trueMoving to the FIPS edition
Remove JANUS_DEV_AUTH and any LDAP skip_verify setting, then change the image to :<version>-fips. No migration runs. Afterwards, check System status → Cryptography and reset the passwords it lists; people with a SHA-1 authenticator set up two-factor again. Moving back to the default edition is safe: it reads everything the FIPS edition wrote.