5050public  class  PolicyManager  {
5151    private  static  final  Logger  logger  = LogManager .getLogger (PolicyManager .class );
5252
53-     record  ModuleEntitlements (Map <Class <? extends  Entitlement >, List <Entitlement >> entitlementsByType , FileAccessTree  fileAccess ) {
54-         public  static  final  ModuleEntitlements  NONE  = new  ModuleEntitlements (Map .of (), FileAccessTree .EMPTY );
53+     static  final  String  UNKNOWN_COMPONENT_NAME  = "(unknown)" ;
54+     static  final  String  SERVER_COMPONENT_NAME  = "(server)" ;
55+     static  final  String  APM_AGENT_COMPONENT_NAME  = "(APM agent)" ;
56+ 
57+     /** 
58+      * @param componentName the plugin name; or else one of the special component names 
59+      *                      like {@link #SERVER_COMPONENT_NAME} or {@link #APM_AGENT_COMPONENT_NAME}. 
60+      */ 
61+     record  ModuleEntitlements (
62+         String  componentName ,
63+         Map <Class <? extends  Entitlement >, List <Entitlement >> entitlementsByType ,
64+         FileAccessTree  fileAccess 
65+     ) {
5566
5667        ModuleEntitlements  {
5768            entitlementsByType  = Map .copyOf (entitlementsByType );
5869        }
5970
60-         public  static  ModuleEntitlements  from (List <Entitlement > entitlements ) {
71+         public  static  ModuleEntitlements  none (String  componentName ) {
72+             return  new  ModuleEntitlements (componentName , Map .of (), FileAccessTree .EMPTY );
73+         }
74+ 
75+         public  static  ModuleEntitlements  from (String  componentName , List <Entitlement > entitlements ) {
6176            var  fileEntitlements  = entitlements .stream ()
6277                .filter (e  -> e .getClass ().equals (FileEntitlement .class ))
6378                .map (e  -> (FileEntitlement ) e )
6479                .toList ();
6580            return  new  ModuleEntitlements (
81+                 componentName ,
6682                entitlements .stream ().collect (groupingBy (Entitlement ::getClass )),
6783                FileAccessTree .of (fileEntitlements )
6884            );
@@ -84,7 +100,7 @@ public <E extends Entitlement> Stream<E> getEntitlements(Class<E> entitlementCla
84100    final  Map <Module , ModuleEntitlements > moduleEntitlementsMap  = new  ConcurrentHashMap <>();
85101
86102    protected  final  Map <String , List <Entitlement >> serverEntitlements ;
87-     protected  final  List <Entitlement > agentEntitlements ;
103+     protected  final  List <Entitlement > apmAgentEntitlements ;
88104    protected  final  Map <String , Map <String , List <Entitlement >>> pluginsEntitlements ;
89105    private  final  Function <Class <?>, String > pluginResolver ;
90106
@@ -106,9 +122,9 @@ private static Set<Module> findSystemModules() {
106122    }
107123
108124    /** 
109-      * The package name containing agent  classes. 
125+      * The package name containing classes from the APM agent . 
110126     */ 
111-     private  final  String  agentsPackageName ;
127+     private  final  String  apmAgentPackageName ;
112128
113129    /** 
114130     * Frames originating from this module are ignored in the permission logic. 
@@ -117,25 +133,25 @@ private static Set<Module> findSystemModules() {
117133
118134    public  PolicyManager (
119135        Policy  serverPolicy ,
120-         List <Entitlement > agentEntitlements ,
136+         List <Entitlement > apmAgentEntitlements ,
121137        Map <String , Policy > pluginPolicies ,
122138        Function <Class <?>, String > pluginResolver ,
123-         String  agentsPackageName ,
139+         String  apmAgentPackageName ,
124140        Module  entitlementsModule 
125141    ) {
126142        this .serverEntitlements  = buildScopeEntitlementsMap (requireNonNull (serverPolicy ));
127-         this .agentEntitlements  = agentEntitlements ;
143+         this .apmAgentEntitlements  = apmAgentEntitlements ;
128144        this .pluginsEntitlements  = requireNonNull (pluginPolicies ).entrySet ()
129145            .stream ()
130146            .collect (toUnmodifiableMap (Map .Entry ::getKey , e  -> buildScopeEntitlementsMap (e .getValue ())));
131147        this .pluginResolver  = pluginResolver ;
132-         this .agentsPackageName  = agentsPackageName ;
148+         this .apmAgentPackageName  = apmAgentPackageName ;
133149        this .entitlementsModule  = entitlementsModule ;
134150
135151        for  (var  e  : serverEntitlements .entrySet ()) {
136-             validateEntitlementsPerModule ("server" , e .getKey (), e .getValue ());
152+             validateEntitlementsPerModule (SERVER_COMPONENT_NAME , e .getKey (), e .getValue ());
137153        }
138-         validateEntitlementsPerModule ("agent" , "unnamed" , agentEntitlements );
154+         validateEntitlementsPerModule (APM_AGENT_COMPONENT_NAME , "unnamed" , apmAgentEntitlements );
139155        for  (var  p  : pluginsEntitlements .entrySet ()) {
140156            for  (var  m  : p .getValue ().entrySet ()) {
141157                validateEntitlementsPerModule (p .getKey (), m .getKey (), m .getValue ());
@@ -147,7 +163,7 @@ private static Map<String, List<Entitlement>> buildScopeEntitlementsMap(Policy p
147163        return  policy .scopes ().stream ().collect (toUnmodifiableMap (Scope ::moduleName , Scope ::entitlements ));
148164    }
149165
150-     private  static  void  validateEntitlementsPerModule (String  sourceName , String  moduleName , List <Entitlement > entitlements ) {
166+     private  static  void  validateEntitlementsPerModule (String  componentName , String  moduleName , List <Entitlement > entitlements ) {
151167        Set <Class <? extends  Entitlement >> flagEntitlements  = new  HashSet <>();
152168        for  (var  e  : entitlements ) {
153169            if  (e  instanceof  FileEntitlement ) {
@@ -156,7 +172,7 @@ private static void validateEntitlementsPerModule(String sourceName, String modu
156172            if  (flagEntitlements .contains (e .getClass ())) {
157173                throw  new  IllegalArgumentException (
158174                    "[" 
159-                         + sourceName 
175+                         + componentName 
160176                        + "] using module [" 
161177                        + moduleName 
162178                        + "] found duplicate flag entitlements [" 
@@ -184,9 +200,10 @@ private void neverEntitled(Class<?> callerClass, Supplier<String> operationDescr
184200
185201        throw  new  NotEntitledException (
186202            Strings .format (
187-                 "Not entitled: caller [%s], module [%s], operation [%s]" ,
188-                 callerClass ,
189-                 requestingClass .getModule () == null  ? "<none>"  : requestingClass .getModule ().getName (),
203+                 "Not entitled: component [%s], module [%s], class [%s], operation [%s]" ,
204+                 getEntitlements (requestingClass ).componentName (),
205+                 requestingClass .getModule ().getName (),
206+                 requestingClass ,
190207                operationDescription .get ()
191208            )
192209        );
@@ -240,9 +257,10 @@ public void checkFileRead(Class<?> callerClass, Path path) {
240257        if  (entitlements .fileAccess ().canRead (path ) == false ) {
241258            throw  new  NotEntitledException (
242259                Strings .format (
243-                     "Not entitled: caller  [%s], module [%s], entitlement [file], operation [read], path [%s]" ,
244-                     callerClass ,
260+                     "Not entitled: component  [%s], module [%s], class  [%s], entitlement [file], operation [read], path [%s]" ,
261+                     entitlements . componentName () ,
245262                    requestingClass .getModule (),
263+                     requestingClass ,
246264                    path 
247265                )
248266            );
@@ -264,9 +282,10 @@ public void checkFileWrite(Class<?> callerClass, Path path) {
264282        if  (entitlements .fileAccess ().canWrite (path ) == false ) {
265283            throw  new  NotEntitledException (
266284                Strings .format (
267-                     "Not entitled: caller  [%s], module [%s], entitlement [file], operation [write], path [%s]" ,
268-                     callerClass ,
285+                     "Not entitled: component  [%s], module [%s], class  [%s], entitlement [file], operation [write], path [%s]" ,
286+                     entitlements . componentName () ,
269287                    requestingClass .getModule (),
288+                     requestingClass ,
270289                    path 
271290                )
272291            );
@@ -300,30 +319,33 @@ public void checkAllNetworkAccess(Class<?> callerClass) {
300319        }
301320
302321        var  classEntitlements  = getEntitlements (requestingClass );
303-         if  (classEntitlements .hasEntitlement (InboundNetworkEntitlement .class ) == false ) {
304-             throw  new  NotEntitledException (
305-                 Strings .format (
306-                     "Missing entitlement: class [%s], module [%s], entitlement [inbound_network]" ,
307-                     requestingClass ,
308-                     requestingClass .getModule ().getName ()
309-                 )
310-             );
311-         }
322+         checkFlagEntitlement (classEntitlements , InboundNetworkEntitlement .class , requestingClass );
323+         checkFlagEntitlement (classEntitlements , OutboundNetworkEntitlement .class , requestingClass );
324+     }
312325
313-         if  (classEntitlements .hasEntitlement (OutboundNetworkEntitlement .class ) == false ) {
326+     private  static  void  checkFlagEntitlement (
327+         ModuleEntitlements  classEntitlements ,
328+         Class <? extends  Entitlement > entitlementClass ,
329+         Class <?> requestingClass 
330+     ) {
331+         if  (classEntitlements .hasEntitlement (entitlementClass ) == false ) {
314332            throw  new  NotEntitledException (
315333                Strings .format (
316-                     "Missing entitlement: class [%s], module [%s], entitlement [outbound_network]" ,
334+                     "Not entitled: component [%s], module [%s], class [%s], entitlement [%s]" ,
335+                     classEntitlements .componentName (),
336+                     requestingClass .getModule ().getName (),
317337                    requestingClass ,
318-                     requestingClass . getModule (). getName ( )
338+                     PolicyParser . getEntitlementTypeName ( entitlementClass )
319339                )
320340            );
321341        }
322342        logger .debug (
323343            () -> Strings .format (
324-                 "Entitled: class [%s], module [%s], entitlements [inbound_network, outbound_network]" ,
344+                 "Entitled: component [%s], module [%s], class [%s], entitlement [%s]" ,
345+                 classEntitlements .componentName (),
346+                 requestingClass .getModule ().getName (),
325347                requestingClass ,
326-                 requestingClass . getModule (). getName ( )
348+                 PolicyParser . getEntitlementTypeName ( entitlementClass )
327349            )
328350        );
329351    }
@@ -338,19 +360,21 @@ public void checkWriteProperty(Class<?> callerClass, String property) {
338360        if  (entitlements .getEntitlements (WriteSystemPropertiesEntitlement .class ).anyMatch (e  -> e .properties ().contains (property ))) {
339361            logger .debug (
340362                () -> Strings .format (
341-                     "Entitled: class  [%s], module [%s], entitlement [write_system_properties], property [%s]" ,
342-                     requestingClass ,
363+                     "Entitled: component  [%s], module [%s], class  [%s], entitlement [write_system_properties], property [%s]" ,
364+                     entitlements . componentName () ,
343365                    requestingClass .getModule ().getName (),
366+                     requestingClass ,
344367                    property 
345368                )
346369            );
347370            return ;
348371        }
349372        throw  new  NotEntitledException (
350373            Strings .format (
351-                 "Missing entitlement: class  [%s], module [%s], entitlement [write_system_properties], property [%s]" ,
352-                 requestingClass ,
374+                 "Not entitled: component  [%s], module [%s], class  [%s], entitlement [write_system_properties], property [%s]" ,
375+                 entitlements . componentName () ,
353376                requestingClass .getModule ().getName (),
377+                 requestingClass ,
354378                property 
355379            )
356380        );
@@ -361,27 +385,7 @@ private void checkEntitlementPresent(Class<?> callerClass, Class<? extends Entit
361385        if  (isTriviallyAllowed (requestingClass )) {
362386            return ;
363387        }
364- 
365-         ModuleEntitlements  entitlements  = getEntitlements (requestingClass );
366-         if  (entitlements .hasEntitlement (entitlementClass )) {
367-             logger .debug (
368-                 () -> Strings .format (
369-                     "Entitled: class [%s], module [%s], entitlement [%s]" ,
370-                     requestingClass ,
371-                     requestingClass .getModule ().getName (),
372-                     PolicyParser .getEntitlementTypeName (entitlementClass )
373-                 )
374-             );
375-             return ;
376-         }
377-         throw  new  NotEntitledException (
378-             Strings .format (
379-                 "Missing entitlement: class [%s], module [%s], entitlement [%s]" ,
380-                 requestingClass ,
381-                 requestingClass .getModule ().getName (),
382-                 PolicyParser .getEntitlementTypeName (entitlementClass )
383-             )
384-         );
388+         checkFlagEntitlement (getEntitlements (requestingClass ), entitlementClass , requestingClass );
385389    }
386390
387391    ModuleEntitlements  getEntitlements (Class <?> requestingClass ) {
@@ -391,47 +395,44 @@ ModuleEntitlements getEntitlements(Class<?> requestingClass) {
391395    private  ModuleEntitlements  computeEntitlements (Class <?> requestingClass ) {
392396        Module  requestingModule  = requestingClass .getModule ();
393397        if  (isServerModule (requestingModule )) {
394-             return  getModuleScopeEntitlements (requestingClass ,  serverEntitlements , requestingModule .getName (), "server" );
398+             return  getModuleScopeEntitlements (serverEntitlements , requestingModule .getName (), SERVER_COMPONENT_NAME );
395399        }
396400
397401        // plugins 
398402        var  pluginName  = pluginResolver .apply (requestingClass );
399403        if  (pluginName  != null ) {
400404            var  pluginEntitlements  = pluginsEntitlements .get (pluginName );
401405            if  (pluginEntitlements  == null ) {
402-                 return  ModuleEntitlements .NONE ;
406+                 return  ModuleEntitlements .none ( pluginName ) ;
403407            } else  {
404408                final  String  scopeName ;
405409                if  (requestingModule .isNamed () == false ) {
406410                    scopeName  = ALL_UNNAMED ;
407411                } else  {
408412                    scopeName  = requestingModule .getName ();
409413                }
410-                 return  getModuleScopeEntitlements (requestingClass ,  pluginEntitlements , scopeName , pluginName );
414+                 return  getModuleScopeEntitlements (pluginEntitlements , scopeName , pluginName );
411415            }
412416        }
413417
414-         if  (requestingModule .isNamed () == false  && requestingClass .getPackageName ().startsWith (agentsPackageName )) {
415-             // agents are  the only thing running non-modular in the system classloader 
416-             return  ModuleEntitlements .from (agentEntitlements );
418+         if  (requestingModule .isNamed () == false  && requestingClass .getPackageName ().startsWith (apmAgentPackageName )) {
419+             // The APM agent is  the only thing running non-modular in the system classloader 
420+             return  ModuleEntitlements .from (APM_AGENT_COMPONENT_NAME ,  apmAgentEntitlements );
417421        }
418422
419-         logger .warn ("No applicable entitlement policy for class [{}]" , requestingClass .getName ());
420-         return  ModuleEntitlements .NONE ;
423+         return  ModuleEntitlements .none (UNKNOWN_COMPONENT_NAME );
421424    }
422425
423426    private  ModuleEntitlements  getModuleScopeEntitlements (
424-         Class <?> callerClass ,
425427        Map <String , List <Entitlement >> scopeEntitlements ,
426428        String  moduleName ,
427-         String  component 
429+         String  componentName 
428430    ) {
429431        var  entitlements  = scopeEntitlements .get (moduleName );
430432        if  (entitlements  == null ) {
431-             logger .warn ("No applicable entitlement policy for [{}], module [{}], class [{}]" , component , moduleName , callerClass );
432-             return  ModuleEntitlements .NONE ;
433+             return  ModuleEntitlements .none (componentName );
433434        }
434-         return  ModuleEntitlements .from (entitlements );
435+         return  ModuleEntitlements .from (componentName ,  entitlements );
435436    }
436437
437438    private  static  boolean  isServerModule (Module  requestingModule ) {
0 commit comments