Authority Password Hashing Guidance

Audience: Authority operators, Security Guild, identity-plugin authors. Scope: How Stella Ops Authority hashes and verifies credentials, the recommended Argon2id parameters per environment, and how to configure and observe the rollout. Status: Drafted 2025-10-11 alongside SEC1.A / SEC1.PLG rollout; reconciled against source 2026-05-30. Argon2id is the default hashing algorithm for the Standard plug-in and is recommended for all Authority identity providers.

1. Overview

Stella Ops Authority issues and verifies credentials through the shared StellaOps.Cryptography provider abstraction. As of October 2025:

Note (verified against source 2026-05-30): The host-level authority.security.passwordHashing block (AuthoritySecurityOptions.PasswordHashing in StellaOps.Configuration) is bound and validated, but is not currently consumed as a system-wide default that propagates to plug-ins. The Standard plug-in does not read the host block; there is no inheritance/override merge today. Treat the per-plug-in passwordHashing block as the operative configuration. See §3.

EnvironmentmemorySizeInKibiterationsparallelismNotes
Production (default)1945621Balances CPU with 19 MiB memory cost; ~175 ms on 4 vCPU host.
High-security enclave3276831Increases memory pressure; confirm capacity on shared hosts.
Resource-constrained lab819221Use only for bootstrap/testing; increase once hardware upgraded.
PBKDF2 fallback≥210000Set algorithm: Pbkdf2 only when Argon2 hardware support unavailable.

⚠️ Lowering parameters below these baselines should be a temporary measure. Document any deviations in runbooks and schedule follow-up work to restore defaults.

Defaults caveat: The Production-row values match the PasswordHashOptions code defaults (memorySizeInKib = 19456, iterations = 2, parallelism = 1), which apply to Argon2id. There is no algorithm-specific default for PBKDF2PasswordHashOptions.Iterations defaults to 2 regardless of algorithm, so when you set algorithm: Pbkdf2 you must explicitly raise iterations to a PBKDF2-appropriate value (the ≥210000 OWASP guidance above); leaving it at the Argon2id default of 2 would be insecure for PBKDF2. The ~175 ms on 4 vCPU figure is an operational estimate, not a value asserted by the code or tests.

3. Configuring Authority Defaults

authority.yaml (or equivalent) accepts the following block, which binds to AuthoritySecurityOptions.PasswordHashing:

security:
  passwordHashing:
    algorithm: Argon2id      # Argon2id | Pbkdf2 (the PasswordHashAlgorithm enum)
    memorySizeInKib: 19456   # ~19 MiB
    iterations: 2
    parallelism: 1

⚠️ This host block is validated but not yet propagated to plug-ins. As of the current implementation (StellaOps.Configuration.AuthoritySecurityOptions), the only consumer of this block is its own Validate() call at host startup. The Standard plug-in’s CryptoPasswordHasher reads StandardPluginOptions.PasswordHashing — the plug-in’s own passwordHashing block (§4) — and never the host block. To change the effective hashing parameters today, edit the per-plug-in block, not this one. Wiring host-default propagation/override is open follow-up work.

Runtime validation (PasswordHashOptions.Validate()) ensures memorySizeInKib, iterations, and parallelism are all strictly greater than 0; each failing value throws an InvalidOperationException with a specific message (memory cost / iterations / parallelism). The algorithm is a closed enum (Argon2id | Pbkdf2), so any unrecognised value fails at configuration-binding time rather than in Validate().

4. Plug-in Configuration

The Standard plug-in’s hashing parameters are set entirely by its own passwordHashing block (at the root of standard.yaml), which binds to StandardPluginOptions.PasswordHashing:

passwordHashing:
  algorithm: Argon2id
  memorySizeInKib: 8192
  iterations: 2
  parallelism: 1

5. Observability & Migration

Reconciled against source 2026-05-30. The Standard plug-in does not emit a dedicated password-rehash metric. There is no Meter/Counter in StellaOps.Authority.Plugin.Standard, and no password_rehash_total (or any auth.plugins.standard.*) metric exists in the code. Earlier guidance referencing such a metric was aspirational and is not implemented.

6. Operational Checklist

  1. Update the plug-in passwordHashing block with the desired parameters (the host security.passwordHashing block does not drive plug-in hashing today — see §3); restart the host.
  2. Redeploy the updated plug-in configuration.
  3. Monitor the audit log for the plugin.rehashed property (see §5 — there is no password_rehash_total metric) and watch login success rates; investigate any spike in failures (likely due to mis-sized limits).
  4. Review hardware utilisation; Argon2id increases memory pressure compared to PBKDF2.
  5. Archive this document with the change request and notify SOC of the new baseline.

For additional context on tuning trade-offs, consult the OWASP Password Storage Cheat Sheet. For the complementary brute-force and burst controls on the authentication endpoints, see Authority rate-limit guidance.

7. Native Argon2 Preview Build Flag