Skip to content

Conversation

@akshayutture-augment
Copy link

* remove the use of client side cache for in-proc authz client

Co-authored-by: Gabriel MABILLE <[email protected]>

* add a permission denial cache, fetch perms if not in either of the caches

Co-authored-by: Gabriel MABILLE <[email protected]>

* Clean up tests

Co-authored-by: Ieva <[email protected]>

* Cache tests

Co-authored-by: Ieva <[email protected]>

* Add test to list + cache

Co-authored-by: Ieva <[email protected]>

* Add outdated cache test

Co-authored-by: Ieva <[email protected]>

* Re-organize metrics

Co-authored-by: Ieva <[email protected]>

---------

Co-authored-by: Gabriel MABILLE <[email protected]>
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@akshayutture-augment
Copy link
Author

@greptileai

@greptile-apps
Copy link

greptile-apps bot commented Nov 14, 2025

Greptile Overview

Confidence Score: 2/5

  • This PR has a critical logic bug that undermines the denial cache optimization
  • The denial cache will not be populated when cached permissions indicate a denial, meaning the optimization only works for database-fetched denials. This is a functional correctness issue that reduces the effectiveness of the caching improvements
  • pkg/services/authz/rbac/service.go requires attention - the Check method has a logic bug where the denial cache is not populated when using cached permissions

Important Files Changed

File Analysis

Filename Score Overview
pkg/services/authz/rbac/service.go 2/5 Introduced a permission denial cache and optimized Check/List methods to use cached permissions before DB lookup, but has critical logic bug where denials aren't cached when cached permissions indicate denial
pkg/services/authz/rbac/cache.go 5/5 Added new cache key function for permission denials with namespace, user, action, name, and parent folder as components
pkg/services/authz/rbac.go 4/5 Added NoopCache implementation for in-process client and refactored client creation to use authzlib options pattern
pkg/services/authz/rbac/service_test.go 5/5 Added comprehensive tests for cache behavior in Check and List operations, removed outdated test for removed caching logic in getUserPermissions

Sequence Diagram

sequenceDiagram
    participant Client
    participant Service
    participant DenialCache
    participant PermCache
    participant Database

    Client->>Service: Check(request)
    Service->>DenialCache: Get(permDenialKey)
    alt denial cached
        DenialCache-->>Service: found=true
        Service-->>Client: Allowed=false (cached)
    else denial not cached
        DenialCache-->>Service: found=false
        Service->>PermCache: Get(userPermKey)
        alt permissions cached
            PermCache-->>Service: cached permissions
            Service->>Service: checkPermission(cachedPerms)
            alt allowed
                Service-->>Client: Allowed=true (cached)
            else denied
                Note over Service,DenialCache: BUG: denial not cached here
                Service-->>Client: Allowed=false (not cached)
            end
        else permissions not cached
            PermCache-->>Service: not found
            Service->>Database: getIdentityPermissions()
            Database-->>Service: fresh permissions
            Service->>PermCache: Set(permissions)
            Service->>Service: checkPermission(permissions)
            alt denied
                Service->>DenialCache: Set(permDenialKey, true)
            end
            Service-->>Client: Allowed=result
        end
    end
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

4 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +123 to +136
cachedPerms, err := s.getCachedIdentityPermissions(ctx, checkReq.Namespace, checkReq.IdentityType, checkReq.UserUID, checkReq.Action)
if err == nil {
allowed, err := s.checkPermission(ctx, cachedPerms, checkReq)
if err != nil {
ctxLogger.Error("could not check permission", "error", err)
s.metrics.requestCount.WithLabelValues("true", "true", req.GetVerb(), req.GetGroup(), req.GetResource()).Inc()
return deny, err
}
if allowed {
s.metrics.permissionCacheUsage.WithLabelValues("true", checkReq.Action).Inc()
s.metrics.requestCount.WithLabelValues("false", "true", req.GetVerb(), req.GetGroup(), req.GetResource()).Inc()
return &authzv1.CheckResponse{Allowed: allowed}, nil
}
}
Copy link

Choose a reason for hiding this comment

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

logic: denial cache won't be populated when cached permissions indicate denial

When getCachedIdentityPermissions returns cached permissions and checkPermission determines allowed=false, the code returns early without caching the denial (line 135 exits before reaching line 154 where denials are cached). This means subsequent identical requests will repeatedly call getCachedIdentityPermissions and checkPermission instead of hitting the denial cache.

The denial cache is only populated when permissions are fetched from the database (line 154), not when using cached permissions.

Prompt To Fix With AI
This is a comment left during a code review.
Path: pkg/services/authz/rbac/service.go
Line: 123:136

Comment:
**logic:** denial cache won't be populated when cached permissions indicate denial

When `getCachedIdentityPermissions` returns cached permissions and `checkPermission` determines `allowed=false`, the code returns early without caching the denial (line 135 exits before reaching line 154 where denials are cached). This means subsequent identical requests will repeatedly call `getCachedIdentityPermissions` and `checkPermission` instead of hitting the denial cache.

The denial cache is only populated when permissions are fetched from the database (line 154), not when using cached permissions.

How can I resolve this? If you propose a fix, please make it concise.

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.

3 participants