Skip to content

feat(middleware): forward product on M2M auth (flag-gated)#123

Merged
qnen merged 1 commit into
developfrom
feat/item-17-m2m-product-forward
Jul 17, 2026
Merged

feat(middleware): forward product on M2M auth (flag-gated)#123
qnen merged 1 commit into
developfrom
feat/item-17-m2m-product-forward

Conversation

@qnen

@qnen qnen commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

What

Adds AuthClient.ForwardM2MProduct (read once from AUTH_M2M_PRODUCT_FORWARD_ENABLED, default off). When enabled, M2M (application-token) authorization calls forward the route product — the same field already forwarded for normal-user flows.

Why

This is the last piece of Item 17 Fase 2 (resource-prefix). Once Custom permission resources are prefixed with {product}/ (seed + migration 43, already on develop of plugin-access-manager), the enforce side dual-matches a bare request only when product is present so it can strip the prefix. The M2M path forwarded no product, so a bare M2M request (e.g. plugin-fees → midaz) stops matching the now-prefixed stored resource and the auth service denies it (403). Forwarding product for application tokens closes that gap.

Isolation is preserved: on the M2M path product is not the authorization gate (the governing m2m-permission is) — it only scopes the resource-prefix strip, which the access-manager already gates via permissionBelongsToProduct.

Design

  • Flag-gated, default off → deploy ≠ release. Merging + bumping consumers changes nothing; activation is flipping AUTH_M2M_PRODUCT_FORWARD_ENABLED=true per environment (staging first). Rollback = flip the flag, not a code revert.
  • No consumer code changes — consumers already pass product at the call site; lib-auth was dropping it for application. A dependency bump + env flag is all that's needed.
  • Shared shouldForwardProduct helper keeps the request body (checkAuthorization) and the telemetry payload (authPayload) in lockstep.
  • Normal-user behavior is unchanged; empty product is never forwarded.

Rollout order

  1. Merge this PR (flag off).
  2. Bump lib-auth in M2M consumers (midaz + plugins), deploy with flag off.
  3. Release = set AUTH_M2M_PRODUCT_FORWARD_ENABLED=true per env, staging first.

Follow-up (separate PR, in plugin-access-manager): make the product-matchers accept the slash separator ({product}/role) in addition to the legacy hyphen, before slash-named custom roles are enforced.

Tests

checkAuthorization (M2M flag on forwards / flag on + empty product omits), authPayload gating (flag on/off/empty), gRPC unary interceptor end-to-end with flag on, and NewAuthClient env parsing. gofmt clean · go build ./... · go test ./... green · golangci-lint 0 issues.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jul 17, 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: 85cc5907-6ad5-4398-9f65-37568fbbc2d5

📥 Commits

Reviewing files that changed from the base of the PR and between e6227e8 and 93c44db.

📒 Files selected for processing (5)
  • README.md
  • auth/middleware/middleware.go
  • auth/middleware/middlewareGRPC.go
  • auth/middleware/middlewareGRPC_test.go
  • auth/middleware/middleware_test.go

📝 Walkthrough

Walkthrough

Changes

The auth middleware now reads AUTH_M2M_PRODUCT_FORWARD_ENABLED into AuthClient. Non-empty products are forwarded for M2M/application tokens only when enabled, and gRPC telemetry follows the same rule. Tests cover flag parsing, authorization requests, telemetry payloads, and empty-product handling.

M2M Product Forwarding

Layer / File(s) Summary
Forwarding flag and authorization decision
auth/middleware/middleware.go, README.md
AuthClient stores the environment-controlled flag, and authorization requests conditionally include non-empty products for application tokens while preserving their subject.
gRPC payload product gating
auth/middleware/middlewareGRPC.go
gRPC authorization and telemetry payloads use the M2M forwarding flag when deciding whether to include product.
Product forwarding coverage
auth/middleware/middlewareGRPC_test.go, auth/middleware/middleware_test.go
Tests cover enabled and disabled flags, empty products, normal-user behavior, subject preservation, and environment parsing.

Sequence Diagram(s)

sequenceDiagram
  participant GRPCInterceptor
  participant AuthClient
  participant AuthService
  GRPCInterceptor->>AuthClient: resolve product and authorize
  AuthClient->>AuthService: send request with conditional product
  AuthService-->>AuthClient: return authorization result
  AuthClient-->>GRPCInterceptor: return result
  GRPCInterceptor->>AuthClient: build telemetry payload
  AuthClient-->>GRPCInterceptor: include product only when forwarded
Loading

Possibly related PRs

  • LerianStudio/lib-auth#122: Earlier auth middleware logic forwarded product only for normal-user tokens; this PR extends it to optionally support application/M2M tokens.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/item-17-m2m-product-forward

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

M2M (application-token) authorization calls sent no product, so once Custom permission resources are prefixed with "{product}/" (Item 17 F2), a bare M2M request stops matching the stored resource and the auth service denies it (403).

Forward the route product for application tokens too, gated by AUTH_M2M_PRODUCT_FORWARD_ENABLED (default off) so deploy != release: prefix isolation activates by flipping the flag, with no consumer code change. Normal-user behavior is unchanged. A shared shouldForwardProduct helper keeps the request body and telemetry payload in lockstep.

X-Lerian-Ref: 0x1
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@qnen
qnen force-pushed the feat/item-17-m2m-product-forward branch from e6227e8 to 93c44db Compare July 17, 2026 21:37
@qnen
qnen merged commit 2fda16e into develop Jul 17, 2026
3 checks passed
@qnen
qnen deleted the feat/item-17-m2m-product-forward branch July 17, 2026 21:41
@lerian-studio-midaz-push-bot

Copy link
Copy Markdown

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

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