Conversation
Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.37.0 to 1.39.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](open-telemetry/opentelemetry-go@v1.37.0...v1.39.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel dependency-version: 1.39.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Generated-by: Claude AI-Model: claude-opus-4-5-20251101
X-Lerian-Ref: 0x1
X-Lerian-Ref: 0x1
Bumps [github.com/golang-jwt/jwt/v5](https://github.com/golang-jwt/jwt) from 5.3.0 to 5.3.1. - [Release notes](https://github.com/golang-jwt/jwt/releases) - [Commits](golang-jwt/jwt@v5.3.0...v5.3.1) --- updated-dependencies: - dependency-name: github.com/golang-jwt/jwt/v5 dependency-version: 5.3.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
…elv2 docs: update license to Elastic License 2.0 (ELv2)
## [2.4.1-beta.1](v2.4.0...v2.4.1-beta.1) (2026-02-03)
X-Lerian-Ref: 0x1
…rn 🔧 Implements comprehensive Makefile infrastructure aligned with Midaz lib-commons standards: Core improvements: - Modular test framework (mk/tests.mk) with unit, integration and coverage targets - Colored console output with ANSI codes for better readability - Smart coverage reporting via scripts/coverage.sh with exclusion support - Enhanced security scanning with SARIF output support (make sec SARIF=1) - Git hooks verification and installation commands - Support for low-resource environments (LOW_RESOURCE=1) - Test filtering by pattern (RUN=) and package (PKG=) New commands: - make test-unit / test-integration / test-all - make coverage-unit / coverage-integration / coverage - make cover-html (generates HTML reports) - make tools (installs gotestsum) - make check-tests / check-hooks / check-envs - make clean (removes build artifacts and reports) Infrastructure files: - mk/tests.mk: Test targets with gotestsum integration and testcontainers support - scripts/coverage.sh: Intelligent coverage script with package filtering - scripts/coverage_ignore.txt: Coverage exclusion patterns - .ignorecoverunit: Unit test coverage exclusions (filters *_mock.go) Updated .gitignore: - Added /dist/, /reports/, coverage files, and gosec-report.sarif All 22 commands tested and validated successfully. X-Lerian-Ref: 0x1
Replace find | xargs pipeline with find -exec to prevent failures under set -e when no integration test files are found. The -exec approach is more robust and doesn't require null-delimited handling. X-Lerian-Ref: 0x1
Remove 'make cover' and 'make cover-html' commands which have been superseded by the more granular coverage-unit and coverage-integration commands. Also removes the associated coverage.sh script and coverage_ignore.txt file. X-Lerian-Ref: 0x1
chore: add build, test and coverage commands
## [2.5.0-beta.1](v2.4.1-beta.1...v2.5.0-beta.1) (2026-02-09) ### Bug Fixes * **tests:** use safe find -exec instead of xargs pipeline 🐛 ([da45b1a](da45b1a))
Update imports from v2 to v3 and point to published version, removing local replace directive. X-Lerian-Ref: 0x1
…p/github.com/golang-jwt/jwt/v5-5.3.1 build(deps): bump github.com/golang-jwt/jwt/v5 from 5.3.0 to 5.3.1
## [2.5.0-beta.2](v2.5.0-beta.1...v2.5.0-beta.2) (2026-02-20)
Bumps [github.com/gofiber/fiber/v2](https://github.com/gofiber/fiber) from 2.52.9 to 2.52.11. - [Release notes](https://github.com/gofiber/fiber/releases) - [Commits](gofiber/fiber@v2.52.9...v2.52.11) --- updated-dependencies: - dependency-name: github.com/gofiber/fiber/v2 dependency-version: 2.52.11 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
…p/github.com/gofiber/fiber/v2-2.52.11 build(deps): bump github.com/gofiber/fiber/v2 from 2.52.9 to 2.52.11
## [2.5.0-beta.3](v2.5.0-beta.2...v2.5.0-beta.3) (2026-02-20)
…metry.io/otel-1.39.0
…p/go.opentelemetry.io/otel-1.39.0 build(deps): bump go.opentelemetry.io/otel from 1.37.0 to 1.39.0
## [2.5.0-beta.4](v2.5.0-beta.3...v2.5.0-beta.4) (2026-02-20)
Feature/multi tenant
## [2.5.0-beta.5](v2.5.0-beta.4...v2.5.0-beta.5) (2026-02-20)
- 17 test functions with 40+ subtests covering both middleware files - gRPC: stripBearer, policyForMethod, grpcErrorFromHTTP, extractTokenFromMD, SubFromMetadata, NewGRPCAuthUnaryPolicy integration - HTTP: checkAuthorization subject construction for normal-user and application tokens, mock server integration, error handling - Documents known bug: application tokens hardcode "admin/" prefix instead of using owner claim from JWT - Add testify v1.11.1 dependency Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add extractTenantClaims to parse tenantId/tenantSlug/owner from JWT - Propagate tenant metadata (md-tenant-id, md-tenant-slug, md-tenant-owner) in unary interceptor when MULTI_TENANT_ENABLED=true - Add NewGRPCAuthStreamPolicy streaming interceptor mirroring unary behavior - Add wrappedServerStream to override context for streaming calls - Add tests for extraction, propagation, and streaming interceptor Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace NewTracerFromContext + NewHeaderIDFromContext with the unified NewTrackingFromContext across HTTP and gRPC middleware. X-Lerian-Ref: 0x1
Adapt all middleware call sites to the breaking changes introduced in lib-commons v4: - opentelemetry: span args changed from pointer to value (HandleSpanError, SetSpanAttributesFromValue) - opentelemetry: ExtractHTTPContext and InjectHTTPContext signatures reversed (ctx first) - SetSpanAttributesFromStruct replaced by SetSpanAttributesFromValue - NoneLogger replaced by log.NewNop() - Add logErrorf/logInfof helpers for nil-safe logger calls - Add initializeDefaultLogger to replace zap.InitializeLoggerWithError() - Update testLogger to implement the new v4 log.Logger interface (Log/With/WithGroup/Enabled/Sync) X-Lerian-Ref: 0x1
If the default logger initialization fails, the previous code attempts to log this error using the uninitialized logger instance itself. This causes a nil pointer dereference and panics the application. This commit replaces the faulty call with `stdlog.Printf`. Using the standard library logger ensures the initialization error is reported safely without crashing. The application then gracefully falls back to using a no-op logger.
feat(middleware): migrate lib-commons from v3 to v4
## [2.5.0-beta.7](v2.5.0-beta.6...v2.5.0-beta.7) (2026-03-10) ### Features * **middleware:** migrate to lib-commons v4 API ([2e12d9b](2e12d9b)) ### Bug Fixes * **auth/middleware:** prevent panic on logger initialization failure ([6ba51e5](6ba51e5))
checkAuthorization returned HTTP 500 when JWT parsing failed (malformed/invalid token). The Authorize caller also hardcoded 500, ignoring the returned status code. Now returns 401 Unauthorized for parse failures and the caller respects the returned status code. X-Lerian-Ref: 0x1
fix(auth/middleware): return 401 instead of 500 for malformed tokens
## [2.5.0-beta.8](v2.5.0-beta.7...v2.5.0-beta.8) (2026-03-17) ### Bug Fixes * **auth/middleware:** return 401 instead of 500 for malformed tokens ([4f51877](4f51877))
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (2)
WalkthroughThis pull request upgrades the Go toolchain and many dependencies (including lib-commons v2→v4), expands the Makefile into a project task runner with a new mk/tests.mk include, and adds LICENSE and coverage ignore files. The auth middleware is refactored to use updated commons and OpenTelemetry APIs, adds tolerant error unmarshalling for numeric/string Sequence Diagram(s)sequenceDiagram
participant Client as gRPC Client
participant StreamInterceptor as gRPC Stream Interceptor
participant AuthClient as Auth Service Client
participant TokenHandler as Token & Claims Handler
participant Metadata as Context & Metadata
participant Handler as Method Handler
Client->>StreamInterceptor: Start streaming RPC
StreamInterceptor->>StreamInterceptor: Check auth enabled / resolve policy
StreamInterceptor->>TokenHandler: Extract token from metadata
alt token missing
StreamInterceptor->>Client: Return Unauthenticated (gRPC) error
else token present
TokenHandler->>TokenHandler: Parse/inspect token (ParseUnverified / verify)
StreamInterceptor->>AuthClient: call auth.checkAuthorization
alt authorization fails
AuthClient->>StreamInterceptor: Unauthorized/Forbidden
StreamInterceptor->>Client: Return corresponding gRPC error
else authorization succeeds
alt MULTI_TENANT_ENABLED == "true"
TokenHandler->>TokenHandler: Extract tenant claims (id, slug, owner)
Metadata->>Metadata: Inject tenant metadata keys (md-tenant-*)
end
StreamInterceptor->>Handler: Invoke wrapped stream with enriched Context()
Handler->>Handler: Read tenant metadata from Context()
Handler-->>Client: Stream responses
end
end
🚥 Pre-merge checks | ❌ 2❌ Failed checks (2 warnings)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment Tip CodeRabbit can use your project's `golangci-lint` configuration to improve the quality of Go code reviews.Add a configuration file to your project to customize how CodeRabbit runs |
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@auth/middleware/middleware_test.go`:
- Around line 156-158: The comment next to the assertion on capturedBody["sub"]
in middleware_test.go currently prefixes "BUG:" but documents expected hardcoded
"admin/" behavior; if this behavior is intentional, remove the "BUG:" prefix (or
replace with "NOTE:"/TODO) to avoid misleading reviewers and update the comment
to state it's expected; if it's actually a bug, create an issue tracking the
bug, reference that issue ID in a TODO comment next to the assert.Equal line
(capturedBody["sub"]) and keep the test as-is until the bug is fixed so CI
surfaces the failure.
In `@auth/middleware/middlewareGRPC_test.go`:
- Around line 424-429: The test currently declares handlerCalled and sets it
inside noopHandler but never asserts it; either remove the handlerCalled
variable and the blank identifier assignment that suppresses the warning (i.e.,
drop handlerCalled and the trailing "_ = handlerCalled" lines and keep
noopHandler returning "ok"), or keep handlerCalled and add assertions in the
error-case tests to verify the handler was not invoked (e.g., assert
handlerCalled == false after calling the middleware) so the tracking variable is
actually used; update tests that reference handlerCalled/noopHandler
accordingly.
In `@auth/middleware/middlewareGRPC.go`:
- Around line 270-290: Extract the duplicated tenant propagation block into a
helper function propagateTenantClaims(ctx context.Context, token string, logger
log.Logger) context.Context that checks os.Getenv("MULTI_TENANT_ENABLED"), calls
extractTenantClaims(token), logs extraction errors, copies incoming metadata,
sets "md-tenant-id", "md-tenant-slug", and "md-tenant-owner" when present, and
returns metadata.NewIncomingContext(ctx, md); then replace the duplicated code
in both the unary interceptor (where extractTenantClaims is currently used) and
the stream interceptor (where wrappedServerStream is created) by calling ctx =
propagateTenantClaims(ctx, token, auth.Logger) and for the stream update ss =
&wrappedServerStream{ServerStream: ss, ctx: ctx} after calling the helper.
- Around line 102-121: extractTenantClaims' returned error is being discarded;
capture the fourth return value (err) instead of using '_' and log it at debug
level when MULTI_TENANT_ENABLED is true so tenant propagation failures are
visible during troubleshooting. Update the block that calls
extractTenantClaims(token) to assign the error (e.g., tenantID, tenantSlug,
tOwner, err := extractTenantClaims(token)), and if err != nil call the existing
logger (e.g., authLogger or the package logger) with a debug message including
the error and token/ctx context; leave behavior unchanged otherwise and still
set metadata via metadata.FromIncomingContext / metadata.NewIncomingContext as
before.
In `@go.mod`:
- Line 11: The dependency google.golang.org/grpc pinned to v1.79.2 contains a
critical auth bypass (CVE-2026-33186); update the module version in go.mod to
v1.79.3 or later to fix it. If you cannot upgrade immediately, add an outermost
unary and stream interceptor on your gRPC server (where you call grpc.NewServer
or configure interceptors) that rejects requests whose full method string is
empty or does not start with '/' to block malformed :path values; after
upgrading remove the temporary interceptor. Ensure you update go.mod's
google.golang.org/grpc entry and run go mod tidy to refresh the lock.
In `@LICENSE`:
- Around line 1-93: The repo added Elastic License 2.0 (LICENSE) but lacked
propagation; update README.md to add an explicit "License" section that names
"Elastic License 2.0" and briefly calls out the hosted/managed-service
restriction, add SPDX-License-Identifier: Elastic-2.0 headers to all source
files (e.g., top of .go/.ts/.js files) and ensure go.mod contains license
metadata (module/comments or a license directive) so tooling sees Elastic-2.0;
search for README.md, go.mod and all source files to apply these changes
consistently and commit them alongside the LICENSE file.
In `@Makefile`:
- Around line 269-274: Update the goreleaser Makefile target "goreleaser" to
replace the removed flag form "--skip-publish" with the new "--skip=publish";
specifically, in the command invoked by the goreleaser target (the line that
currently runs "goreleaser release --snapshot --skip-publish --clean"), change
the flag to "--skip=publish" so the release snapshot command works with
goreleaser v1.21+ and v2.0.
In `@mk/tests.mk`:
- Around line 221-230: The current glob-to-regex conversion in mk/tests.mk (the
sed pipeline that builds regex_patterns from patterns read from
.ignorecoverunit) only escapes '.' and converts '*' to '.*', so it fails on
other glob metacharacters (e.g., '+', '?', '[]') — update the file to either (A)
document this limitation immediately above the block that defines
patterns/regex_patterns and explain acceptable pattern syntax for
.ignorecoverunit, or (B) replace the simple sed conversion that produces
regex_patterns with a more robust glob-to-regex conversion (e.g., a small
perl/python one-liner or utility) that properly escapes regex metacharacters
while translating globs; ensure the rest of the flow (reading patterns into
patterns, filtering unit_coverage.out into unit_coverage_filtered.out, and mv
back) still uses the new regex_patterns variable.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 9c2b8bbb-9f36-4172-871a-6381f3e5d35f
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (11)
.gitignore.ignorecoverunitCHANGELOG.mdLICENSEMakefileauth/middleware/middleware.goauth/middleware/middlewareGRPC.goauth/middleware/middlewareGRPC_test.goauth/middleware/middleware_test.gogo.modmk/tests.mk
| // BUG: hardcodes "admin/" prefix. The sub parameter is used as-is with the | ||
| // "admin/<sub>-editor-role" pattern, regardless of the actual user type. | ||
| assert.Equal(t, "admin/my-app-editor-role", capturedBody["sub"]) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Documented behavior: hardcoded "admin/" prefix for non-normal users.
The test documents this as a potential bug with the comment on lines 156-157. If this is intentional behavior, consider removing the "BUG:" prefix from the comment to avoid confusion. If it's actually a bug, consider opening an issue to track it.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@auth/middleware/middleware_test.go` around lines 156 - 158, The comment next
to the assertion on capturedBody["sub"] in middleware_test.go currently prefixes
"BUG:" but documents expected hardcoded "admin/" behavior; if this behavior is
intentional, remove the "BUG:" prefix (or replace with "NOTE:"/TODO) to avoid
misleading reviewers and update the comment to state it's expected; if it's
actually a bug, create an issue tracking the bug, reference that issue ID in a
TODO comment next to the assert.Equal line (capturedBody["sub"]) and keep the
test as-is until the bug is fixed so CI surfaces the failure.
| handlerCalled := false | ||
|
|
||
| noopHandler := func(_ context.Context, _ any) (any, error) { | ||
| handlerCalled = true | ||
| return "ok", nil | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Remove unused handlerCalled variable or add assertions.
The handlerCalled variable is set in noopHandler but never asserted on. The blank identifier assignment at line 558 just suppresses the compiler warning. For error-case tests (lines 495, 520, 547), you should either assert that the handler was not called, or simplify by removing the tracking variable entirely.
♻️ Option 1: Remove tracking (simpler)
- handlerCalled := false
-
- noopHandler := func(_ context.Context, _ any) (any, error) {
- handlerCalled = true
- return "ok", nil
- }
+ noopHandler := func(_ context.Context, _ any) (any, error) {
+ return "ok", nil
+ }And remove line 558:
- // Prevent compiler from optimizing away the handlerCalled variable
- _ = handlerCalled♻️ Option 2: Assert handler not called in error tests
+ handlerCalled = false // reset before test
resp, err := interceptor(context.Background(), "req", dummyInfo, noopHandler)
require.Error(t, err)
assert.Nil(t, resp)
+ assert.False(t, handlerCalled, "handler should not be called on error")Also applies to: 557-558
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@auth/middleware/middlewareGRPC_test.go` around lines 424 - 429, The test
currently declares handlerCalled and sets it inside noopHandler but never
asserts it; either remove the handlerCalled variable and the blank identifier
assignment that suppresses the warning (i.e., drop handlerCalled and the
trailing "_ = handlerCalled" lines and keep noopHandler returning "ok"), or keep
handlerCalled and add assertions in the error-case tests to verify the handler
was not invoked (e.g., assert handlerCalled == false after calling the
middleware) so the tracking variable is actually used; update tests that
reference handlerCalled/noopHandler accordingly.
| // Propagate tenant claims if multi-tenant mode is enabled | ||
| if os.Getenv("MULTI_TENANT_ENABLED") == "true" { | ||
| tenantID, tenantSlug, tOwner, _ := extractTenantClaims(token) | ||
| md, _ := metadata.FromIncomingContext(ctx) | ||
| md = md.Copy() | ||
|
|
||
| if tenantID != "" { | ||
| md.Set("md-tenant-id", tenantID) | ||
| } | ||
|
|
||
| if tenantSlug != "" { | ||
| md.Set("md-tenant-slug", tenantSlug) | ||
| } | ||
|
|
||
| if tOwner != "" { | ||
| md.Set("md-tenant-owner", tOwner) | ||
| } | ||
|
|
||
| ctx = metadata.NewIncomingContext(ctx, md) | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider logging when tenant claim extraction fails.
The extractTenantClaims error is silently discarded on line 104. While this is defensive (authorization already passed), logging at debug level could help troubleshoot tenant propagation issues in multi-tenant deployments.
💡 Suggested improvement
// Propagate tenant claims if multi-tenant mode is enabled
if os.Getenv("MULTI_TENANT_ENABLED") == "true" {
- tenantID, tenantSlug, tOwner, _ := extractTenantClaims(token)
+ tenantID, tenantSlug, tOwner, extractErr := extractTenantClaims(token)
+ if extractErr != nil {
+ logErrorf(ctx, auth.Logger, "failed to extract tenant claims: %v", extractErr)
+ }
md, _ := metadata.FromIncomingContext(ctx)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@auth/middleware/middlewareGRPC.go` around lines 102 - 121,
extractTenantClaims' returned error is being discarded; capture the fourth
return value (err) instead of using '_' and log it at debug level when
MULTI_TENANT_ENABLED is true so tenant propagation failures are visible during
troubleshooting. Update the block that calls extractTenantClaims(token) to
assign the error (e.g., tenantID, tenantSlug, tOwner, err :=
extractTenantClaims(token)), and if err != nil call the existing logger (e.g.,
authLogger or the package logger) with a debug message including the error and
token/ctx context; leave behavior unchanged otherwise and still set metadata via
metadata.FromIncomingContext / metadata.NewIncomingContext as before.
| // Propagate tenant claims if multi-tenant mode is enabled | ||
| if os.Getenv("MULTI_TENANT_ENABLED") == "true" { | ||
| tenantID, tenantSlug, tOwner, _ := extractTenantClaims(token) | ||
| md, _ := metadata.FromIncomingContext(ctx) | ||
| md = md.Copy() | ||
|
|
||
| if tenantID != "" { | ||
| md.Set("md-tenant-id", tenantID) | ||
| } | ||
|
|
||
| if tenantSlug != "" { | ||
| md.Set("md-tenant-slug", tenantSlug) | ||
| } | ||
|
|
||
| if tOwner != "" { | ||
| md.Set("md-tenant-owner", tOwner) | ||
| } | ||
|
|
||
| ctx = metadata.NewIncomingContext(ctx, md) | ||
| ss = &wrappedServerStream{ServerStream: ss, ctx: ctx} | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Duplicate tenant propagation logic between unary and stream interceptors.
Lines 270-290 duplicate the tenant claim propagation logic from lines 102-121. Consider extracting this into a shared helper function to reduce maintenance burden.
♻️ Proposed refactor
// propagateTenantClaims extracts tenant claims from the token and injects them into metadata.
// Returns the updated context with tenant metadata.
func propagateTenantClaims(ctx context.Context, token string, logger log.Logger) context.Context {
if os.Getenv("MULTI_TENANT_ENABLED") != "true" {
return ctx
}
tenantID, tenantSlug, tOwner, err := extractTenantClaims(token)
if err != nil {
logErrorf(ctx, logger, "failed to extract tenant claims: %v", err)
return ctx
}
md, _ := metadata.FromIncomingContext(ctx)
md = md.Copy()
if tenantID != "" {
md.Set("md-tenant-id", tenantID)
}
if tenantSlug != "" {
md.Set("md-tenant-slug", tenantSlug)
}
if tOwner != "" {
md.Set("md-tenant-owner", tOwner)
}
return metadata.NewIncomingContext(ctx, md)
}Then use in both interceptors:
ctx = propagateTenantClaims(ctx, token, auth.Logger)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@auth/middleware/middlewareGRPC.go` around lines 270 - 290, Extract the
duplicated tenant propagation block into a helper function
propagateTenantClaims(ctx context.Context, token string, logger log.Logger)
context.Context that checks os.Getenv("MULTI_TENANT_ENABLED"), calls
extractTenantClaims(token), logs extraction errors, copies incoming metadata,
sets "md-tenant-id", "md-tenant-slug", and "md-tenant-owner" when present, and
returns metadata.NewIncomingContext(ctx, md); then replace the duplicated code
in both the unary interceptor (where extractTenantClaims is currently used) and
the stream interceptor (where wrappedServerStream is created) by calling ctx =
propagateTenantClaims(ctx, token, auth.Logger) and for the stream update ss =
&wrappedServerStream{ServerStream: ss, ctx: ctx} after calling the helper.
| github.com/golang-jwt/jwt/v5 v5.3.1 | ||
| github.com/stretchr/testify v1.11.1 | ||
| go.opentelemetry.io/otel v1.42.0 | ||
| google.golang.org/grpc v1.79.2 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for security advisories affecting grpc-go
gh api graphql -f query='
{
securityVulnerabilities(first: 5, ecosystem: GO, package: "google.golang.org/grpc") {
nodes {
advisory {
summary
severity
publishedAt
ghsaId
}
vulnerableVersionRange
firstPatchedVersion {
identifier
}
}
}
}'Repository: LerianStudio/lib-auth
Length of output: 225
🌐 Web query:
GHSA-p77j-4mvh-x3m3 google.golang.org/grpc vulnerability
💡 Result:
GHSA-p77j-4mvh-x3m3 (aka CVE-2026-33186) is a critical authorization-bypass in gRPC-Go (google.golang.org/grpc) caused by improper validation of the HTTP/2 :path pseudo-header. If an attacker sends a request whose :path omits the required leading slash (e.g., Service/Method instead of /Service/Method), the server may still route it, but path-based authorization interceptors may evaluate the non-canonical method string and fail to match “deny” rules—potentially allowing access when a fallback “allow” rule exists. [1]
- Affected:
google.golang.org/grpc< 1.79.3 [1] - Fixed in: 1.79.3 [1]
- Recommended remediation: upgrade to v1.79.3+. [1]
- Workaround (if you can’t upgrade immediately): add an outermost interceptor that rejects any method where
info.FullMethodis empty or doesn’t start with/(the advisory includes an example), and/or enforce strict HTTP/2 pseudo-header validation at the proxy/load balancer layer. [1]
Source: GitHub Advisory Database / grpc-go security advisory. [1]
References:
[1] GHSA-p77j-4mvh-x3m3
🌐 Web query:
gRPC-Go authorization bypass missing leading slash :path vulnerability
💡 Result:
What the vulnerability is
A recently disclosed issue (tracked publicly as CVE-2026-33186) describes an authorization bypass in gRPC-Go when an attacker sends an HTTP/2 request with a malformed :path pseudo-header that is missing the required leading / (e.g., pkg.Service/Method instead of /pkg.Service/Method). The bypass occurs only when authorization logic “fails open” (i.e., treats an unrecognized / unmatched method name as allowed). One reported affected scenario is gRPC-Go’s experimental xDS RBAC authorizer behavior in certain policy modes. [1]
Why it can bypass auth (mechanics)
In gRPC-Go’s xDS RBAC implementation, RBAC matching is performed against values placed into metadata, including :path. The code populates :path from the gRPC method name (grpc.Method(ctx)) rather than from the raw incoming :path header. [2] If an attacker can influence the method string format such that it doesn’t match policy expectations (e.g., missing the leading slash), then policies that rely on matching may not trigger, and any configuration that effectively allows on non-match can be bypassed. [1]
Impact / when you are actually vulnerable
You are most likely exposed if all of the following are true:
- You use gRPC-Go xDS RBAC / authorization (the experimental RBAC path described in the disclosure). [1]
- Your effective authorization stance is fail-open on “unknown/unmatched method” (commonly: deny-list style policies where “no match” means “allow”). [1]
If you use allow-list style authorization (default-deny: “only explicitly allowed methods pass”), this specific issue is much less likely to become an auth bypass (though malformed :path should still be treated as suspicious input). [1]
Mitigations you can apply immediately
- Fail closed: ensure your authorizer denies any request whose method/path is not recognized or does not match an expected canonical form. [1]
- Enforce canonical gRPC method format at the edge (proxy / gateway / interceptor): reject any request where
:pathdoes not start with/. - Prefer ALLOW (default-deny) RBAC policy posture over DENY-only posture for method-level access control. [1]
Patch status (as of 2026-03-20)
Public discussion exists, but I did not find an official upstream gRPC-Go security advisory or fixed-version reference in the sources retrieved above; treat this as “track upstream and be ready to upgrade” once gRPC-Go publishes a fix/release.
Sources: [1] [2]
🌐 Web query:
google.golang.org/grpc v1.79.2 security vulnerability patched version
💡 Result:
For google.golang.org/grpc v1.79.2, the patched (non-vulnerable) version is v1.79.3. The gRPC-Go advisory GHSA-p77j-4mvh-x3m3 / CVE-2026-33186 lists affected versions < 1.79.3 and patched version 1.79.3. [1]
Sources:
[1] (github.com)
Citations:
Critical security vulnerability in google.golang.org/grpc v1.79.2: Upgrade to v1.79.3 or later.
GHSA-p77j-4mvh-x3m3 (CVE-2026-33186) is a critical authorization bypass in gRPC-Go caused by improper validation of the HTTP/2 :path pseudo-header. If an attacker sends a request with a malformed :path that omits the required leading slash (e.g., Service/Method instead of /Service/Method), path-based authorization interceptors may fail to match deny rules and incorrectly allow access. Upgrade immediately to v1.79.3+.
If an immediate upgrade is not possible, add an outermost interceptor that rejects any request where the method name is empty or does not start with /.
🧰 Tools
🪛 OSV Scanner (2.3.3)
[CRITICAL] 11-11: google.golang.org/grpc 1.79.2: gRPC-Go has an authorization bypass via missing leading slash in :path
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@go.mod` at line 11, The dependency google.golang.org/grpc pinned to v1.79.2
contains a critical auth bypass (CVE-2026-33186); update the module version in
go.mod to v1.79.3 or later to fix it. If you cannot upgrade immediately, add an
outermost unary and stream interceptor on your gRPC server (where you call
grpc.NewServer or configure interceptors) that rejects requests whose full
method string is empty or does not start with '/' to block malformed :path
values; after upgrading remove the temporary interceptor. Ensure you update
go.mod's google.golang.org/grpc entry and run go mod tidy to refresh the lock.
| Elastic License 2.0 | ||
|
|
||
| URL: https://www.elastic.co/licensing/elastic-license | ||
|
|
||
| ## Acceptance | ||
|
|
||
| By using the software, you agree to all of the terms and conditions below. | ||
|
|
||
| ## Copyright License | ||
|
|
||
| The licensor grants you a non-exclusive, royalty-free, worldwide, | ||
| non-sublicensable, non-transferable license to use, copy, distribute, make | ||
| available, and prepare derivative works of the software, in each case subject to | ||
| the limitations and conditions below. | ||
|
|
||
| ## Limitations | ||
|
|
||
| You may not provide the software to third parties as a hosted or managed | ||
| service, where the service provides users with access to any substantial set of | ||
| the features or functionality of the software. | ||
|
|
||
| You may not move, change, disable, or circumvent the license key functionality | ||
| in the software, and you may not remove or obscure any functionality in the | ||
| software that is protected by the license key. | ||
|
|
||
| You may not alter, remove, or obscure any licensing, copyright, or other notices | ||
| of the licensor in the software. Any use of the licensor's trademarks is subject | ||
| to applicable law. | ||
|
|
||
| ## Patents | ||
|
|
||
| The licensor grants you a license, under any patent claims the licensor can | ||
| license, or becomes able to license, to make, have made, use, sell, offer for | ||
| sale, import and have imported the software, in each case subject to the | ||
| limitations and conditions in this license. This license does not cover any | ||
| patent claims that you cause to be infringed by modifications or additions to | ||
| the software. If you or your company make any written claim that the software | ||
| infringes or contributes to infringement of any patent, your patent license for | ||
| the software granted under these terms ends immediately. If your company makes | ||
| such a claim, your patent license ends immediately for work on behalf of your | ||
| company. | ||
|
|
||
| ## Notices | ||
|
|
||
| You must ensure that anyone who gets a copy of any part of the software from you | ||
| also gets a copy of these terms. | ||
|
|
||
| If you modify the software, you must include in any modified copies of the | ||
| software prominent notices stating that you have modified the software. | ||
|
|
||
| ## No Other Rights | ||
|
|
||
| These terms do not imply any licenses other than those expressly granted in | ||
| these terms. | ||
|
|
||
| ## Termination | ||
|
|
||
| If you use the software in violation of these terms, such use is not licensed, | ||
| and your licenses will automatically terminate. If the licensor provides you | ||
| with a notice of your violation, and you cease all violation of this license no | ||
| later than 30 days after you receive that notice, your licenses will be | ||
| reinstated retroactively. However, if you violate these terms after such | ||
| reinstatement, any additional violation of these terms will cause your licenses | ||
| to terminate automatically and permanently. | ||
|
|
||
| ## No Liability | ||
|
|
||
| *As far as the law allows, the software comes as is, without any warranty or | ||
| condition, and the licensor will not be liable to you for any damages arising | ||
| out of these terms or the use or nature of the software, under any kind of | ||
| legal claim.* | ||
|
|
||
| ## Definitions | ||
|
|
||
| The **licensor** is the entity offering these terms, and the **software** is the | ||
| software the licensor makes available under these terms, including any portion | ||
| of it. | ||
|
|
||
| **you** refers to the individual or entity agreeing to these terms. | ||
|
|
||
| **your company** is any legal entity, sole proprietorship, or other kind of | ||
| organization that you work for, plus all organizations that have control over, | ||
| are under the control of, or are under common control with that | ||
| organization. **control** means ownership of substantially all the assets of an | ||
| entity, or the power to direct its management and policies by vote, contract, or | ||
| otherwise. Control can be direct or indirect. | ||
|
|
||
| **your licenses** are all the licenses granted to you for the software under | ||
| these terms. | ||
|
|
||
| **use** means anything you do with the software requiring one of your licenses. | ||
|
|
||
| **trademark** means trademarks, service marks, and similar rights. |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Read-only consistency check for license references across repo artifacts.
fd -HI 'LICENSE*|README*|NOTICE*|COPYING*|go.mod|package.json|pyproject.toml|setup.py|pom.xml|Cargo.toml' .
rg -n -C2 'SPDX|license|Elastic|Apache|MIT|BSD|GPL|MPL' .Repository: LerianStudio/lib-auth
Length of output: 3615
🏁 Script executed:
# Check README.md for license section
head -100 ./README.md | tail -50
# Check go.mod for license declaration
cat ./go.mod
# Search for any SPDX headers or old license references in code
rg -l 'SPDX-License-Identifier|Apache|MIT|BSD' --type-list | head -20
fd -e go -e ts -e js -e py | head -20 | xargs -I {} head -5 {}Repository: LerianStudio/lib-auth
Length of output: 5048
🏁 Script executed:
# Check if README.md mentions license/Elastic
rg -i 'license|elastic' ./README.md -A 2 -B 2
# Search for SPDX headers in source files
rg 'SPDX-License-Identifier'
# List all files in repo to check for conflicting licenses
find . -maxdepth 2 -type f \( -name "LICENSE*" -o -name "COPYING*" -o -name "NOTICE*" \)
# Check if any go.mod file has license field
rg 'license' ./go.modRepository: LerianStudio/lib-auth
Length of output: 74
Update README and source files to document Elastic License 2.0 adoption.
The Elastic License 2.0 file was added, but the license change is not documented elsewhere. README.md contains no license statement, source files have no SPDX headers, and go.mod includes no license metadata. This creates a compliance gap where downstream users and integrators remain unaware of the licensing restrictions (notably the hosted/managed service limitation). Add an explicit license section to README.md, include SPDX-License-Identifier headers in source files, and consider adding license metadata to go.mod for visibility.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@LICENSE` around lines 1 - 93, The repo added Elastic License 2.0 (LICENSE)
but lacked propagation; update README.md to add an explicit "License" section
that names "Elastic License 2.0" and briefly calls out the
hosted/managed-service restriction, add SPDX-License-Identifier: Elastic-2.0
headers to all source files (e.g., top of .go/.ts/.js files) and ensure go.mod
contains license metadata (module/comments or a license directive) so tooling
sees Elastic-2.0; search for README.md, go.mod and all source files to apply
these changes consistently and commit them alongside the LICENSE file.
| .PHONY: goreleaser | ||
| goreleaser: | ||
| $(call print_title,Creating release snapshot with goreleaser) | ||
| $(call check_command,goreleaser,"go install github.com/goreleaser/goreleaser@latest") | ||
| goreleaser release --snapshot --skip-publish --clean | ||
| @echo "$(GREEN)$(BOLD)[ok]$(NC) Release snapshot created successfully$(GREEN) ✔️$(NC)" |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
goreleaser --skip-publish deprecated flag
💡 Result:
goreleaser release --skip-publish was deprecated (since v1.21) as part of consolidating multiple --skip-* flags into a single --skip flag, and it was removed in GoReleaser v2.0 (2024-05-26). Use --skip=publish instead. [1]
Examples:
- Before:
goreleaser release --skip-validate --skip-publish - After:
goreleaser release --skip=validate,publish(or--skip=validate --skip=publish) [1]
goreleaser release --help lists publish as a valid --skip option. [2]
Sources
[1] GoReleaser Deprecation notices (the --skip consolidation, incl. --skip-publish) (goreleaser.com)
[2] GoReleaser goreleaser release command docs (--skip valid options incl. publish) (goreleaser.com)
Citations:
Replace deprecated --skip-publish flag with --skip=publish.
The --skip-publish flag was deprecated in goreleaser v1.21 and removed entirely in v2.0 (2024-05-26). This will cause the command to fail with newer goreleaser versions.
♻️ Proposed fix
goreleaser:
$(call print_title,Creating release snapshot with goreleaser)
$(call check_command,goreleaser,"go install github.com/goreleaser/goreleaser@latest")
- goreleaser release --snapshot --skip-publish --clean
+ goreleaser release --snapshot --skip=publish --clean
`@echo` "$(GREEN)$(BOLD)[ok]$(NC) Release snapshot created successfully$(GREEN) ✔️$(NC)"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .PHONY: goreleaser | |
| goreleaser: | |
| $(call print_title,Creating release snapshot with goreleaser) | |
| $(call check_command,goreleaser,"go install github.com/goreleaser/goreleaser@latest") | |
| goreleaser release --snapshot --skip-publish --clean | |
| @echo "$(GREEN)$(BOLD)[ok]$(NC) Release snapshot created successfully$(GREEN) ✔️$(NC)" | |
| .PHONY: goreleaser | |
| goreleaser: | |
| $(call print_title,Creating release snapshot with goreleaser) | |
| $(call check_command,goreleaser,"go install github.com/goreleaser/goreleaser@latest") | |
| goreleaser release --snapshot --skip=publish --clean | |
| `@echo` "$(GREEN)$(BOLD)[ok]$(NC) Release snapshot created successfully$(GREEN) ✔️$(NC)" |
🧰 Tools
🪛 checkmake (0.2.2)
[warning] 269-269: Missing required phony target "all"
(minphony)
[warning] 269-269: Missing required phony target "test"
(minphony)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Makefile` around lines 269 - 274, Update the goreleaser Makefile target
"goreleaser" to replace the removed flag form "--skip-publish" with the new
"--skip=publish"; specifically, in the command invoked by the goreleaser target
(the line that currently runs "goreleaser release --snapshot --skip-publish
--clean"), change the flag to "--skip=publish" so the release snapshot command
works with goreleaser v1.21+ and v2.0.
| if [ -f .ignorecoverunit ]; then \ | ||
| echo "Filtering coverage with .ignorecoverunit patterns..."; \ | ||
| patterns=$$(grep -v '^#' .ignorecoverunit | grep -v '^$$' | tr '\n' '|' | sed 's/|$$//'); \ | ||
| if [ -n "$$patterns" ]; then \ | ||
| regex_patterns=$$(echo "$$patterns" | sed 's/\./\\./g' | sed 's/\*/.*/g'); \ | ||
| head -1 $(TEST_REPORTS_DIR)/unit_coverage.out > $(TEST_REPORTS_DIR)/unit_coverage_filtered.out; \ | ||
| tail -n +2 $(TEST_REPORTS_DIR)/unit_coverage.out | grep -vE "$$regex_patterns" >> $(TEST_REPORTS_DIR)/unit_coverage_filtered.out || true; \ | ||
| mv $(TEST_REPORTS_DIR)/unit_coverage_filtered.out $(TEST_REPORTS_DIR)/unit_coverage.out; \ | ||
| echo "Excluded patterns: $$patterns"; \ | ||
| fi; \ |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Regex conversion for .ignorecoverunit patterns is basic.
The sed substitutions on lines 225-225 convert . → \. and * → .*, which handles the documented patterns (*_mock.go). However, this won't correctly handle more complex glob patterns or paths containing regex metacharacters like +, ?, [, etc.
This is acceptable for the current use case, but consider documenting this limitation in .ignorecoverunit or using a more robust glob-to-regex conversion if patterns become more complex.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@mk/tests.mk` around lines 221 - 230, The current glob-to-regex conversion in
mk/tests.mk (the sed pipeline that builds regex_patterns from patterns read from
.ignorecoverunit) only escapes '.' and converts '*' to '.*', so it fails on
other glob metacharacters (e.g., '+', '?', '[]') — update the file to either (A)
document this limitation immediately above the block that defines
patterns/regex_patterns and explain acceptable pattern syntax for
.ignorecoverunit, or (B) replace the simple sed conversion that produces
regex_patterns with a more robust glob-to-regex conversion (e.g., a small
perl/python one-liner or utility) that properly escapes regex metacharacters
while translating globs; ensure the rest of the flow (reading patterns into
patterns, filtering unit_coverage.out into unit_coverage_filtered.out, and mv
back) still uses the new regex_patterns variable.
The auth service may return the 'code' field as a number (e.g. 401) instead of a string. This caused json.Unmarshal to fail with a type mismatch, surfacing as a 500 instead of propagating the actual error. Add unmarshalErrorResponse helper using json.RawMessage to tolerate both string and numeric code values in checkAuthorization and GetApplicationToken. X-Lerian-Ref: 0x1
…code fix(auth/middleware): handle numeric code field in auth error response
## [2.5.0-beta.9](v2.5.0-beta.8...v2.5.0-beta.9) (2026-03-20) ### Bug Fixes * **auth/middleware:** handle numeric code field in auth error response ([165db5f](165db5f))
|
🎉 This PR is included in version 2.5.0-beta.9 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
auth/middleware/middleware.go (1)
160-166:⚠️ Potential issue | 🟠 MajorAdd HTTP timeouts to all outbound auth-service clients.
All three
http.Client{}instances in this file (lines 160, 260, 403) lack timeout configuration. Clients without timeouts can hang indefinitely on network stalls, which risks goroutine exhaustion and service unavailability under load.💡 Proposed fix
@@ const ( normalUser string = "normal-user" pluginName string = "plugin-auth" + defaultHTTPTimeout = 5 * time.Second ) @@ - client := &http.Client{} + client := &http.Client{Timeout: defaultHTTPTimeout} @@ - client := &http.Client{} + client := &http.Client{Timeout: defaultHTTPTimeout} @@ - client := &http.Client{} + client := &http.Client{Timeout: defaultHTTPTimeout}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@auth/middleware/middleware.go` around lines 160 - 166, The three outbound HTTP clients created as client := &http.Client{} in middleware.go (the client used to GET healthURL and the other two client instances at the other locations) lack timeouts and can hang; update each client construction to set a sensible Timeout (e.g. replace &http.Client{} with &http.Client{Timeout: httpClientTimeout} or a literal like 5*time.Second), make the timeout configurable via a package-level const/var (httpClientTimeout) or existing config, and consider reusing a single shared http.Client instead of creating per-request clients; ensure the time package is imported if needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@auth/middleware/middleware.go`:
- Around line 160-166: The three outbound HTTP clients created as client :=
&http.Client{} in middleware.go (the client used to GET healthURL and the other
two client instances at the other locations) lack timeouts and can hang; update
each client construction to set a sensible Timeout (e.g. replace &http.Client{}
with &http.Client{Timeout: httpClientTimeout} or a literal like 5*time.Second),
make the timeout configurable via a package-level const/var (httpClientTimeout)
or existing config, and consider reusing a single shared http.Client instead of
creating per-request clients; ensure the time package is imported if needed.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: f31cbe06-e3a5-467f-be80-815efca4a0b5
📒 Files selected for processing (2)
CHANGELOG.mdauth/middleware/middleware.go
…0-beta.9 chore(deps): bump lib-commons to v4.2.0
## [2.5.0-beta.10](v2.5.0-beta.9...v2.5.0-beta.10) (2026-03-21)
|
🎉 This PR is included in version 2.5.0-beta.10 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 2.5.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Pull Request Checklist
Pull Request Type
Checklist
Please check each item after it's completed.
Additional Notes
Obs: Please, always remember to target your PR to develop branch instead of main.