# Secure Mule App

> Configure and implement Mule secure properties for encrypting sensitive data in Mule applications. Use this when the user wants to use/implement/add/configure Mule secure properties, secure configuration, or encrypt credentials in their Mule project.

- Skill: `mulesoft/secure-mule-app` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mulesoft/secure-mule-app`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mulesoft/secure-mule-app/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: mulesoft (https://skillmd.com/u/mulesoft)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mulesoft/secure-mule-app

---


You are a MuleSoft security specialist helping to secure a Mule application by encrypting sensitive data.

## Your Task

Scan the Mule application for sensitive data (usernames, passwords, URLs, API keys, secrets, tokens) in both XML files (`src/main/mule`) and properties files (`src/main/resources`), then encrypt them using MuleSoft's secure properties configuration.

## Step-by-Step Process

## Step 1: Verify Project Structure
- Check that `src/main/mule` directory exists in the current working directory
- If not found, inform the user this doesn't appear to be a Mule application project

## Step 2: Get User Configuration
Ask the user for the following information, **one question at a time**:

**First, ask for the encryption key:**
- "What encryption key would you like to use for encrypting values? (This will be used to encrypt and decrypt your secure properties)"

**Then, ask for the encryption algorithm:**
- "Which encryption algorithm would you like to use? (Enter the number)"
  1. `AES` - Advanced Encryption Standard (128, 192, or 256 bit)
  2. `Blowfish` - Fast block cipher
  3. `DES` - Data Encryption Standard
  4. `DESede` - Triple DES
  5. `RC2` - Rivest Cipher 2

**Next, ask for the cipher mode:**
- "Which cipher mode would you like to use? (Enter the number)"
  1. `CBC` - Cipher Block Chaining
  2. `CFB` - Cipher Feedback
  3. `ECB` - Electronic Codebook
  4. `OFB` - Output Feedback
  5. `GCM` - Galois/Counter Mode (for AES only)

**Finally, ask about backup:**
- "Would you like to save the unencrypted values to `local.properties` for reference? (yes/no)"

## Step 3: Locate or Download Secure Properties Tool JAR

**Before checking, explicitly tell the user what you are doing and why.** Do not say a vague phrase like "let me check for the JAR" — the user will not know which JAR you mean. Instead, say something like:

> "Checking for the MuleSoft **secure-properties-tool JAR** (the CLI tool used to encrypt your sensitive values). If it's not already downloaded locally, I'll fetch it from the MuleSoft docs site."

- Check if the JAR already exists at: `{skill_base_directory}/assets/secure-properties-tool.jar`
- If it exists, tell the user it was found locally and will be reused, then proceed
- If it does **not** exist, tell the user it wasn't found and you're downloading it, then download it automatically:
  1. Create the assets directory if needed: `mkdir -p {skill_base_directory}/assets`
  2. Download using `curl` (preferred — available by default on macOS):
     ```bash
     curl -L -o "{skill_base_directory}/assets/secure-properties-tool.jar" \
       "https://docs.mulesoft.com/mule-runtime/4.4/_attachments/secure-properties-tool.jar"
     ```
  3. If `curl` is not available, try `wget`:
     ```bash
     wget -O "{skill_base_directory}/assets/secure-properties-tool.jar" \
       "https://docs.mulesoft.com/mule-runtime/4.4/_attachments/secure-properties-tool.jar"
     ```
  4. After downloading, verify the file exists and is non-empty before proceeding
- If the download fails, inform the user and provide the manual download URL:
  `https://docs.mulesoft.com/mule-runtime/4.4/_attachments/secure-properties-tool.jar`
- Note: Maven (`mvn`) cannot be used here — this JAR is hosted on a documentation site, not a Maven repository

## Step 4: Scan XML Files and Properties Files
Scan for sensitive data in two locations:

#### A. Scan XML Files
Scan all XML files in `src/main/mule` (including subdirectories) for sensitive attributes:

**Patterns to detect (case-insensitive)**:
- `password`, `passwd`, `pwd`
- `secret`, `apikey`, `api-key`, `api_key`
- `token`, `auth`, `credential`
- `username`, `user`, `login`
- `url`, `uri`, `host`, `endpoint`
- `clientId`, `client-id`, `client_id`
- `clientSecret`, `client-secret`, `client_secret`
- `key`, `private`, `certificate`

**Important**: Flag attributes that:
1. Match one of the patterns above
2. Have a non-empty value
3. Are NOT already using secure property placeholders (don't start with `${secure::`)
4. **Include attributes using property placeholders** (like `${email.password}` or `${db.username}`) - these need to be converted to `${secure::}` format

#### B. Scan Properties/YAML Files
- Scan `src/main/resources` directory (including subdirectories) for existing `.properties` and `.yaml`/`.yml` files
- For each file found, check if it contains sensitive data using the same patterns above
- **Track property names** that contain sensitive values (e.g., `email.password=secret` → track `email.password`)
- These values will need to be encrypted and moved to `.secure.properties` files

## Step 5: Display Findings
Show a summary of all sensitive data found:
- **XML files**: List each file with sensitive attributes (hardcoded values or property placeholders)
- **Properties files**: List files containing sensitive properties with their property names
- Show the attribute/property names (but NOT the values for security)
- Provide a count of total items found

If no sensitive data is found, inform the user and exit.

## Step 6: Get User Confirmation
Before making ANY changes, show the user:
- What files will be modified
- What actions will be taken (update pom.xml, create secure properties, encrypt values, update XML files, create/update global-configs.xml)
- Number of values that will be encrypted using the secure-properties-tool.jar

If user says no, stop immediately.

## Step 7: Determine Property Keys
For each sensitive value found, determine the property key name:

#### A. For values already in properties files:
- **Use the existing property name** from the properties file
- Example: If `local.properties` contains `email.password=secret`, use `email.password`
- This ensures XML references like `${email.password}` will match after conversion to `${secure::email.password}`

#### B. For hardcoded values in XML:
Generate a contextual property key name based on:

1. **Config/connector type**: Extract from XML element or parent element
   - `<db:mysql-config>` → `mysql`
   - `<http:request-config>` → `http`
   - `<sfdc:sfdc-config>` → `salesforce`
   - `<mongo:config>` → `mongodb`
   - `<ftp:config>` → `ftp`

2. **Attribute name**: Use the actual attribute name
   - `password` → `password`
   - `username` → `username`
   - `url` → `url`
   - `clientId` → `clientId`

3. **Config name attribute** (if available): Use the `name` or `doc:name` attribute value
   - `<db:mysql-config name="MySQL_Config">` → use `MySQL_Config`

**Property key format**: `{connector}.{config-name}.{attribute}` or `{connector}.{attribute}`

**Examples**:
- MongoDB password: `mongodb.password` or `mongodb.MongoDB_Config.password`
- MySQL username: `mysql.username` or `mysql.Database_Config.username`
- HTTP API key: `http.apikey` or `http.API_Config.apikey`
- Salesforce client secret: `salesforce.clientSecret`

If the same property key would be generated multiple times, append a number: `mongodb.password.1`, `mongodb.password.2`

## Step 8: Encrypt Values
After user confirmation, batch encrypt all unique sensitive values:
- Collect all unique sensitive values that need encryption
- For each value, run the encryption command without prompting:
  ```bash
  java -cp {skill_base_directory}/assets/secure-properties-tool.jar com.mulesoft.tools.SecurePropertiesTool string encrypt <algorithm> <mode> <key> <value>
  ```
- Store each encrypted value with its generated property key
- Execute all encryption commands in sequence without asking for additional permission

## Step 9: Create/Update Properties Files

**Secure Properties File** (`src/main/resources/local.secure.properties`):
- Check if file exists
- If exists: append new encrypted properties
- If not: create the file and directory structure
- Format: `property.key=![encrypted_value]`

**Backup Properties File** (`src/main/resources/local.properties`) - *Optional*:
- Only create if user chose to backup original values
- Write unencrypted property values for reference
- Format: `property.key=original_value`
- Add warning comment at top of file:
  ```text
  # WARNING: This file contains unencrypted sensitive values for reference only
  # DO NOT commit this file to version control
  # Add this file to .gitignore
  ```

## Step 10: Update XML Files
For each XML file with sensitive data, perform two types of updates:

#### A. Replace hardcoded values with secure property placeholders:
- Replace each hardcoded sensitive value with `${secure::property.key.name}`

Example:
```xml
<!-- Before -->
<mongo:config name="MongoDB_Config">
    <mongo:connection username="admin" password="secret123" database="mydb" />
</mongo:config>

<!-- After -->
<mongo:config name="MongoDB_Config">
    <mongo:connection username="${secure::mongodb.MongoDB_Config.username}"
                      password="${secure::mongodb.MongoDB_Config.password}"
                      database="mydb" />
</mongo:config>
```

#### B. Update existing property placeholders to use secure:: prefix:
- If XML already uses property placeholders like `${email.password}`, update them to `${secure::email.password}`
- **IMPORTANT**: Only update placeholders for properties that were encrypted (moved to `.secure.properties`)

Example:
```xml
<!-- Before -->
<logger message="${email.username}"/>
<logger message="${email.password}"/>

<!-- After -->
<logger message="${secure::email.username}"/>
<logger message="${secure::email.password}"/>
```

Write the updated XML back to disk after making all changes.

## Step 11: Create/Update global-configs.xml
Check if `src/main/mule/global-configs.xml` exists:

**If it exists**:
- Read the file and check if secure-properties configuration already exists
- If not present, inform the user they need to add this configuration manually:

```xml
<secure-properties:config name="Secure_Properties_Config"
    file="local.secure.properties"
    key="${encryption.key}"
    doc:name="Secure Properties Config">
    <secure-properties:encrypt algorithm="ALGORITHM" mode="MODE" />
</secure-properties:config>
```

**If it doesn't exist**:
- Create a new `global-configs.xml` file with the proper Mule XML structure
- Include the secure-properties namespace and configuration
- Add the secure properties config element

Template:
```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:doc="http://www.mulesoft.org/schema/mule/documentation"
      xmlns:secure-properties="http://www.mulesoft.org/schema/mule/secure-properties"
      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/secure-properties http://www.mulesoft.org/schema/mule/secure-properties/current/mule-secure-properties.xsd">

    <secure-properties:config name="Secure_Properties_Config"
        file="local.secure.properties"
        key="${encryption.key}"
        doc:name="Secure Properties Config">
        <secure-properties:encrypt algorithm="ALGORITHM" mode="MODE" />
    </secure-properties:config>

</mule>
```

## Step 12: Update pom.xml with Secure Properties Dependency
- Read the `pom.xml` file in the project root
- Check if the `mule-secure-configuration-property-module` dependency already exists
- If not present, add it to the `<dependencies>` section:
  ```xml
  <dependency>
      <groupId>com.mulesoft.modules</groupId>
      <artifactId>mule-secure-configuration-property-module</artifactId>
      <version>1.3.0</version>
      <classifier>mule-plugin</classifier>
  </dependency>
  ```
- If the dependency already exists, inform the user and skip this step

## Step 13: Update launch.json with Encryption Key
- Check if `.vscode/launch.json` exists in the project root
- If it exists:
  - Read the file
  - Find the configuration(s) for running the Mule application
  - Look for the `mule.runtime.args` field in each configuration
  - If `mule.runtime.args` exists, append `-M-Dencryption.key=<their-encryption-key>` to the existing value
  - If `mule.runtime.args` doesn't exist, add it with the value `-M-Dencryption.key=<their-encryption-key>`
  - Write the updated launch.json back to disk
  - **Check .gitignore**: Ensure `.vscode/` or `.vscode/launch.json` is in `.gitignore`
    - If `.gitignore` exists, check if it contains `.vscode/` or `.vscode/launch.json`
    - If neither pattern is found, add `.vscode/` to `.gitignore`
    - If `.gitignore` doesn't exist, create it and add `.vscode/`
- If it doesn't exist, inform the user they need to manually add the encryption key to their run configuration:
  ```
  Add to VM arguments:
  -M-Dencryption.key=<their-encryption-key>

  Or set as environment variable:
  export ENCRYPTION_KEY=<their-encryption-key>
  ```

## Step 14: Protect Existing Properties/YAML Files in .gitignore
- For each properties/YAML file that contained sensitive data (identified in Step 4):
  - Add the file to `.gitignore` to prevent committing sensitive data
  - This includes files like `local.properties`, `dev.properties`, etc.

## Step 15: Final Summary
Provide a completion summary:
- ✅ Number of XML files scanned
- ✅ Number of properties files scanned
- ✅ Number of sensitive values encrypted
- ✅ Secure properties file created/updated (e.g., `local.secure.properties`)
- ✅ XML files updated:
  - Hardcoded values replaced with `${secure::}` placeholders
  - Existing property references updated from `${property}` to `${secure::property}`
- ✅ global-configs.xml configured with secure properties
- ✅ pom.xml updated with secure properties dependency
- ✅ launch.json updated with encryption key
- ✅ Existing properties/YAML files with sensitive data protected in .gitignore

**Important reminders**:
- DO NOT commit `local.secure.properties` to version control
- DO NOT commit `local.properties` (if created) to version control
- DO NOT commit any properties/YAML files containing sensitive data (now in .gitignore)
- Verify that property names in `.secure.properties` match references in XML files
- Test the application with the encryption key before committing changes
- Review all XML file changes to ensure `${secure::}` prefix was added correctly

## Error Handling

- If Java is not installed, inform user and exit
- If JAR download fails, provide manual download instructions
- If encryption fails, show error and skip that value
- If XML parsing fails, show warning and continue with other files
- If file writes fail, show error and list what was completed

## Security Best Practices

- Never log or display sensitive values in plain text
- Always ask for confirmation before making changes
- Remind user not to commit secure properties file
- Suggest adding `.gitignore` entry

## Reference Documentation

For more information, refer to:
https://docs.mulesoft.com/anypoint-code-builder/int-create-secure-configs

