Radiator Server Documentation — v10.34.1

Security requirements change over time. A hash that was acceptable a few years ago may no longer meet your current policy.

Use login-time rehashing to upgrade stored password hashes gradually, without forcing a global password reset.

Why Rehash During Login

Use this approach when you need to:

  • Migrate from plaintext or weak legacy hashes to stronger formats
  • Increase PBKDF2 cost (rounds) or Argon2 cost (memory_kib, iterations, parallelism)
  • Keep backend data aligned with current security policy

With login-time rehashing, Radiator only writes a new hash after a successful authentication. Users who never log in are not modified.

Rehash Pattern

A safe rehash flow has four steps:

  1. Authenticate user against the currently stored password hash.
  2. In post-authentication, check if the stored value already matches your target format.
  3. If not, hash the verified plaintext credential (auth.password) with the target settings.
  4. Persist the new hash to your backend.

Use auth.password as the input for rehashing. This value represents the verified credential from the current PAP login attempt.

Example: Rehash to PBKDF2-SHA512

This example upgrades accounts to {pbkdf2-sha512} after successful PAP authentication.

backends {
    radiatordb "CUSTOMER_DB" {
        query "FIND_USER" {
            get {
                key "%{aaa.identity}";
                collection "customers";
                destination user;
            }
        }

        query "UPDATE_PASSWORD" {
            put {
                key "%{aaa.identity}";
                collection "customers";
                bindings {
                    username = aaa.identity;
                    password_hash = auth.password | password_hash("pbkdf2-sha512", rounds=300000);
                }
            }
        }
    }
}

aaa {
    policy "BASIC_AUTH" {
        handler "PAP" {
            @authentication {
                backend {
                    name "CUSTOMER_DB";
                    query "FIND_USER";
                }
                must pap;
            }

            @post-authentication {
                if all {
                    user.password !starts "{pbkdf2-sha512}";
                } then {
                    backend {
                        name "CUSTOMER_DB";
                        query "UPDATE_PASSWORD";
                    }
                }
            }
        }
    }
}

For algorithm formats and option details, see Password Hashing.