@@ -224,18 +224,11 @@ func (t *LLMProviderTransformer) transformProxy(proxy *api.LLMProxyConfiguration
224224
225225 // Phase 2: Process User-Defined Policies
226226 if proxy .Spec .Policies != nil {
227+ registerExplicitLLMPolicyOperations (operationRegistry , * proxy .Spec .Policies , nil )
228+
227229 for _ , llmPol := range * proxy .Spec .Policies {
228230 for _ , pathEntry := range llmPol .Paths {
229- // Expand wildcard methods in policy
230- var policyMethods []string
231- if len (pathEntry .Methods ) == 1 && string (pathEntry .Methods [0 ]) == "*" {
232- policyMethods = constants .WILDCARD_HTTP_METHODS
233- } else {
234- policyMethods = make ([]string , len (pathEntry .Methods ))
235- for i , m := range pathEntry .Methods {
236- policyMethods [i ] = string (m )
237- }
238- }
231+ policyMethods := expandLLMPolicyMethods (pathEntry .Methods )
239232
240233 for _ , policyMethod := range policyMethods {
241234 attachedPolicyPaths := make (map [string ]bool )
@@ -244,11 +237,7 @@ func (t *LLMProviderTransformer) transformProxy(proxy *api.LLMProxyConfiguration
244237 // Create operation if it doesn't exist (dynamic operation creation)
245238 key := pathMethodKey {path : pathEntry .Path , method : policyMethod }
246239 if _ , exists := operationRegistry [key ]; ! exists {
247- op := & api.Operation {
248- Path : pathEntry .Path ,
249- Method : api .OperationMethod (policyMethod ),
250- }
251- operationRegistry [key ] = op
240+ op := ensureOperation (operationRegistry , pathEntry .Path , policyMethod )
252241 methodOperations = append (methodOperations , op )
253242 }
254243
@@ -451,18 +440,13 @@ func (t *LLMProviderTransformer) transformProvider(provider *api.LLMProviderConf
451440
452441 // Phase 3: Process User-Defined Policies
453442 if provider .Spec .Policies != nil {
443+ registerExplicitLLMPolicyOperations (operationRegistry , * provider .Spec .Policies , func (path , method string ) bool {
444+ return ! isDeniedByException (path , method , deniedPathMethods )
445+ })
446+
454447 for _ , llmPol := range * provider .Spec .Policies {
455448 for _ , pathEntry := range llmPol .Paths {
456- // Expand wildcard methods in policy
457- var policyMethods []string
458- if len (pathEntry .Methods ) == 1 && string (pathEntry .Methods [0 ]) == "*" {
459- policyMethods = constants .WILDCARD_HTTP_METHODS
460- } else {
461- policyMethods = make ([]string , len (pathEntry .Methods ))
462- for i , m := range pathEntry .Methods {
463- policyMethods [i ] = string (m )
464- }
465- }
449+ policyMethods := expandLLMPolicyMethods (pathEntry .Methods )
466450
467451 for _ , policyMethod := range policyMethods {
468452 attachedPolicyPaths := make (map [string ]bool )
@@ -477,11 +461,7 @@ func (t *LLMProviderTransformer) transformProvider(provider *api.LLMProviderConf
477461 key := pathMethodKey {path : pathEntry .Path , method : policyMethod }
478462 if _ , exists := operationRegistry [key ]; ! exists {
479463 // Create operation for user policy
480- op := & api.Operation {
481- Path : pathEntry .Path ,
482- Method : api .OperationMethod (policyMethod ),
483- }
484- operationRegistry [key ] = op
464+ op := ensureOperation (operationRegistry , pathEntry .Path , policyMethod )
485465 methodOperations = append (methodOperations , op )
486466 }
487467
@@ -567,18 +547,13 @@ func (t *LLMProviderTransformer) transformProvider(provider *api.LLMProviderConf
567547
568548 // Phase 3: Process Policies with Dynamic Operation Creation
569549 if provider .Spec .Policies != nil {
550+ registerExplicitLLMPolicyOperations (operationRegistry , * provider .Spec .Policies , func (path , method string ) bool {
551+ return isAllowedByAccessControl (path , method , normalizedExceptions )
552+ })
553+
570554 for _ , llmPol := range * provider .Spec .Policies {
571555 for _ , pathEntry := range llmPol .Paths {
572- // Expand wildcard methods in policy
573- var policyMethods []string
574- if len (pathEntry .Methods ) == 1 && string (pathEntry .Methods [0 ]) == "*" {
575- policyMethods = constants .WILDCARD_HTTP_METHODS
576- } else {
577- policyMethods = make ([]string , len (pathEntry .Methods ))
578- for i , m := range pathEntry .Methods {
579- policyMethods [i ] = string (m )
580- }
581- }
556+ policyMethods := expandLLMPolicyMethods (pathEntry .Methods )
582557
583558 for _ , policyMethod := range policyMethods {
584559 attachedPolicyPaths := make (map [string ]bool )
@@ -590,11 +565,7 @@ func (t *LLMProviderTransformer) transformProvider(provider *api.LLMProviderConf
590565 key := pathMethodKey {path : pathEntry .Path , method : policyMethod }
591566 if _ , exists := operationRegistry [key ]; ! exists {
592567 // Create operation for specific policy path covered by wildcard access control
593- op := & api.Operation {
594- Path : pathEntry .Path ,
595- Method : api .OperationMethod (policyMethod ),
596- }
597- operationRegistry [key ] = op
568+ op := ensureOperation (operationRegistry , pathEntry .Path , policyMethod )
598569 methodOperations = append (methodOperations , op )
599570 }
600571 }
@@ -803,6 +774,51 @@ func appendOperationPolicy(op *api.Operation, pol api.Policy) {
803774 op .Policies = & existing
804775}
805776
777+ // ensureOperation checks if an operation for the given path+method exists in the registry, and creates it if not
778+ func ensureOperation (operationRegistry map [pathMethodKey ]* api.Operation , path , method string ) * api.Operation {
779+ key := pathMethodKey {path : path , method : method }
780+ if op , exists := operationRegistry [key ]; exists {
781+ return op
782+ }
783+
784+ op := & api.Operation {
785+ Path : path ,
786+ Method : api .OperationMethod (method ),
787+ }
788+ operationRegistry [key ] = op
789+ return op
790+ }
791+
792+ // expandLLMPolicyMethods takes the methods defined in an LLM policy and expands them to actual HTTP methods if wildcard is used
793+ func expandLLMPolicyMethods (methods []api.LLMPolicyPathMethods ) []string {
794+ if len (methods ) == 1 && string (methods [0 ]) == constants .WILD_CARD {
795+ return append ([]string (nil ), constants .WILDCARD_HTTP_METHODS ... )
796+ }
797+
798+ expanded := make ([]string , len (methods ))
799+ for i , method := range methods {
800+ expanded [i ] = string (method )
801+ }
802+ return expanded
803+ }
804+
805+ // registerExplicitLLMPolicyOperations iterates through the explicitly defined policies in the LLM policy and ensures that operations
806+ // exist for their paths and methods in the operation registry. The shouldRegister callback allows conditional registration based on
807+ // path and method (e.g., to skip paths/methods denied by access control exceptions).
808+ func registerExplicitLLMPolicyOperations (operationRegistry map [pathMethodKey ]* api.Operation , policies []api.LLMPolicy ,
809+ shouldRegister func (path , method string ) bool ) {
810+ for _ , llmPol := range policies {
811+ for _ , pathEntry := range llmPol .Paths {
812+ for _ , method := range expandLLMPolicyMethods (pathEntry .Methods ) {
813+ if shouldRegister != nil && ! shouldRegister (pathEntry .Path , method ) {
814+ continue
815+ }
816+ ensureOperation (operationRegistry , pathEntry .Path , method )
817+ }
818+ }
819+ }
820+ }
821+
806822func getOperationsForMethod (operationRegistry map [pathMethodKey ]* api.Operation , method string ) []* api.Operation {
807823 ops := make ([]* api.Operation , 0 )
808824 for key , op := range operationRegistry {
0 commit comments