New Ory Agent Security is now live! Claim your complimentary test drive. Get Started!

Skip to main content

Running Ory Polis in FIPS 140-3 mode

Ory Polis for OEL has a second container image, polis-oel-fips, which runs with an OpenSSL FIPS provider active. In this image every cryptographic operation Polis performs is served by that provider, and algorithms outside the FIPS-approved set are unavailable rather than merely discouraged.

The application code is identical to the standard image. Only the base image, the OpenSSL FIPS provider, and the behaviour that follows from restricting Polis to approved algorithms differ.

info

The FIPS image is preview work. It is built and security-scanned on every release, but it is not published to the enterprise registry, and the release pipeline's runtime tests do not yet cover it. Reach out to Ory if you want to evaluate it.

What is and is not being claimed​

FIPS 140-3 validates cryptographic modules, not applications. The polis-oel-fips image:

  • performs all cryptography inside an OpenSSL FIPS provider,
  • uses only FIPS-approved algorithms for security functions, and
  • runs in FIPS mode unconditionally — this cannot be turned off at runtime, and it does not depend on the host kernel being booted with fips=1. Polis does warn when the host is not in FIPS mode, see Recommended configuration.

The FIPS provider in this image is compiled from upstream OpenSSL source. It is therefore not a CMVP-validated cryptographic module, and the image must not be represented as FIPS 140-2 or FIPS 140-3 validated. The CMVP certificates published for OpenSSL cover specific vendor-built binaries on specific tested operational environments. If your programme requires a certificate number that covers the running binary, contact us before deploying.

The datastore keyspace differs from the standard image​

Polis derives every datastore key — and from it every SSO connection clientID, setup-link ID, identity federation app ID, directory-sync group membership ID, and the idHash claim — from a hash of the record's identifying parts.

ImageDigestLength
polis-oelRIPEMD-16040 hex characters
polis-oel-fipsSHA-25664 hex characters

RIPEMD-160 is not FIPS-approved at any implementation, so the FIPS image cannot use it. Each digest is used at its full width, so identifiers the FIPS image issues — connection clientIDs, setup-link IDs, identity federation app IDs and the idHash claim — are 64 characters rather than 40. The schema accommodates both; check anywhere your own systems store a Polis-issued identifier for a fixed-width column or validation.

warning

A database written by one image cannot be read by the other. The two digests produce different keys for the same record, so switching an existing deployment between polis-oel and polis-oel-fips makes its existing records unreachable. Choose one image per deployment.

Polis logs the digest it is using on every start, so you can confirm which keyspace a running process is on:

FIPS 140-3 mode is active (Node.js crypto backed by an OpenSSL FIPS provider). Datastore keys use SHA-256.
FIPS 140-3 mode is not active. Datastore keys use RIPEMD-160.

Refusing to start outside FIPS mode​

The polis-oel-fips image sets POLIS_REQUIRE_FIPS=1. With it set, Polis refuses to start, and its database migration job refuses to run, if FIPS mode is not active. This stops a process that lost FIPS mode, for example because OPENSSL_FORCE_FIPS_MODE was overridden, from writing RIPEMD-160 keys into a FIPS datastore:

POLIS_REQUIRE_FIPS is set but FIPS mode is not active. Run with OPENSSL_FORCE_FIPS_MODE=1 or on a host in FIPS mode: the
datastore keyspace of a FIPS deployment is not compatible with non-FIPS mode.

Keep the variable set to 1 for a FIPS deployment.

Choosing an image, and moving between them​

The two images are deliberately separate deployments. There is no automatic migration and no dual-read mode, by design: a FIPS deployment and a non-FIPS deployment do not share a datastore.

For a new deployment, start on the image you intend to keep — nothing further is required.

Migrating an existing deployment is a manual re-key, not a schema migration, and everything Polis stores under a digest-derived key has to be re-established. That includes:

  • SSO connections. Each clientID is derived from the digest, so it changes value and length. Anything that stored a clientID needs updating, as does the idHash claim if your application correlates users on it — the id claim is unaffected.
  • Identity federation apps, setup links, and directory-sync group memberships, for the same reason.
  • The SAML signing certificate, if you let Polis generate one. It is stored under a digest-derived key, so a FIPS deployment cannot read a certificate a non-FIPS deployment wrote, and mints a new key pair instead. Identity providers holding the old certificate will then reject signed authentication requests, and assertions encrypted to the old public key cannot be decrypted. Deployments that set PUBLIC_KEY and PRIVATE_KEY are not affected: an operator-supplied certificate never goes through the datastore.
  • In-flight state. Ephemeral records such as OAuth state are not carried over, so migrate during a maintenance window.

Contact us before migrating an existing deployment. We plan the re-key with you, including the signing certificate, rather than leaving it to a self-service procedure.

Microsoft SQL Server is not supported​

The MSSQL driver authenticates with NTLM, which depends on MD4. MD4 cannot be used under FIPS 140-3, so the FIPS image refuses to start when DB_TYPE=mssql, and its database migration job refuses to run:

FIPS mode: the mssql database engine is not supported because its NTLM authentication relies on MD4.
It is the only one FIPS rules out: set DB_TYPE to postgres, cockroachdb, yugabytedb, mysql, mariadb, or
sqlite, or use a non-SQL DB_ENGINE.

MSSQL is the only database Polis supports that FIPS rules out. PostgreSQL, CockroachDB, YugabyteDB, MySQL, MariaDB and SQLite all work, as do the non-SQL engines (MongoDB, Redis, DynamoDB, PlanetScale). The standard image is unaffected.

Identity provider requirements​

The FIPS provider does not implement algorithms that some identity providers still default to. Under the FIPS image your IdP must:

  • sign SAML responses with RSA-SHA256. RSA-SHA1 signatures cannot be verified.
  • use RSA-OAEP for key transport if it encrypts assertions. RSA-PKCS#1 v1.5 (rsa-1_5) key transport is unavailable.
  • use AES for assertion encryption. 3DES is unavailable.

Polis reports these failures with a message naming the likely cause and the fix rather than the underlying OpenSSL error, so a misconfigured IdP is identifiable from the SSO trace.

Polis warns at start-up, without refusing to run, about three things that weaken the posture of an otherwise FIPS deployment:

  • Run on a host booted with fips=1. The image turns FIPS mode on by itself, but a FIPS provider certificate only covers an operating environment whose kernel is in FIPS mode. Polis checks /proc/sys/crypto/fips_enabled and warns when it is not 1.
  • Set DB_ENCRYPTION_KEY. Without it, records are stored without encryption at rest.
  • Supply PUBLIC_KEY and PRIVATE_KEY. Without them Polis generates a self-signed SAML signing certificate on first start. That is convenient for evaluation, but the key material is not under your control and it does not survive a move between the two images. Certificates Polis generates itself use RSA-3072.

Everything else is configured exactly as for the standard image; see Environment Variables.