---
schema_version: "1"
id: afb0cc3c4cf782d600f65f36243fd8bb7600a9ab8d8c3adb55cf47f352db0ecb
title: Custom Policy Development Reference
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/mule-gateway/policies-custom-mule-4-reference.md
canonical_url: https://docs.mulesoft.com/mule-gateway/policies-custom-mule-4-reference
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 821dfd2cf9e18d0c470767dd263648bdeed0393f91fe83fc418bca562ad1030f
description: MuleSoft Documentation Site
latest: true
---
---
product: Mule Gateway
---

# Custom Policy Development Reference

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

The Mule 4 engine provides powerful capabilities for building custom policies through its
architecture and XML schema language.

We use Maven to build and deploy Mule 4 policies. Policies consist of two files:

1.  A deployable JAR file that contains the policy implementation.

2.  A YAML Configuration File, where the policy parameters and metadata are defined.

To package a policy in Maven, the development project must be composed of the following files

- An XML template

  It contains the implementation of the policy using Mule’s XML schema language.

- A YAML file

  It defines the configurable parameters of the policy. Anypoint API Manager uses this file to
  render the UI to display inputs for the policy.

- The template’s `pom.xml` file

  It defines policy dependencies. The packaging type needs to be `mule-policy`. The `pom.xml` file
  may define any other Maven plugin that helps to manage the development lifecycle of the Maven
  project.

- Resources

  Optional files that the policy depends on, such as certificates and configuration properties
  files.

- The mule-artifact.json descriptor

  > [!NOTE] Policies cannot export resources nor packages such as Java classes.

## Basic XML structure

Below is an example of the basic structure of a policy configuration:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:http-policy="http://www.mulesoft.org/schema/mule/http-policy">

  <http-policy:proxy name="policy-template">  (1)
     <http-policy:source>  (2)
          …  (3)
         <http-policy:execute-next/> (4)
          …  (5)
     </http-policy:source>
  </http-policy:proxy>
</mule>
```

<table><tbody><tr><td><i data-value="1"></i><b>1</b></td><td>The definition of a policy starts with the <code>http-policy:proxy</code> element with a name argument. The <code>http-policy:proxy</code> element must contain <code>http-policy:source</code> or a <code>http-policy:operation</code> element. In this example, <code>http-policy:source</code> is used.</td></tr><tr><td><i data-value="2"></i><b>2</b></td><td>The <code>http-policy:source</code> block contains the actual instructions to execute, relative to the Mule flow the policy is configured to handle. The <code>http-policy:source</code> block can inject instructions before an HTTP Listener event fires at the start of a flow, and inject instructions after the flow completes.</td></tr><tr><td><i data-value="3"></i><b>3</b></td><td>Any Mule Event operation that is defined before the <code>execute-next</code> element will be executed before the start of a flow with an HTTP Listener.</td></tr><tr><td><i data-value="4"></i><b>4</b></td><td>The <code>http-policy:execute-next</code> element is required to continue the Mule Event processing. The <code>http-policy:execute-next</code> element can trigger other policies or the application flow. Any policy can stop the Mule Event processing chain by not executing <code>http-policy:execute-next</code>.</td></tr><tr><td><i data-value="5"></i><b>5</b></td><td>Mule Event operations defined after the <code>http-policy:execute-next</code> element will be executed after the flow completes. These Mule Event processors will be able to process the Mule Event returned from the flow.</td></tr></tbody></table>

### Understanding execution order

Consider the case where a Mule application contains two policies, A and B.

Policy A has order 1 and Policy B has order 2.

Policy A is defined by the following configuration:

```xml
  <http-policy:proxy name="policy-A">
     <http-policy:source>
          <A1 />
         <http-policy:execute-next/>
          <A2 />
     </http-policy:source>
  </http-policy:proxy>
```

And policy B config is:

```xml
  <http-policy:proxy name="policy-B">
     <http-policy:source>
          <B1 />
         <http-policy:execute-next/>
          <B2 />
     </http-policy:source>
  </http-policy:proxy>
```

A flow is defined as:

```xml
  <flow name="flow">
     <http:listener />
     <F1/>
  </flow>
```

When an HTTP Request arrives at the Mule application’s endpoint, the execution order follows the
diagram below:

<A1> → <B1> → <F1> → <B2> → <A2>

The policy with the lower order executes first. The flow will always execute in the middle of the
policy operations.

With this model, the Mule Event processing chain can be controlled with the presence or absence of
the `http-policy:execute-next` element.

For example, by placing the `http-policy:execute-next` element inside a `choice` element, the next
Mule Event execution can continue or stop, depending on the choice condition.

In the example below, the flow will only execute when the incoming request has a header named
`myHeader` and its value is `someValue`. A message is logged if the incoming request does not
satisfy the constraint.

```xml
  <http-policy:proxy name="policy">
     <http-policy:source>
        <choice>
           <when expression="#[attributes.headers['myHeader'] == 'someValue']" >
              <http-policy:execute-next/>
           </when>
           <otherwise>
              <logger message="Avoid Flow execution" />
           </otherwise>
        </choice>
      </http-policy:source>
  </http-policy:proxy>
```

## Using extensions

Policies, just like Mule applications, can make use of Mule extensions or plugins to extend the Mule
Core capabilities.

For example, a policy is required to add additional headers to the HTTP Response from a flow’s HTTP
Listener.  
The first step is to add a Maven dependency that can modify an HTTP Request object.

The `mule-http-policy-transform-extension` Mule plugin can modify HTTP Requests.

```xml
   <dependencies>
       <dependency>
           <groupId>com.mulesoft.anypoint</groupId>
           <artifactId>mule-http-policy-transform-extension</artifactId>
           <version>1.0.0</version>
           <classifier>mule-plugin</classifier>
       </dependency>
   </dependencies>
```

These examples are developed using Mule extension v1.0.0. Using a different version of the extension
might cause the examples to not work as expected. To update your Mule extension version, see
[HTTP Policy Transform Extension](https://docs.mulesoft.com/mule-gateway/policies-custom-http-transform).

Next, the XML `http-transform` namespace must be added to expose the operations in the above
dependency.

```xml
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:http-policy="http://www.mulesoft.org/schema/mule/http-policy"
     xmlns:http-transform="http://www.mulesoft.org/schema/mule/http-policy-transform"
     xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
              http://www.mulesoft.org/schema/mule/http-policy http://www.mulesoft.org/schema/mule/http-policy/current/mule-http-policy.xsd
              http://www.mulesoft.org/schema/mule/http-policy-transform http://www.mulesoft.org/schema/mule/http-policy-transform/current/mule-http-policy-transform.xsd">

   <http-policy:proxy name="policy">
       <http-policy:source>
           <http-policy:execute-next/>

           <http-transform:add-headers outputType="response">
               <http-transform:headers>#[{'policyHeader': 'policyHeaderValue'}]</http-transform:headers>
           </http-transform:add-headers>
       </http-policy:source>
   </http-policy:proxy>
</mule>
```

If a policy needs to use custom code, the policy can either:

1.  Import a custom Mule plugin programmed with the Java or XML SDK Extension

2.  Use the `<scripting:execute>` element to add in custom scripts

The recommended method is to use the SDK Extensions.

> [!CAUTION] Custom policies can’t use connectors that export resources or packages such as Java
> classes. For example, custom policies can’t use the Java or Spring connectors.

## Outbound policies

Policies can be applied to outbound HTTP Requests within a flow as well. This capability enables
policies to inject additional headers and other information into outbound HTTP traffic through an
HTTP Requester defined in a flow.

Below is an example of a policy that contains source and operation blocks:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:http-policy="http://www.mulesoft.org/schema/mule/http-policy">

  <http-policy:proxy name="policy-template">  (1)
      <http-policy:source>
     …
      <http-policy:execute-next/>
     …
      </http-policy:operation> (2)
  </http-policy:proxy>
</mule>
```

<table><tbody><tr><td><i data-value="1"></i><b>1</b></td><td>One <code>http-policy:proxy</code> element is used for both types of policy blocks. Both source and operation blocks may be present. When both blocks are present, each block can share variables to keep state throughout the policy execution.</td></tr><tr><td><i data-value="2"></i><b>2</b></td><td>This policy block contains code to be executed after the flow’s HTTP Requester returns an HTTP response. If the flow does not contain an HTTP Requester element, then this block is never executed.</td></tr></tbody></table>

In general, the `http-policy:operation` block allows a policy to inject code before Mule execution
reaches an HTTP Requester and after an HTTP Requester returns an HTTP response. The operation block
can contain an `http-policy:execute-next` element to control operations before and after an HTTP
Request in a flow.

**Execution order example**

There are two policies, A and B.

Policy A has order 1 and Policy B has order 2.

Policy A is defined by the following configuration:

```xml
  <http-policy:proxy name="policy-A">
     <http-policy:source>
        <A1 />
        <http-policy:execute-next/>
        <A2 />
     </http-policy:source>

     <http-policy:operation>
        <A3 />
        <http-policy:execute-next/>
        <A4 />
     </http-policy:operation>
  </http-policy:proxy>
```

And policy B config is:

```xml
  <http-policy:proxy name="policy-B">
     <http-policy:source>
        <B1 />
        <http-policy:execute-next/>
        <B2 />
     </http-policy:source>

     <http-policy:operation>
        <B3 />
        <http-policy:execute-next/>
        <B4 />
     </http-policy:operation>
  </http-policy:proxy>
```

A flow is defined as:

```xml
  <flow name="flow">
      <http:listener />
      <F1/>
      <http:request />
      <F2/>
  </flow>
```

When Mule runtime receives an HTTP Request, the execution order is as shown in this diagram:

<A1> → <B1> → <F1> → <A3> → <B3> → <http:requester> → <B4> → <A4> → <F2> → <B2> → <A2>

Operation policies are only injected around the `http:request` operation.

## Error Handling

Mule 4 policies can handle errors thrown by

1.  The policy

2.  A flow within the Mule application

3.  Other policies

Error handling can be accomplished using Mule 4’s `try` and `error-handler` elements.

Once an error is caught by an `error-handler`, the error is either, propagated up the Mule Event
processing chain, or handled, where normal Mule event process execution continues.

For example, consider the following policy and flow:

```xml
  <http-policy:proxy name="policy">
     <http-policy:source>
        <try>
           <P1 />
           <http-policy:execute-next/>
           <P2 />
           <error-handler>
              <on-error-continue>
                 <PEH />
              </on-error-continue>
           </error-handler>
        </try>
      </http-policy:source>
  </http-policy:proxy>
```

```xml
  <flow name="flow">
     <http:listener />
     <F1 />
     <F2 />
     <error-handler>
        <on-error-continue>
           <FEH />
        </on-error-continue>
     </error-handler>
  </flow>
```

### Scenario 1

Assume `<F1>` raises an error. The execution order follows the diagram below:

<P1> → <F1> → <FEH> → <P2>

`<F2>` is not executed, and processing continues into the flow’s error-handler.  
Since the flow’s error-handler is configured not to propagate errors, `<FEH>` will return to the
policy and `<P2>` executes instead of the policy’s `error-handler`.

### Scenario 2

Assume `<P1>` raises an error. The execution order follows the diagram below:

<P1> → <PEH>

From the example above, the flow never executes.

### Scenario 3

Assume now that the flow’s error handler propagates errors.

```xml
  <error-handler>
     <on-error-propagate>
        <FEH />
     </on-error-propagate>
  </error-handler>
```

Assume `<F1>` raises an error. The execution order follows the diagram below:

<P1> → <F1> → <FEH> → <PEH>

The error gets propagated back to the policy, and the policy’s error handler continues handling the
error.

In summary, error handlers provide an alternative method to conditionally execute a flow within a
policy.

## Classloading isolation

### Between policies

Policies contain the same classloading isolation architecture seen in Mule 4 applications: any
resource or library that a policy defines is not visible to other policies.

### Between a Policy and an Application

Classloading between policies and Mule 4 applications is not completely isolated. This scenario is
similar to classloading isolation between applications and domains:

Any plugin, library, or resource visible to the application is also visible to any policy applied to
that application.

However, any plugin, library, or resource visible to a policy is **not** visible to the application
applied.

### Dependency resolution

If a policy and an application use different versions of the same dependency, the application’s
dependency version will be used by the policy.

You can read more on classloading isolation in the
[Classloading Isolation](https://docs.mulesoft.com/mule-runtime/latest/about-classloading-isolation) topic.

## Variables and Event Scope

A policy can define any number of variables. Variables within a policy scope can be shared between
policy blocks. For example, a variable `maxCount` defined in a `http-policy:source` block is
available in a subsequent `http-policy:operation` block.

However, any variables defined in a policy are **not** available to other policies and to the
application.  
Furthermore, variables defined by the application are not available to any policy.

## Mule message propagation in source policies

Policies can make changes to the Mule message, but the changes may not get propagated, depending on
where the Mule message changes are made relative to the `http-policy:execute-next` element.

For source policies, any modification to a Mule Message made after the `http-policy:execute-next`
element, will continue propagation throughout the rest of the Mule event processing chain.

The below policy and flow illustrates this concept:

```xml
<http-policy:proxy name="policy">
  <http-policy:source>
     <http-policy:execute-next/>
     <set-payload value="Policy Message" />
   </http-policy:source>
</http-policy:proxy>
```

```xml
<flow name="flow">
  <http:listener />
  <set-payload value="Flow Message" />
</flow>
```

The final response back to the client will be an HTTP Response that contains "Policy Message" as the
body.

However, modifications made before the `execute-next` element, are not propagated to the next policy
or application by default.

Consider the below policy and flow:

```xml
<http-policy:proxy name="policy">
  <http-policy:source>
     <set-payload value="Policy Message" />
     <http-policy:execute-next/>
  </http-policy:source>
</http-policy:proxy>
```

```xml
<flow name="flow">
  <http:listener />
  <logger message=#[payload] />
</flow>
```

The final response back to the client will be an HTTP Response that contains an empty body.
Furthermore, the logger in the flow will log an empty payload.

### Propagating the Mule message

Within the `http-policy:source` tag, set the attribute `propagateMessageTransformations` to `true`
to enable propagation.

```xml
<http-policy:proxy name="policy">
  <http-policy:source propagateMessageTransformations="true">
     <set-payload value="Policy Message" />
     <http-policy:execute-next/>
  </http-policy:source>
</http-policy:proxy>
```

```xml
<flow name="flow">
  <http:listener />
  <logger message=#[payload] />
</flow>
```

The final response back to the client will be an HTTP Response that contains "Policy Message" as the
body. The logger within the flow will log "Policy Message."

This design prevents unintentional modifications that can affect the application.

## Mule message propagation in operation policies

Mule message propagation is similar to source policies but in the opposite direction. In operation
policies, modifications made before the `execute-next` element are always propagated. Modifications
made after the `execute-next` element, are not propagated by default.

Propagation can be enabled using the same attribute `propagateMessageTransformations` in the
operation policy definition:

```xml
<http-policy:proxy name="scope-payload">
   <http-policy:operation propagateMessageTransformations="true">
       …
       <http-policy:execute-next/>
       …
   </http-policy:operation>
</http-policy:proxy>
```

In summary, variables cannot be used to share information from a policy to other policies or Mule
applications.

However, Mule messages can be used to share information from a policy to other policies or Mule
applications. Dependent on where the Mule message is set within a policy block, the attribute
`propagateMessageTransformations` may need to be set to true to enable Mule message propagation.

## Authentication (Security Context)

User authentication can be exposed through the Authentication object within the Security context
object.

If a policy sets the Authentication object, it will be available to other policies and to the
application.  
The Authentication object can be accessed using DataWeave:

#\[authentication.principal\] #\[authentication.password\]
#\[authentication.properties.someProperty\]

The only method to set the Authentication object is through a dependency using the SDK Mule
extension.  
Refer to the [Authentication Handler](https://docs.mulesoft.com/mule-sdk/latest/authentication-handler) article to learn
how to set the authentication object.

Mule 4 Provided Policies use this exact method to propagate client information.

## YAML Configuration File

Mule 4’s policies use YAML files to store metadata and user parameters. This flexible design allows
a policy to work across multiple APIs that require different user parameters and configurations.

For example, the Rate Limit Policy allows for different configurations based on user parameters: a
user may want to allow up to 100 requests per minute on one API, and allow 5000 per minute on a
different API.

To allow user parameters, policy developers define user input in the YAML Configuration file. The
file is then used by API Manager to render the UI for user input.

**Example of a Client ID enforcement YAML file**

```yaml
id: openam-access-token-enforcement  (1)
name: OpenAM access token enforcement  (2)
supportedPoliciesVersions: '>=v4'  (3)
supportedJavaVersions: ["8", "11", "17"]  (4)
description: Enforces access tokens by OpenAM.  (5)
category: Security  (6)
violationCategory: authentication  (7)
type: system  (8)
resourceLevelSupported: true  (9)
standalone: true  (10)
identityManagement:  (11)
type: OpenAM
- OAuth 2.0 protected
configuration:  (12)
- propertyName: scopes
  name: Scopes
  description: A space-separated list of supported scopes
  type: string
  optional: true
  sensitive: false
  allowMultiple: false
- propertyName: exposeHeaders
  name: Expose Headers
  description: In a proxy scenario, defines if headers should be exposed in the request to the backend. The headers that may
      be sent are the user properties returned by the federation server when validating the access token with a 'X-AGW-' prefix.
  type: boolean
  optional: true
  defaultValue: true
  allowMultiple: false
```

<table><tbody><tr><td><i data-value="1"></i><b>1</b></td><td>Unique ID within your organization of the policy. Required</td></tr><tr><td><i data-value="2"></i><b>2</b></td><td>User friendly name that is used for displaying the policy name in API Manager’s UI. Required</td></tr><tr><td><i data-value="3"></i><b>3</b></td><td>Deprecated property. Value should be set to ‘&gt;=v1’ for now. Required</td></tr><tr><td><i data-value="4"></i><b>4</b></td><td>Java versions supported by the policy. Required for Java 17 runtime support. Without this field, the policy won’t appear in API Manager for Java 17 runtimes. Optional</td></tr><tr><td><i data-value="5"></i><b>5</b></td><td>Description of what the policy does. Also used in API Manager’s UI. Required</td></tr><tr><td><i data-value="6"></i><b>6</b></td><td>Category to which the policy belongs. Used to group and filter policies in API Manager’s UI, any String value is valid. Required</td></tr><tr><td><i data-value="7"></i><b>7</b></td><td>Value used by Edge to show metrics about different types of policy violations. Required</td></tr><tr><td><i data-value="8"></i><b>8</b></td><td>Deprecated property. Value should be set to ‘system’. Required</td></tr><tr><td><i data-value="9"></i><b>9</b></td><td>Whether resource level pointcuts should be enabled when applying the policy. Required</td></tr><tr><td><i data-value="10"></i><b>10</b></td><td>Deprecated property. Value should be set to ‘true’. Required</td></tr><tr><td><i data-value="11"></i><b>11</b></td><td>Whether policy requires information about an identity management that’s configured for the API’s Organization. Optional</td></tr><tr><td><i data-value="12"></i><b>12</b></td><td>Where the policy parameters are defined. Every parameter listed here will be rendered as an expected user input in API Manager’s UI. It expects an array of values. Required</td></tr></tbody></table>

Below is the syntax for defining the above policy’s parameters:

```yaml
propertyName: scopes (1)
name: Scopes (2)
description: A space-separated list of supported scopes (3)
type: string (4)
defaultValue: some String (5)
optional: true (6)
sensitive: false (7)
allowMultiple: false (8)
```

<table><tbody><tr><td><i data-value="1"></i><b>1</b></td><td>Internal name of the parameter. Must be unique within the policy.</td></tr><tr><td><i data-value="2"></i><b>2</b></td><td>User friendly name of the parameter. Used for displaying in API Manager’s UI.</td></tr><tr><td><i data-value="3"></i><b>3</b></td><td>Description of the parameter. Also, used for displaying in API Manager’s UI.</td></tr><tr><td><i data-value="4"></i><b>4</b></td><td>Type of the parameter.</td></tr><tr><td><i data-value="5"></i><b>5</b></td><td>Default value for the parameter.</td></tr><tr><td><i data-value="6"></i><b>6</b></td><td>Whether is mandatory for the user to enter this value or not.</td></tr><tr><td><i data-value="7"></i><b>7</b></td><td>Whether this property should be masked when entering in API Manager’s UI.</td></tr><tr><td><i data-value="8"></i><b>8</b></td><td>Whether multiple values should be allowed for this parameter.</td></tr></tbody></table>

### Parameter types

Depending of the type of the parameter, the UI will render a different type of input such as:

- text boxes

- radio buttons

- checkboxes

Some rendered elements require additional configurations. The list of elements that require
additional configurations are:

- **String**: Any string expected.

- **Expression**: A DataWeave expression starting with #\[ and finished with \] is expected.

- **Boolean**: true or false.

- **Int**: A number is expected. This type requires additional properties:

  ```yaml
  minimumValue: -1 (1)
  maximumValue: 2147483647 (2)
  ```

  <table><tbody><tr><td><i data-value="1"></i><b>1</b></td><td>Minimum value allowed for the parameter.</td></tr><tr><td><i data-value="2"></i><b>2</b></td><td>Maximum value allowed for the parameter.</td></tr></tbody></table>

- **Radio**: One value of a group of options. This type requires additional properties:

  ```yaml
  options: (1)
  - name: HTTP Basic Authentication Header
    value: httpBasicAuthenticationHeader
  - name: Custom Expression
    value: customExpression
  ```

  <table><tbody><tr><td><i data-value="1"></i><b>1</b></td><td>List of options for the user to choose. Each option has a name for displaying in the UI and an internal value used in the policy.</td></tr></tbody></table>

- **Keyvalues**: Collection of Key-Value pairs.

## HandleBars

Policies support Handlebars, a templating engine for resolving the configurable parameters of the
policy and implementing semantic logic, such as conditionals. This is the preferred method of using
user inputs in the policies.

Each policy parameter defined in a YAML Configuration file will be available as a HandleBars
variable for resolving the final policy configuration.

> [!NOTE] Handlebars is an extension of Mustache, which was used in earlier versions of Mule
> policies.

Depending on the parameter type defined in the YAML, the variable will be of a different HandleBars
type.

String, Expression, Radio, Int, and Boolean are primitive types in HandleBars.

The primitive types can be referenced from the policy template using curly brackets:
`{{{myproperty}}}`

Keyvalues are complex types in HandleBars. Complex types have inner properties, and those can be
referenced as follows:

{{{keyvalue.key}}} {{{keyvalue.value}}}

There are some properties that are available to use in policies without being defined in the YAML
Configuration file:

- **policyId** id of the policy, useful for logging or naming a policy

- **isWsdlEndpoint** indicates whether the API where the policy is being applied is a WSDL API.

When an Identity Management is defined for the organization where the API is being applied, then the
following properties are also available:

**identityManagementTokenUrl** introspection endpoint of the identity management.
**identityManagementClientId** client Id for authenticating to the introspection endpoint.
**identityManagementClientSecret** client secret for authenticating to the introspection endpoint.

## Pointcuts

In earlier versions, the pointcut element was required to configure a custom policy. Pointcuts
specified the API that the policy operates.  
In Mule 4, there is no need to configure the pointcut element. Information about the API on which
the custom policy operates is provided by API Manager when a policy is applied.

See offline policies for configuration guidelines when a policy is not applied online.

## Advanced topics

- [Reviewing HTTP Policy Transform Extension](https://docs.mulesoft.com/mule-gateway/policies-custom-http-transform)

- [Removing HTTP Caching Custom Policy example](https://docs.mulesoft.com/mule-gateway/policies-custom-mule-4-caching)

## See also

- [Packaging a Custom Policy](https://docs.mulesoft.com/mule-gateway/policies-custom-package)

- [Uploading a Custom Policy to Exchange](https://docs.mulesoft.com/mule-gateway/policies-custom-upload-to-exchange)
