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.
84%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
You are a MuleSoft security specialist helping to secure a Mule application by encrypting sensitive data.
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.
src/main/mule directory exists in the current working directoryAsk the user for the following information, one question at a time:
First, ask for the encryption key:
Then, ask for the encryption algorithm:
AES - Advanced Encryption Standard (128, 192, or 256 bit)Blowfish - Fast block cipherDES - Data Encryption StandardDESede - Triple DESRC2 - Rivest Cipher 2Next, ask for the cipher mode:
CBC - Cipher Block ChainingCFB - Cipher FeedbackECB - Electronic CodebookOFB - Output FeedbackGCM - Galois/Counter Mode (for AES only)Finally, ask about backup:
local.properties for reference? (yes/no)"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."
{skill_base_directory}/assets/secure-properties-tool-j17.jarmkdir -p {skill_base_directory}/assetscurl (preferred — available by default on macOS). -f makes an HTTP error such as a 404 fail the command instead of saving the error page as the JAR:
curl -fL -o "{skill_base_directory}/assets/secure-properties-tool-j17.jar" \
"https://docs.mulesoft.com/mule-runtime/latest/_attachments/secure-properties-tool-j17.jar"curl is not available, try wget:
wget -O "{skill_base_directory}/assets/secure-properties-tool-j17.jar" \
"https://docs.mulesoft.com/mule-runtime/latest/_attachments/secure-properties-tool-j17.jar"unzip -tq "{skill_base_directory}/assets/secure-properties-tool-j17.jar" must exit 0. If it fails (an error page, a truncated or empty download — wget -O can leave one behind), delete the file and treat the download as failedhttps://docs.mulesoft.com/mule-runtime/latest/_attachments/secure-properties-tool-j17.jar-j17 JAR (secure-properties-tool-j17.jar), not the older secure-properties-tool.jar — the older one was built for pre-JDK 17 connectors. The -j17 JAR is published only under the docs site's latest path; the 4.4 path returns 404 for it.-j17 JAR runs on Java 8 or later — string encrypt/decrypt was verified on Java 8, 11 and 17. A Java version check is not needed beyond Java being installed.mvn) cannot be used here — this JAR is hosted on a documentation site, not a Maven repositoryScan for sensitive data in two locations:
Scan all XML files in src/main/mule (including subdirectories) for sensitive attributes:
Patterns to detect (case-insensitive):
password, passwd, pwdsecret, apikey, api-key, api_keytoken, auth, credentialusername, user, loginurl, uri, host, endpointclientId, client-id, client_idclientSecret, client-secret, client_secretkey, private, certificateImportant: Flag attributes that:
${secure::)${email.password} or ${db.username}) - these need to be converted to ${secure::} formatsrc/main/resources directory (including subdirectories) for existing .properties and .yaml/.yml filesemail.password=secret → track email.password).secure.properties filesShow a summary of all sensitive data found:
If no sensitive data is found, inform the user and exit.
Before making ANY changes, show the user:
If user says no, stop immediately.
For each sensitive value found, determine the property key name:
local.properties contains email.password=secret, use email.password${email.password} will match after conversion to ${secure::email.password}Generate a contextual property key name based on:
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> → ftpAttribute name: Use the actual attribute name
password → passwordusername → usernameurl → urlclientId → clientIdConfig name attribute (if available): Use the name or doc:name attribute value
<db:mysql-config name="MySQL_Config"> → use MySQL_ConfigProperty key format: {connector}.{config-name}.{attribute} or {connector}.{attribute}
Examples:
mongodb.password or mongodb.MongoDB_Config.passwordmysql.username or mysql.Database_Config.usernamehttp.apikey or http.API_Config.apikeysalesforce.clientSecretIf the same property key would be generated multiple times, append a number: mongodb.password.1, mongodb.password.2
After user confirmation, batch encrypt all unique sensitive values:
java -cp {skill_base_directory}/assets/secure-properties-tool-j17.jar com.mulesoft.tools.SecurePropertiesTool string encrypt <algorithm> <mode> <key> <value>Secure Properties File (src/main/resources/local.secure.properties):
property.key=![encrypted_value]Backup Properties File (src/main/resources/local.properties) - Optional:
property.key=original_value# WARNING: This file contains unencrypted sensitive values for reference only
# DO NOT commit this file to version control
# Add this file to .gitignoreFor each XML file with sensitive data, perform two types of updates:
${secure::property.key.name}Example:
<!-- 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>${email.password}, update them to ${secure::email.password}.secure.properties)Example:
<!-- 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.
Check if src/main/mule/global-configs.xml exists:
If it exists:
<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:
global-configs.xml file with the proper Mule XML structureTemplate:
<?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>pom.xml file in the project rootmule-secure-configuration-property-module dependency already exists<dependencies> section:
<dependency>
<groupId>com.mulesoft.modules</groupId>
<artifactId>mule-secure-configuration-property-module</artifactId>
<version>1.3.0</version>
<classifier>mule-plugin</classifier>
</dependency>.vscode/launch.json exists in the project rootmule.runtime.args field in each configurationmule.runtime.args exists, append -M-Dencryption.key=<their-encryption-key> to the existing valuemule.runtime.args doesn't exist, add it with the value -M-Dencryption.key=<their-encryption-key>.vscode/ or .vscode/launch.json is in .gitignore
.gitignore exists, check if it contains .vscode/ or .vscode/launch.json.vscode/ to .gitignore.gitignore doesn't exist, create it and add .vscode/Add to VM arguments:
-M-Dencryption.key=<their-encryption-key>
Or set as environment variable:
export ENCRYPTION_KEY=<their-encryption-key>.gitignore to prevent committing sensitive datalocal.properties, dev.properties, etc.Provide a completion summary:
local.secure.properties)${secure::} placeholders${property} to ${secure::property}Important reminders:
local.secure.properties to version controllocal.properties (if created) to version control.secure.properties match references in XML files${secure::} prefix was added correctly.gitignore entryFor more information, refer to: https://docs.mulesoft.com/anypoint-code-builder/int-create-secure-configs
mulesoft/mulesoft-dx
4340d6c
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.