Skip to content

chore(release): promote v2.9.0 — forward product on user-flow authorization#115

Merged
qnen merged 15 commits into
mainfrom
develop
Jun 26, 2026
Merged

chore(release): promote v2.9.0 — forward product on user-flow authorization#115
qnen merged 15 commits into
mainfrom
develop

Conversation

@rodrigodh

@rodrigodh rodrigodh commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Pull Request Type

  • Feature

Summary

Promotes developmain to cut the stable v2.9.0 release.

The substantive change is the user-flow product-isolation fix (already validated as v2.9.0-beta.1): the authorization middleware now forwards the product to plugin-access-manager on user-flow requests, instead of discarding it. This lets the access manager isolate permissions by product and close the cross-product authorization gap (e.g. a pix permission authorizing midaz routes via resource-name collision).

What's included (main..develop)

On merge, semantic-release analyzes the feat: commit → minor bump → v2.9.0 stable (no BREAKING CHANGE, so it stays minor), generates the changelog/GitHub release, and backmerges main → develop.

Compatibility

Backward compatible in both deploy orderings:

  • New lib-auth + old access manager: the new product field is decoded via Fiber's BodyParser (no DisallowUnknownFields, no strict validator on /v1/authorize), so an access manager without the isolation fix silently ignores it → legacy behavior, no breakage.
  • New access manager + old lib-auth: no product sent → access manager falls back to the legacy path.

Isolation only takes effect once both lib-auth ≥ v2.9.0 and the access manager (with the isolation fix) are deployed.

Checklist

  • I have tested these changes locally.
  • I have ensured that my changes adhere to the project's coding standards.
  • I have checked for any potential security issues.
  • I have ensured that all tests pass.
  • I have updated the version appropriately (semantic-release).
  • I have confirmed this code is ready for review.

Notes

Release promotion PR — intentionally targets main (not develop).

lerian-studio and others added 7 commits May 18, 2026 21:19
Backmerge of post-hotfix Narvi changes from main into develop.
CHANGELOG.md conflict resolved by keeping both main releases and develop beta entries.

Requested-by: @qnen
## [2.8.2-beta.1](v2.8.1...v2.8.2-beta.1) (2026-06-17)
checkAuthorization now takes the product owning the route and derives the subject internally: M2M tokens map to the product's editor role, while normal users are identified by their JWT (owner/userId). The product is forwarded as "product" for normal-user tokens only, so the auth service can isolate permissions by product. Empty product preserves the previous behavior, enabling incremental adoption.

X-Lerian-Ref: 0x1
feat(middleware): forward product on user-flow authorization
## [2.9.0-beta.1](v2.8.2-beta.1...v2.9.0-beta.1) (2026-06-23)

### Features

* **middleware:** forward product on user-flow authorization ([e597ae2](e597ae2))
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 869965f6-570c-47e9-a5db-1f4eaab0bc68

📥 Commits

Reviewing files that changed from the base of the PR and between c88df4e and 8203b56.

📒 Files selected for processing (1)
  • CHANGELOG.md

📝 Walkthrough

Walkthrough

The middleware authorization path now accepts a product identifier, derives subjects differently for normal-user and non-normal-user tokens, conditionally forwards product in authorization requests, and updates gRPC policy resolution, tests, and changelog entries.

Changes

Authorization product forwarding

Layer / File(s) Summary
Authorize input plumbing
auth/middleware/middleware.go, CHANGELOG.md
Authorize now accepts product and passes it into checkAuthorization; the changelog adds the v2.9.0-beta.2, v2.9.0-beta.1, and v2.8.0-beta.5 entries.
Subject derivation and payload fields
auth/middleware/middleware.go
checkAuthorization derives M2M subjects from product, derives normal-user subjects from the JWT sub claim, validates missing sub claims, and forwards product only for normal-user payloads.
gRPC policy product resolution
auth/middleware/middlewareGRPC.go
Unary and stream policies resolve product, pass it into checkAuthorization, and update unary telemetry payload fields.
Authorization behavior tests
auth/middleware/middleware_test.go
The normal-user and application-user tests assert the updated sub values and product forwarding rules, including missing-claim failure and empty-product handling.

Sequence Diagram

sequenceDiagram
  participant AuthClient.Authorize
  participant checkAuthorization
  participant auth service
  AuthClient.Authorize->>checkAuthorization: product, resource, action
  checkAuthorization->>auth service: subject and optional product
  auth service-->>checkAuthorization: authorization result
  checkAuthorization-->>AuthClient.Authorize: handler outcome
Loading

Possibly related PRs

  • LerianStudio/lib-auth#114 — Changes the same Authorize and checkAuthorization product-forwarding flow and matching tests.
  • LerianStudio/lib-auth#116 — Also updates gRPC policy interception to pass product into auth.checkAuthorization and aligns missing-sub handling.
  • LerianStudio/lib-auth#117 — Also extracts JWT subject derivation into deriveSubject and tightens the missing-sub failure path.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch develop

Comment @coderabbitai help to get the list of available commands.

@rodrigodh rodrigodh changed the title Develop chore(release): promote v2.9.0 — forward product on user-flow authorization Jun 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@auth/middleware/middleware_test.go`:
- Around line 104-116: Add regression coverage in
auth/middleware/middleware_test.go for the edge cases around checkAuthorization:
extend the existing test setup around auth.checkAuthorization to assert that an
empty product preserves the prior request behavior, and add a normal-user token
case that verifies tokens missing the JWT sub are rejected. Use the existing
checkAuthorization test helpers and capturedBody assertions so the new cases are
pinned to the auth contract without relying on line numbers.

In `@auth/middleware/middleware.go`:
- Around line 264-267: The new product parameter in
AuthClient.checkAuthorization must not be fed by the old sub resolver on the
gRPC path without updating middlewareGRPC.go. Update middlewareGRPC.go so the
second argument passed into checkAuthorization is an actual product identifier
(or empty when intended), and keep cfg.SubResolver only for subject derivation
where needed. Ensure the gRPC call sites around AuthClient.checkAuthorization
and the M2M role-building logic still preserve the empty-product fallback
instead of producing admin/-editor-role.
- Around line 319-320: The normal-user JWT handling in the middleware is
currently accepting a missing or non-string `sub` claim and still building a
shared principal with an empty user segment. Update the logic around the
`claims["sub"]` parsing in the middleware path that sets `sub` so it validates
the claim is present and a string, and reject the request if it is not. Ensure
the existing owner-based subject construction only happens after a valid `sub`
has been confirmed, so malformed tokens fail closed instead of being forwarded.

In `@CHANGELOG.md`:
- Around line 1-6: Mark the AuthClient.Authorize signature change as breaking in
the changelog entry: update the release notes around the middleware feature so
it is categorized as a breaking change, and mention that product now replaces
sub in the Authorize API. Use the Authorize and AuthClient symbols to locate the
affected release note and ensure downstream Fiber integrations are warned about
the source-level update.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6cb355d5-4b19-4bd5-83ed-2bf791ef3a1b

📥 Commits

Reviewing files that changed from the base of the PR and between 23472ac and 56b1409.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • auth/middleware/middleware.go
  • auth/middleware/middleware_test.go

Comment thread auth/middleware/middleware_test.go
Comment thread auth/middleware/middleware.go
Comment thread auth/middleware/middleware.go Outdated
Comment thread CHANGELOG.md
@rodrigodh rodrigodh requested a review from qnen June 24, 2026 21:48
The shared checkAuthorization parameter was renamed sub->product in the
user-flow product-isolation work, but the gRPC unary/stream interceptors
still named their local "sub" while passing it into the product slot.

Rename the local to product and clarify PolicyConfig/SubResolver docs so
the resolved value's role is explicit: it is the product identifier
(e.g. "midaz") that becomes the M2M subject "admin/<product>-editor-role"
and the normal-user isolation key. No behavior change — the same value is
forwarded; verified against a real M2M call (admin/<product>-editor-role
emitted identically to v2.8.0).

X-Lerian-Ref: 0x1
rodrigodh and others added 2 commits June 25, 2026 14:07
A normal-user token missing the "sub" claim previously produced the
subject "<owner>/" and was sent to the auth service as a degenerate,
identity-less principal. Reject it with 401 (mirroring the existing
missing-owner guard) so malformed tokens fail closed.

Also pin two auth-contract edges flagged in review:
- normal-user without "sub" is rejected;
- an empty product preserves prior behavior (subject unchanged, no
  product forwarded) — the gate-by-presence contract.

X-Lerian-Ref: 0x1
refactor(grpc): name product arg consistently in policy interceptors
## [2.9.0-beta.2](v2.9.0-beta.1...v2.9.0-beta.2) (2026-06-25)

### Bug Fixes

* **middleware:** fail closed when normal-user JWT has no sub claim ([bce4655](bce4655))
@lerian-studio-midaz-push-bot

Copy link
Copy Markdown

🎉 This PR is included in version 2.9.0-beta.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
auth/middleware/middlewareGRPC.go (1)

29-39: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Expose a ProductResolver instead of reinterpreting SubResolver.

The field name still advertises subject resolution while the contract now requires a product identifier. Existing callers can keep compiling while returning legacy subject values, silently defeating product isolation; consider adding ProductResolver and keeping SubResolver only as a deprecated fallback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@auth/middleware/middlewareGRPC.go` around lines 29 - 39, Rename the gRPC
policy hook in PolicyConfig to make the contract explicit: add a ProductResolver
field that returns the product identifier used by checkAuthorization, and keep
SubResolver only as a deprecated fallback for existing callers. Update the
middleware logic in middlewareGRPC.go to prefer ProductResolver when resolving
the product argument, and only use SubResolver when ProductResolver is unset so
legacy code still compiles without silently bypassing product isolation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@auth/middleware/middleware_test.go`:
- Around line 201-224: The check in AuthClient.checkAuthorization is only
asserting the 401 response, but not that missing-sub normal-user tokens are
never forwarded to the auth backend. Update the test around checkAuthorization
to also verify mockAuthServer is not called for this case (for example by using
the mock’s request count or a request assertion), so the fail-closed behavior is
pinned along with the Unauthorized result.

---

Outside diff comments:
In `@auth/middleware/middlewareGRPC.go`:
- Around line 29-39: Rename the gRPC policy hook in PolicyConfig to make the
contract explicit: add a ProductResolver field that returns the product
identifier used by checkAuthorization, and keep SubResolver only as a deprecated
fallback for existing callers. Update the middleware logic in middlewareGRPC.go
to prefer ProductResolver when resolving the product argument, and only use
SubResolver when ProductResolver is unset so legacy code still compiles without
silently bypassing product isolation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2d28cf78-3200-4f09-bea8-307f3c528dc9

📥 Commits

Reviewing files that changed from the base of the PR and between 56b1409 and b9bbf0d.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • auth/middleware/middleware.go
  • auth/middleware/middlewareGRPC.go
  • auth/middleware/middleware_test.go

Comment thread auth/middleware/middleware_test.go Outdated
… complexity

The fail-closed sub guard pushed checkAuthorization to gocyclo 17 (> 16).
Extract the subject-derivation branch (M2M role vs normal-user identity,
with the owner/sub guards) into deriveSubject, bringing checkAuthorization
back to 15. No behavior change.

X-Lerian-Ref: 0x1
rodrigodh and others added 2 commits June 25, 2026 14:32
…ckend

TestCheckAuthorization_MissingSubClaim asserted the 401 result but not the
fail-closed guarantee. Replace the permissive mock with a handler that fails
the test if hit, proving a missing-sub normal-user token is rejected before
any request to the auth service.

X-Lerian-Ref: 0x1
refactor(middleware): cut checkAuthorization cyclomatic complexity
@lerian-studio-midaz-push-bot

Copy link
Copy Markdown

🎉 This PR is included in version 2.9.0-beta.3 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@qnen qnen merged commit a461441 into main Jun 26, 2026
3 checks passed
@lerian-studio-midaz-push-bot

Copy link
Copy Markdown

🎉 This PR is included in version 2.9.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants