@@ -34,6 +34,11 @@ type resource string
3434type target string
3535type lookupKey string
3636
37+ type keyComponents struct {
38+ r resource
39+ t target
40+ }
41+
3742// LookupCacheEntry holds a cached lookup result with TTL tracking
3843type LookupCacheEntry struct {
3944 Results []string
@@ -46,6 +51,7 @@ type projectAuthzCache struct {
4651 directRelationCache * lru.MonitoredLRUCache [resourceTargetRelation , bool ] // resource:target:relation -> bool, e.g. file1:user2:owner -> false
4752 directResourcesIndex map [resource ]map [target ][]resourceTargetRelation
4853 directTargetsIndex map [target ]map [resource ][]resourceTargetRelation
54+ directKeyComponents map [resourceTargetRelation ]keyComponents
4955 indirectRelationCache * lru.MonitoredLRUCache [resourceTargetRelation , bool ] // resource:target:relation -> bool, e.g. file1:user2:owner -> false
5056 lookupCache * lru.MonitoredLRUCache [lookupKey , * LookupCacheEntry ] // lookup cache for WhoCanAccess/WhatCanTargetAccess
5157 lookupCacheEnabled bool
@@ -89,6 +95,7 @@ func NewProjectAuthzCache(ctx context.Context, remoteChangesChecker RemoteChange
8995 pc := & projectAuthzCache {
9096 directResourcesIndex : make (map [resource ]map [target ][]resourceTargetRelation ),
9197 directTargetsIndex : make (map [target ]map [resource ][]resourceTargetRelation ),
98+ directKeyComponents : make (map [resourceTargetRelation ]keyComponents ),
9299 indirectRelationCache : indirectRelationCache ,
93100 lookupCache : lookupCache ,
94101 lookupCacheEnabled : lookupCacheEnabled ,
@@ -271,6 +278,7 @@ func (pc *projectAuthzCache) addDirectRelation(ctx context.Context, r *descope.F
271278 pc .directRelationCache .Add (ctx , key , isAllowed )
272279 resource := resource (r .Resource )
273280 target := target (r .Target )
281+ pc .directKeyComponents [key ] = keyComponents {r : resource , t : target }
274282 pc .addKeyToDirectResourceIndex (key , resource , target )
275283 pc .addKeyToDirectTargetIndex (key , resource , target )
276284}
@@ -303,6 +311,7 @@ func (pc *projectAuthzCache) removeDirectRelation(ctx context.Context, r *descop
303311 target := target (r .Target )
304312 pc .removeKeyFromResourceIndex (resource , target , key )
305313 pc .removeKeyFromTargetIndex (resource , target , key )
314+ delete (pc .directKeyComponents , key )
306315}
307316
308317func (pc * projectAuthzCache ) removeDirectRelationByResource (ctx context.Context , r resource ) {
@@ -387,10 +396,13 @@ func key(r *descope.FGARelation) resourceTargetRelation {
387396
388397func (pc * projectAuthzCache ) removeIndexOnCacheEviction (key resourceTargetRelation , _ bool ) {
389398 // on eviction, we need to remove the keys from the indexes as well
390- splitKey := strings .Split (string (key ), ":" )
391- resource , target := resource (splitKey [0 ]), target (splitKey [1 ])
392- pc .removeKeyFromResourceIndex (resource , target , key )
393- pc .removeKeyFromTargetIndex (resource , target , key )
399+ components , ok := pc .directKeyComponents [key ]
400+ if ! ok {
401+ return
402+ }
403+ pc .removeKeyFromResourceIndex (components .r , components .t , key )
404+ pc .removeKeyFromTargetIndex (components .r , components .t , key )
405+ delete (pc .directKeyComponents , key )
394406}
395407
396408// must be called while holding the mutex
@@ -404,6 +416,7 @@ func (pc *projectAuthzCache) purgeAllCaches(ctx context.Context) {
404416func (pc * projectAuthzCache ) purgeRelationCaches (ctx context.Context ) {
405417 pc .directResourcesIndex = make (map [resource ]map [target ][]resourceTargetRelation )
406418 pc .directTargetsIndex = make (map [target ]map [resource ][]resourceTargetRelation )
419+ pc .directKeyComponents = make (map [resourceTargetRelation ]keyComponents )
407420 pc .directRelationCache .Purge (ctx )
408421 pc .indirectRelationCache .Purge (ctx )
409422 if pc .lookupCache != nil {
0 commit comments