Skip to content

refactor(grpc): name product arg consistently in policy interceptors#116

Merged
rodrigodh merged 2 commits into
developfrom
fix/grpc-product-arg-clarity
Jun 25, 2026
Merged

refactor(grpc): name product arg consistently in policy interceptors#116
rodrigodh merged 2 commits into
developfrom
fix/grpc-product-arg-clarity

Conversation

@rodrigodh

@rodrigodh rodrigodh commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Pull Request Type

  • Refactor

Summary

Clarity-only follow-up to the user-flow product-isolation change. When checkAuthorization's second parameter was renamed subproduct, the HTTP Authorize caller was updated, but the gRPC unary/stream interceptors kept naming their local variable sub while passing it into the product slot. This made the gRPC call sites read as if they were passing a subject when they are actually passing the product identifier.

This PR renames the gRPC local to product and clarifies the PolicyConfig.SubResolver doc so the resolved value's role is explicit.

What it is NOT

No behavior change. The resolved value was already the product identifier (e.g. midaz) — the same thing the HTTP path passes. For M2M it becomes the subject admin/<product>-editor-role; for normal-user it is forwarded as the isolation key.

The public field PolicyConfig.SubResolver and SubFromMetadata are kept (no exported API rename) to avoid breaking consumers.

Why it's safe

  • The gRPC NewGRPCAuthUnaryPolicy/PolicyConfig API is not used by any service in production (only referenced in planned docs), so there is no live path to regress.
  • Real M2M calls go through HTTP Authorize, which uses the same positional slot — unchanged.
  • Verified against a real M2M token (type=application) hitting the local access manager: the new code emits admin/plugin-crm-editor-role / admin/onboarding-editor-role / admin/transaction-editor-role — byte-identical to v2.8.0.

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 confirmed this code is ready for review.

Notes

Targets develop. Should land before promoting v2.9.0 to stable (PR #115).


Update — also closes the remaining CodeRabbit threads

This PR now additionally addresses the two other review findings from the release diff:

  • Fail closed on missing sub (Security thread): a normal-user JWT without a sub claim previously produced "<owner>/" and was sent as an identity-less principal. It is now rejected with 401, mirroring the existing missing-owner guard. Non-breaking — every legitimate user token has sub.
  • Regression coverage (Maintainability thread): added TestCheckAuthorization_MissingSubClaim (rejects no-sub) and TestCheckAuthorization_NormalUser_EmptyProduct_NotForwarded (empty product preserves prior behavior, no product forwarded — gate-by-presence).

All tests green.

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
@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: 9135edc8-0ff9-48c8-aff1-e437c45df816

📥 Commits

Reviewing files that changed from the base of the PR and between 7c76bab and bce4655.

📒 Files selected for processing (2)
  • auth/middleware/middleware.go
  • auth/middleware/middleware_test.go

📝 Walkthrough

Walkthrough

The gRPC auth middleware now resolves and forwards a product identifier in unary and streaming interceptors. Normal-user authorization also now fails when the JWT sub claim is missing.

Changes

gRPC authorization product switch

Layer / File(s) Summary
Policy comments and unary interceptor
auth/middleware/middlewareGRPC.go
The resolver comment now defines a product identifier, and the unary interceptor resolves product, records telemetry with {product, resource, action}, and passes product to auth.checkAuthorization.
Streaming interceptor product resolution
auth/middleware/middlewareGRPC.go
The streaming interceptor resolves product with cfg.SubResolver using req as nil, then passes product to auth.checkAuthorization.

Normal-user authorization validation

Layer / File(s) Summary
Normal-user subject validation
auth/middleware/middleware.go, auth/middleware/middleware_test.go
checkAuthorization now rejects normal-user tokens with an empty sub claim before building the subject, and tests cover the missing-sub failure and empty-product forwarding behavior.

Possibly related PRs

  • LerianStudio/lib-auth#114: Also updates gRPC authorization to pass a product identifier into auth.checkAuthorization instead of sub.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/grpc-product-arg-clarity

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

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
@rodrigodh rodrigodh merged commit 24980b5 into develop Jun 25, 2026
5 checks passed
@rodrigodh rodrigodh deleted the fix/grpc-product-arg-clarity branch June 25, 2026 17:16
@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 📦🚀

@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.

1 participant