Skip to content

chore: update passwap v0.12.1 and align hash validation defaults/errors#12179

Merged
livio-a merged 9 commits into
mainfrom
chore-upgr-passwap
Jun 5, 2026
Merged

chore: update passwap v0.12.1 and align hash validation defaults/errors#12179
livio-a merged 9 commits into
mainfrom
chore-upgr-passwap

Conversation

@muhlemmer

@muhlemmer muhlemmer commented May 18, 2026

Copy link
Copy Markdown
Collaborator

Which Problems Are Solved

  • Upgrading to zitadel/passwap v0.12.1 introduced new encoded-hash validation paths that still had review feedback open.
  • Secret hasher defaults were internally inconsistent (Hasher.Cost: 4 vs Limits.Bcrypt.MinCost: 10), which could reject hashes created by the configured hasher.
  • New validation error IDs/messages and test coverage needed to be aligned with project conventions and expected behavior branches.

How the Problems Are Solved

  • Kept the dependency upgrade to zitadel/passwap v0.12.1 and completed the validation integration.
  • Updated ValidateEncodedHash error handling in internal/crypto/passwap.go to:
    • use unique random-style error IDs,
    • return Errors.Hash.NotSupported for no-verifier cases,
    • keep invalid-hash branches mapped to invalid argument errors.
  • Expanded TestHasher_ValidateEncodedHash in internal/crypto/passwap_test.go to cover and assert:
    • bounds error branch,
    • no-verifier branch,
    • generic invalid-hash branch,
    • expected ZITADEL error IDs/messages.
  • Restored lost inline verifier-context comments for argon2 and md5plain verifier entries.

Additional Changes

  • Added the missing explanatory Limits comment for SecretHasher in cmd/defaults.yaml.
  • Corrected SecretHasher.Limits.Bcrypt.MinCost from 10 to 4 to match the configured default bcrypt cost and avoid configuration footguns.

Additional Context

…er validation limits

- Updated the passwap dependency version from v0.11.0 to v0.12.1 in go.mod and go.sum.
- Added validation limits for various password hashing algorithms in defaults.yaml, including Bcrypt, Argon2, Scrypt, PBKDF2, Sha2, PHPass, and Drupal7.
- Implemented a new method `ValidateEncodedHash` in the Hasher struct to ensure encoded hashes are valid and within specified limits.
- Updated relevant tests to cover new validation logic for encoded password hashes.
Copilot AI review requested due to automatic review settings May 18, 2026 19:20
@vercel

vercel Bot commented May 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Jun 5, 2026 11:50am
zitadel-login Ready Ready Preview, Comment Jun 5, 2026 11:50am

Request Review

@github-actions

Copy link
Copy Markdown

Thanks for your contribution @muhlemmer! 🎉

Please make sure you tick the following checkboxes before marking this Pull Request (PR) as ready for review:

  • I have reviewed my changes and would approve it
  • Documentations and examples are up-to-date
  • Terminology updates follow issue Inconsistent Naming #5888 and TERMINOLOGY.md
  • Logical behavior changes are tested automatically
  • No debug or dead code
  • My code has no repetitions
  • The PR title adheres to the conventional commit format
  • The example texts in the PR description are replaced.
  • If there are any open TODOs or follow-ups, they are described in issues and link to this PR
  • If there are deviations from a user stories acceptance criteria or design, they are agreed upon with the PO and documented.

@nx-cloud

nx-cloud Bot commented May 18, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 4d385e3

Command Status Duration Result
nx affected --nxBail --targets lint test build ... ✅ Succeeded 10m 21s View ↗

☁️ Nx Cloud last updated this comment at 2026-06-05 11:49:12 UTC

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades the zitadel/passwap dependency from v0.11.0 to v0.12.1 and threads the library's new per-algorithm validation bounds through crypto.HashConfig. A new Hasher.ValidateEncodedHash API is added and wired into the user-creation/import/password-set paths so pre-encoded hashes from untrusted sources are rejected when unsupported, malformed, or outside the configured cost bounds. Also adapts the scrypt config mapping to the library's new LN parameter and converts the verifier registry to factory functions that receive the limits.

Changes:

  • Bump passwap to v0.12.1 and adapt to the new NewVerifier(opts) / New<Algo>(params, opts) constructors and the Validate verifier method.
  • Introduce HashLimitsConfig (Bcrypt/Argon2/Scrypt/PBKDF2/Sha2/PHPass/Drupal7) with defaults in defaults.yaml, and add Hasher.ValidateEncodedHash to enforce them on imported/pre-encoded hashes.
  • Replace EncodingSupported checks with ValidateEncodedHash in AddHuman/ChangeHuman/Password.Validate, addHumanCommandPassword, createHuman, and setPasswordCommand.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
go.mod / go.sum Bump passwap from v0.11.0 to v0.12.1.
internal/crypto/passwap.go New limits config, factory-based verifier registry, scrypt switch from N to LN, new ValidateEncodedHash.
internal/crypto/passwap_test.go Smoke test for ValidateEncodedHash; scrypt test updated to LN.
internal/command/user_human.go Replace EncodingSupported with ValidateEncodedHash in AddHuman.Validate, addHumanCommandPassword, createHuman.
internal/command/user_v2_human.go Replace EncodingSupported with ValidateEncodedHash in Password.Validate.
internal/command/user_human_password.go Validate encoded hash inside setPasswordCommand before storing.
internal/command/main_test.go Implement Validate on the test plainHasher for the new verifier.Verifier interface.
internal/command/crypto_test.go Adapt bcrypt.New call site to the new (cost, opts) signature.
cmd/defaults.yaml Document scrypt Cost==LN and add Limits defaults for PasswordHasher and SecretHasher.
Comments suppressed due to low confidence (1)

internal/crypto/passwap.go:232

  • There is no cross-check between the hasher's configured cost parameters (e.g. HasherConfig.Cost for bcrypt/scrypt, Time/Memory/Threads for argon2, Rounds for pbkdf2/sha2) and the new Limits bounds passed to the same algorithm. If an operator configures a Cost/Rounds/etc. outside the configured Min/Max, freshly generated hashes will be rejected by ValidateEncodedHash on subsequent operations (e.g. when re-importing or in a future flow). It would be safer to validate the hasher's own parameters against the limits at NewHasher time and fail fast at startup, instead of producing hashes the same instance will later refuse.
func (c *HashConfig) NewHasher() (*Hasher, error) {
	verifiers, vPrefixes, err := c.buildVerifiers()
	if err != nil {
		return nil, zerrors.ThrowInvalidArgument(err, "CRYPT-sahW9", "password hash config invalid")
	}
	hasher, hPrefixes, err := c.Hasher.buildHasher(c.Limits)
	if err != nil {
		return nil, zerrors.ThrowInvalidArgument(err, "CRYPT-Que4r", "password hash config invalid")
	}
	return &Hasher{
		Swapper:      passwap.NewSwapper(hasher, verifiers...),
		Prefixes:     append(hPrefixes, vPrefixes...),
		HexSupported: slices.Contains(c.Verifiers, HashNameMd5Plain),
	}, nil
}

Comment thread internal/crypto/passwap.go Outdated
Comment thread cmd/defaults.yaml Outdated
Comment thread internal/crypto/passwap.go
Comment thread internal/crypto/passwap_test.go
Comment thread cmd/defaults.yaml
Comment thread internal/crypto/passwap.go Outdated
Copilot AI changed the title chore: update passwap v0.12.1 and enhance password hasher validation limits chore: update passwap v0.12.1 and align hash validation defaults/errors Jun 4, 2026
muhlemmer added 2 commits June 5, 2026 16:04
Replaced the validation error in the TestAddHumanCommand from a generic error to a specific passwap error indicating no verifier is available. This change enhances the clarity of the test's intent and aligns it with the updated passwap dependency.
@codecov

codecov Bot commented Jun 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.70588% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 42.39%. Comparing base (64737bf) to head (4d385e3).
⚠️ Report is 14 commits behind head on main.

Files with missing lines Patch % Lines
internal/crypto/passwap.go 68.08% 26 Missing and 19 partials ⚠️
internal/command/user_human.go 28.57% 3 Missing and 2 partials ⚠️
internal/command/user_human_password.go 33.33% 1 Missing and 1 partial ⚠️
internal/command/user_v2_human.go 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #12179      +/-   ##
==========================================
+ Coverage   42.21%   42.39%   +0.18%     
==========================================
  Files        2082     2082              
  Lines      182058   181969      -89     
==========================================
+ Hits        76853    77153     +300     
+ Misses     100082    99892     -190     
+ Partials     5123     4924     -199     
Flag Coverage Δ
api-test-integration 0.00% <0.00%> (ø)
api-test-unit 43.41% <64.70%> (+0.19%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@livio-a livio-a disabled auto-merge June 5, 2026 12:48
@livio-a livio-a changed the title chore: update passwap v0.12.1 and align hash validation defaults/errors chore(deps): update passwap v0.12.1 and align hash validation defaults/errors Jun 5, 2026
@livio-a livio-a changed the title chore(deps): update passwap v0.12.1 and align hash validation defaults/errors chore: update passwap v0.12.1 and align hash validation defaults/errors Jun 5, 2026
@livio-a livio-a merged commit 25e2633 into main Jun 5, 2026
16 checks passed
@livio-a livio-a deleted the chore-upgr-passwap branch June 5, 2026 12:48
livio-a pushed a commit that referenced this pull request Jun 8, 2026
…rs (#12179)

# Which Problems Are Solved

- Upgrading to `zitadel/passwap` v0.12.1 introduced new encoded-hash
validation paths that still had review feedback open.
- Secret hasher defaults were internally inconsistent (`Hasher.Cost: 4`
vs `Limits.Bcrypt.MinCost: 10`), which could reject hashes created by
the configured hasher.
- New validation error IDs/messages and test coverage needed to be
aligned with project conventions and expected behavior branches.

# How the Problems Are Solved

- Kept the dependency upgrade to `zitadel/passwap` v0.12.1 and completed
the validation integration.
- Updated `ValidateEncodedHash` error handling in
`internal/crypto/passwap.go` to:
  - use unique random-style error IDs,
  - return `Errors.Hash.NotSupported` for no-verifier cases,
  - keep invalid-hash branches mapped to invalid argument errors.
- Expanded `TestHasher_ValidateEncodedHash` in
`internal/crypto/passwap_test.go` to cover and assert:
  - bounds error branch,
  - no-verifier branch,
  - generic invalid-hash branch,
  - expected ZITADEL error IDs/messages.
- Restored lost inline verifier-context comments for argon2 and md5plain
verifier entries.

# Additional Changes

- Added the missing explanatory `Limits` comment for `SecretHasher` in
`cmd/defaults.yaml`.
- Corrected `SecretHasher.Limits.Bcrypt.MinCost` from `10` to `4` to
match the configured default bcrypt cost and avoid configuration
footguns.

# Additional Context

- Follow-up for PR review feedback in
#12179 (review)

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Livio Spring <9405495+livio-a@users.noreply.github.com>

(cherry picked from commit 25e2633)
fo-ofc pushed a commit to O-F-C/zitadel that referenced this pull request Jun 10, 2026
…rs (zitadel#12179)

# Which Problems Are Solved

- Upgrading to `zitadel/passwap` v0.12.1 introduced new encoded-hash
validation paths that still had review feedback open.
- Secret hasher defaults were internally inconsistent (`Hasher.Cost: 4`
vs `Limits.Bcrypt.MinCost: 10`), which could reject hashes created by
the configured hasher.
- New validation error IDs/messages and test coverage needed to be
aligned with project conventions and expected behavior branches.

# How the Problems Are Solved

- Kept the dependency upgrade to `zitadel/passwap` v0.12.1 and completed
the validation integration.
- Updated `ValidateEncodedHash` error handling in
`internal/crypto/passwap.go` to:
  - use unique random-style error IDs,
  - return `Errors.Hash.NotSupported` for no-verifier cases,
  - keep invalid-hash branches mapped to invalid argument errors.
- Expanded `TestHasher_ValidateEncodedHash` in
`internal/crypto/passwap_test.go` to cover and assert:
  - bounds error branch,
  - no-verifier branch,
  - generic invalid-hash branch,
  - expected ZITADEL error IDs/messages.
- Restored lost inline verifier-context comments for argon2 and md5plain
verifier entries.

# Additional Changes

- Added the missing explanatory `Limits` comment for `SecretHasher` in
`cmd/defaults.yaml`.
- Corrected `SecretHasher.Limits.Bcrypt.MinCost` from `10` to `4` to
match the configured default bcrypt cost and avoid configuration
footguns.

# Additional Context

- Follow-up for PR review feedback in
zitadel#12179 (review)

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Livio Spring <9405495+livio-a@users.noreply.github.com>

(cherry picked from commit 25e2633)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants