Install in FIPS mode
CMMC requirement 3.13.11 asks for FIPS-validated cryptography wherever it protects CUI. Gardience stores your System Security Plan, proof files, and evidence packs, and it controls the machines that hold CUI. Many teams treat it as part of the CUI boundary, so an assessor asks which cryptographic modules protect it and for their CMVP certificate numbers. A FIPS install answers that question.
What a FIPS install is
#A FIPS install runs Gardience's FIPS images instead of the standard ones. Every container that does cryptography (the console, the Salt master, the web server, the runner, and the config keeper) is built on Red Hat's Universal Base Image 9, and its cryptography is Red Hat's OpenSSL, except what is listed under What is outside the module. That OpenSSL's FIPS provider is a validated module:
| Module | Version | CMVP certificate | Standard |
|---|---|---|---|
| Red Hat Enterprise Linux 9 - OpenSSL FIPS Provider | 3.0.7-395c1a240fbfffd8 | #4857 | FIPS 140-3, active until 2029-10-28 |
RHEL's OpenSSL reads the host kernel's FIPS flag. On a host in FIPS mode, every container loads the FIPS provider in approved mode, and the provider refuses every algorithm it does not approve. For example MD5, Ed25519, X25519, and the ChaCha20 TLS suites are refused.
Things to know:
- The images hold exactly the validated build. Red Hat later rebuilt the provider for a security fix (package 3.0.7-11.el9_8, version 3.0.7-cda111b5812c30d4). That build is not on certificate #4857 yet, so the FIPS images keep the validated build and the image build stops if the version is anything else. A RHEL 9.8 host itself runs the newer build. Gardience's containers do not use the host's OpenSSL.
- Python uses the module too. The console and the Salt master run RHEL's Python. The
cryptographypackage from PyPI carries its own OpenSSL, which is not validated, so the FIPS images build it from source against RHEL's OpenSSL. The image build stops if it is linked to anything else. - Salt runs in its FIPS mode. The master is set with
fips_mode: Trueand RSA with SHA-224 (OAEP for keys, PKCS#1 v1.5 for signatures), because Salt's SHA-1 defaults are refused by the module. - What changes in the console. Evidence packs and signed reports are signed with ECDSA P-384 and SHA-384 instead of Ed25519 (Ed25519 is not in the validated module). Secrets in the vault are sealed with AES-256-CBC and HMAC-SHA-256, all inside the module. Git deploy keys and the SFTP backup key are ECDSA P-256. TLS to browsers offers only AES-GCM suites.
Before you start
#- A RHEL 9 server (the platform certificate #4857 lists), 4 GB of memory or more, with internet access for the first build. Other RHEL 9 rebuilds in FIPS mode run the same module, and the installer says so, but your assessor may ask about the platform.
- FIPS mode on, before you install:
sudo fips-mode-setup --enable
sudo reboot
sudo fips-mode-setup --check # FIPS mode is enabled.- Plan for disk encryption on the server. Proof files, the SSP, and evidence packs are files on the server's disk. On RHEL 9, LUKS disk encryption is done by the Red Hat Enterprise Linux 9 Kernel Cryptographic API, which has certificates #5445 (kernel 5.14.0-427.124.1.el9_4) and #5034 (kernel 5.14.0-284.57.1.el9_2). Each certificate covers its exact kernel version.
Install
#On a host in FIPS mode, the installer picks the FIPS images on its own:
sudo ./install/install.sh --license /path/to/gardience-license.jsonYou can also ask for it with --fips. The installer refuses --fips on a host that is not in FIPS mode, and changes nothing. To install the standard images on a FIPS host, use --no-fips.
When it finishes, the installer checks every container and prints one line:
FIPS 140: on: every container runs Red Hat's OpenSSL FIPS provider in approved mode (CMVP #4857)Check again any time (for example after a host update):
sudo /opt/gardience/gardience fips-checkIt lists each container, the module it runs, and whether it is in approved mode. The result is shown on the console under Security > FIPS 140.
Security > FIPS 140
#The page shows whether the host is in FIPS mode, the module each container runs and its CMVP certificate number (linked to the NIST page), and the host kernel against the disk encryption certificates. A version that is not listed on a certificate gets no number, and the page says so. On a FIPS install it also lists machines whose Salt agent is older than 3007 (see Agents on a FIPS server). Refused here tries MD5, Ed25519, and X25519 when the page loads, so you can show an assessor that the module refuses them.
Agents on a FIPS server
#A FIPS server refuses Salt's SHA-1 defaults, so agents must use SHA-224. Gardience writes these settings into every agent it installs (enrollment, Add machines, and the onboarding scripts):
fips_mode: True
encryption_algorithm: OAEP-SHA224
signing_algorithm: PKCS1v15-SHA224Only Salt 3007 and later use these settings (Gardience installs 3008.3). An agent you installed yourself needs the same three lines in its minion.d folder.
Agents on Salt 3006. Salt 3006 does not know these settings. A 3006 agent still connects and answers jobs (tested with 3006.28 on Ubuntu 24.04 and Windows Server 2022), because it ignores them and uses Salt's older key exchange, RSA-OAEP with SHA-1, which the module still accepts. So nothing fails, and nothing on the machine tells you. Gardience does: the machine list marks these agents "no SHA-224 on this FIPS server", and Security > FIPS 140 lists them. Upgrade them to Salt 3008.3 (on Windows, the 3008.3 installer; on Linux, unlock the salt packages and install 3008.3), then run the enrollment script on them again.
The agent's own cryptography runs on the managed machine, in the OpenSSL that Salt's agent package carries. That OpenSSL is not in FIPS mode by itself, even on a machine in FIPS mode. What Gardience does about it:
- Linux in FIPS mode. The enrollment script installs a systemd drop-in,
/etc/systemd/system/salt-minion.service.d/gardience-fips.conf. Before every start of the agent, it checks whether the machine is in FIPS mode and has a system FIPS provider (/usr/lib64/ossl-modules/fips.so). If both are true, the agent's OpenSSL uses that provider in approved mode only (/etc/salt/gardience-openssl-fips.cnf). So you can enroll a machine first and turn on FIPS mode later: after the restart into FIPS mode, the agent uses the provider on its own. The agent's OpenSSL then refuses MD5 and SHA-1 signatures, and on RHEL 9 and 10 also Ed25519. Salt's Python keeps its own MD5 code outside OpenSSL; Salt uses SHA-256 for its file checks. Verified with Salt 3008.3 on RHEL 9 and 10, Oracle Linux 9 and 10, Rocky 9, Amazon Linux 2023, and SUSE 15 SP6. Whether that provider is on a CMVP certificate depends on the machine: on RHEL 9 up to 9.7, theopenssl-fips-providerpackage holds the build on certificate #4857; RHEL 9.8 ships a later build that is not on it yet. Check withopenssl list -providerson the machine. An agent you installed yourself gets the same files from the enrollment script (safe to run again). - SUSE Linux Enterprise 15 SP6. SUSE's FIPS pattern does not install OpenSSL 3's FIPS provider. Install the
libopenssl-3-fips-providerpackage, then restart the agent (or the machine): the agent then uses it like on RHEL. Verified on AWS with SUSE 15 SP6 in FIPS mode. - Ubuntu. Ubuntu's FIPS modules come with an Ubuntu Pro subscription, and their provider is not at
/usr/lib64/ossl-modules, so the agent on Ubuntu Pro FIPS starts as before. Not verified. - RHEL 8, Oracle Linux 8, and Rocky 8. These have no FIPS provider: their FIPS module is built into the system's OpenSSL 1.1.1, which the agent does not use. The agent keeps working on these machines in FIPS mode, but its own cryptography is outside the module, as on Windows. Record this in your SSP.
- Windows. The Windows agent's OpenSSL has no FIPS provider. The Windows FIPS policy ("System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing") puts Windows' own cryptography in FIPS mode, not Salt's. The connection is protected on the server side by the module above; on the Windows machine, it is not FIPS-validated today. Record this in your SSP and plan of action for 3.13.11.
Gardience checks each machine's FIPS mode (CMMC setting FIPS-validated cryptography mode).
License and release signatures
#From 1.28, licenses and releases carry a second signature, ECDSA P-384 with SHA-384 (FIPS 186-5), next to Ed25519. A FIPS install checks only that one, inside the module:
- The license. A license file issued from 1.28 on has a
signature_p384field, checked inside the module. Security > FIPS 140 says which kind of license this install has. A license file issued before 1.28 carries only Ed25519, so it is checked with libsodium, outside the module, as before (it protects none of your data). To move it inside the module, download a new license file from your account at gardience.com/account and install it. - Releases.
gardience upgradechecks the release's.sha256.p384.siginside the module and refuses a release without one. The P-384 release key comes with your first 1.28 or later release. Until then (a FIPS install from before 1.28), the upgrade checks Ed25519 with OpenSSL's default provider, outside the module. See Upgrade.
What is outside the module
#- Licenses issued before 1.28. See above.
- Windows agents. See above.
- Salt's agent sign-in token. Salt proves an agent's identity with an RSA signature made through OpenSSL's low-level RSA functions, which do not run through the FIPS provider. The keys and data of the connection are protected inside the module.
- Secrets sent to machines. A vault secret passed to a playbook run, a LUKS disk passphrase, and a LAPS password travel to the agent sealed with AES-256-GCM, computed by the module, but with a nonce Gardience generates. FIPS 140-3 counts GCM with a nonce made outside the module as a non-approved use. Underneath, Salt's encrypted connection carries them, inside the module on the server. Moving this to AES-256-CBC with HMAC-SHA-256, as the vault already uses, is planned for the next release. Record it in your SSP until then.
- Local console passwords. Local accounts' passwords are stored as SHA-512 crypt hashes and checked by the system's crypt library, not OpenSSL. Directory sign-in (LDAP, Okta, or Microsoft Entra ID) keeps password checks out of Gardience.
- Docker. Docker Engine's own code (image downloads, its API socket) does not handle your data.
Backups
#Encrypted backups (gardience backup --passphrase-file F) use the host's OpenSSL for AES-256-CBC with PBKDF2, so on a FIPS host they are made inside the host's FIPS module.
Upgrades
#gardience upgrade keeps a FIPS install a FIPS install, and refuses to continue if the host is no longer in FIPS mode. Run gardience fips-check afterwards.