FIPS 140-3 Images

Every Hatchet server image is also published with a -fips suffix. Tags match the regular images.

What a -fips image guarantees

  • Every Go binary is built with GOFIPS140=v1.0.0, which links the validated Go Cryptographic Module (CMVP certificate #4985) and bakes fips140=on into the binary. The module runs its integrity self-test at startup and TLS is restricted to approved cipher suites and curves. You can verify a binary with go version -m <binary>: it reports GOFIPS140=v1.0.0-c2097c7c and DefaultGODEBUG=fips140=on.
  • A binary built with GOFIPS140 refuses to start if GODEBUG=fips140=off is set in its environment.
  • On top of the module, the server refuses non-approved choices: bcrypt password hashes, an AES-GCM master keyset, HMAC-MD5 and HMAC-SHA1 inbound webhooks, and HMAC keys shorter than 112 bits (session cookie secrets, webhook signing secrets).
  • FIPS images do not ship the openssl, curl or psql command-line tools. hatchet-admin quickstart refuses the certificate stage on a FIPS build so you need to provide your own certificates or pass --skip certs.

libcrypto3 and libssl3 are present in the image because the Alpine base depends on them. Nothing in Hatchet loads them: all binaries are built with CGO_ENABLED=0 and use only the Go module. Security scanners may still list them.

Requirements

  • Postgres must use scram-sha-256 password authentication. md5 is not approved. Postgres 14 and later default to SCRAM.
  • Cookie secrets, inbound webhook signing secrets and any other HMAC secret must be at least 14 bytes.
  • Keysets must be generated by a FIPS build of hatchet-admin, which produces AES-CTR-HMAC-SHA256 keys. Regular builds generate AES-GCM keys, which a FIPS build refuses.

Moving between image kinds

The two directions are not symmetric.

  • Regular to FIPS needs the steps below. A FIPS image refuses an AES-GCM master key and bcrypt password hashes, so keysets must be regenerated, encrypted secrets re-created, and passwords reset.
  • FIPS to regular needs nothing. A regular image reads a CTR-HMAC master key, keeps using CTR-HMAC data keys for it, decrypts every secret the FIPS image wrote, and verifies PBKDF2 passwords. API tokens and sessions stay valid.

One thing to watch after a rollback: users created or password-reset while on the regular image get bcrypt hashes. If you later return to the FIPS image, those users are refused until reset with hatchet-admin user set-password. Everything else written by the regular image remains readable by the FIPS image.

Switching an existing deployment to -fips

If you must move an existing database, expect these three steps. None of them is automatic.

  1. Regenerate the keysets. The server refuses to start on an AES-GCM master key. Run hatchet-admin keyset create-local-keys from a FIPS build and install the new master, private JWT and public JWT keysets together. The JWT keysets are stored encrypted under the master key, so they cannot be reused.
  2. Re-create encrypted secrets and reissue tokens. Anything encrypted under the old master key is unreadable afterwards: OAuth tokens, Slack integrations and inbound webhook credentials. Every API token was signed with the old JWT keyset, so workers need new tokens.
  3. Reset passwords. Users with bcrypt hashes get invalid credentials on login and the server logs a warning naming the fix. Set a new password with:
printf '%s\n' "$NEW_PASSWORD" | hatchet-admin user set-password --config ./config --email user@example.com --password-stdin

This writes a PBKDF2-HMAC-SHA256 hash and revokes the user's existing sessions.

Last updated on October 12, 2026

On this page