Have you ever accidentally git pushed an application.yml with a database password written in plain text? Sensitive information stays in Git history forever. But HashiCorp Vault or AWS Secrets Manager feels like overkill for many situations — that’s where Jasypt comes in.
With Jasypt, you can replace sensitive values like passwords with encrypted strings in ENC(...) format, with almost no changes to your existing application.yml structure. It’s safe to commit to Git, and Spring automatically decrypts the values at startup.
Why Plain Text Passwords Are a Problem
Committing something like spring.datasource.password: mysecretpassword to a Git repository introduces the following risks:
- Every team member can see the password
- If you accidentally make the GitHub repository public, crawlers will pick it up immediately
- It can leak through log output or error messages
Understanding How Jasypt Works
Adding jasypt-spring-boot-starter hooks into Spring’s property loading process. When it detects a value wrapped in ENC(...), it automatically decrypts it using the specified encryption key and passes the plain text value to the application. Since it uses symmetric-key encryption, how you manage this key (jasypt.encryptor.password) is the core responsibility.
Adding the Dependency
Add jasypt-spring-boot-starter and the Maven plugin used for encrypting strings to your pom.xml.
<dependencies>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-maven-plugin</artifactId>
<version>3.0.5</version>
</plugin>
</plugins>
</build>
This article assumes Spring Boot 3.x (Java 17 or later). No additional JCE configuration is required in a Spring Boot 3.x environment. Check Maven Central for the latest version.
Encrypting with the Maven Plugin
# Encrypt
mvn jasypt:encrypt-value \
-Djasypt.encryptor.password="mySecretKey" \
-Djasypt.plugin.value="mysecretpassword"
Running this outputs the encrypted string. Depending on the plugin version, the output may already include the ENC(...) wrapper — if not, manually wrap it with ENC( and ) before pasting it into application.yml.
For decryption verification, pass only the string inside ENC().
# Verify decryption (pass only the string inside ENC())
mvn jasypt:decrypt-value \
-Djasypt.encryptor.password="mySecretKey" \
-Djasypt.plugin.value="xxxxxxxx..."
Passing the entire ENC() wrapper will cause decryption to fail. Pass only the string inside the parentheses of ENC(xxxxxx) to -Djasypt.plugin.value.
Embedding Encrypted Values in application.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: dbuser
password: ENC(AbCdEfGhIjKlMnOpQrStUvWxYz==)
app:
api-key: ENC(XyZ123AbC456DefGhI789==)
jwt-secret: ENC(PqRsTuVwXyZaBcDeFgHiJkL==)
An incorrect ENC( / ) format will cause an exception at startup, so make sure no extra spaces crept in when copying.
Configuring the Encryption Key
Never hardcode the encryption key directly in application.yml. Committing the key to Git defeats the entire purpose of encryption.
Spring Boot automatically converts environment variables like JASYPT_ENCRYPTOR_PASSWORD to the jasypt.encryptor.password property (uppercase with underscores → lowercase with dots). So all you need to do is set the environment variable before starting the application.
# Set the environment variable and start the application
export JASYPT_ENCRYPTOR_PASSWORD=mySecretKey
./mvnw spring-boot:run
# When launching with java -jar
JASYPT_ENCRYPTOR_PASSWORD=mySecretKey java -jar target/myapp.jar
When running with Docker, add -e JASYPT_ENCRYPTOR_PASSWORD=xxx to your options.
Managing the Key Locally with a .env File
For team development, a common pattern is for each developer to manage the key using a .env file.
# .env
JASYPT_ENCRYPTOR_PASSWORD=myLocalDevKey
# Add to .gitignore
.env
Spring Boot and Maven do not automatically read .env files, so you need to use a tool like direnv or dotenv-cli to load the environment variables into your shell.
With direnv, add dotenv to your .envrc and run direnv allow. With dotenv-cli, you can start the application like this:
dotenv run -- ./mvnw spring-boot:run
It’s a good idea to share a .env.example with your team to document which variables are required. Combining this with profile-based configuration switching between dev and prod keeps per-environment management clean. For more details, see Safely Switching Environment-Specific Configuration with Spring Boot Profiles.
For general configuration file management, see The Complete Guide to Spring Boot Configuration Files as well.
Integrating with GitHub Actions CI/CD
Register JASYPT_ENCRYPTOR_PASSWORD under Settings > Secrets and variables > Actions in your repository, then reference it from your workflow.
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
env:
JASYPT_ENCRYPTOR_PASSWORD: ${{ secrets.JASYPT_ENCRYPTOR_PASSWORD }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- run: mvn test
Hardening the Encryption Algorithm
In jasypt-spring-boot-starter 3.x, the default algorithm is already PBEWITHHMACSHA512ANDAES_256. For new projects, a secure algorithm is used without any additional configuration.
That said, declaring it explicitly makes the configuration intent clear. This change is required when migrating from v2.x (v2.x’s default PBEWithMD5AndDES is no longer recommended due to MD5’s weak collision resistance and DES’s 56-bit key length).
jasypt:
encryptor:
algorithm: PBEWITHHMACSHA512ANDAES_256
iv-generator-classname: org.jasypt.iv.RandomIvGenerator
If you change the algorithm, specify the same algorithm on the Maven plugin side as well (e.g., -Djasypt.encryptor.algorithm=PBEWITHHMACSHA512ANDAES_256). A mismatch between the algorithm used for encryption and decryption will cause an error at startup. Also note that all existing encrypted values will need to be regenerated.
Jasypt’s Limitations and Next Steps
Jasypt is convenient, but it has its limitations:
- Key rotation is cumbersome (all encrypted values must be regenerated)
- No audit logs or fine-grained access control
- As the team grows, sharing and managing the key becomes unwieldy
“Easy to start, hard to scale” is the honest trade-off. When compliance requirements tighten or microservices multiply, consider migrating to HashiCorp Vault or AWS Secrets Manager.
Once you’ve finished replacing values with ENC() in application.yml, verify these three things:
.envis listed in.gitignoreand is not tracked by Gitgit logshows no plain text secrets remaining in historyJASYPT_ENCRYPTOR_PASSWORDis correctly injected in your CI/CD pipeline and tests pass