Lightweight Java library for masking sensitive data during JSON serialization β and beyond.
- Zero configuration β just annotate your fields with
@MaskData - 12 built-in mask types β credit cards, emails, phones, IBANs, SSNs, names, passports, bank accounts, IPs, and more
- Custom masking β configurable mask character, visible start/end
MaskUtilsβ use masking intoString(), logs, or anywhere- Java records support β works with records, classes, and methods
- Spring Boot Starter β auto-configuration via
application.yml - Per-ObjectMapper config β
MaskingModulefor multi-tenant / parallel-test scenarios - Audit logging β track masked field access (SLF4J or custom)
- Global config β enable/disable at runtime, customizable mask character
- JMH benchmarks β proven performance
- Extensible β implement
MaskingStrategyfor custom logic
| Module | Description |
|---|---|
bankmasker-core |
Core library β annotations, strategies, serializer, MaskUtils |
bankmasker-spring-boot-starter |
Auto-configuration for Spring Boot |
bankmasker-benchmark |
JMH performance benchmarks |
<!-- Core only (any Java project) -->
<dependency>
<groupId>io.github.zeytx</groupId>
<artifactId>bankmasker-core</artifactId>
<version>1.0.1</version>
</dependency>
<!-- Spring Boot (includes core automatically) -->
<dependency>
<groupId>io.github.zeytx</groupId>
<artifactId>bankmasker-spring-boot-starter</artifactId>
<version>1.0.1</version>
</dependency>// Core only (any Java project)
implementation 'io.github.zeytx:bankmasker-core:1.0.1'
// Spring Boot (includes core automatically)
implementation 'io.github.zeytx:bankmasker-spring-boot-starter:1.0.1'public class PaymentDTO {
@MaskData(MaskType.CREDIT_CARD)
private String cardNumber;
@MaskData(MaskType.EMAIL)
private String email;
@MaskData(MaskType.PHONE)
private String phone;
@MaskData(MaskType.IBAN)
private String iban;
@MaskData(MaskType.SSN)
private String ssn;
@MaskData(MaskType.NAME)
private String fullName;
@MaskData(MaskType.DNI)
private String nationalId;
@MaskData(MaskType.PASSPORT)
private String passport;
@MaskData(MaskType.BANK_ACCOUNT)
private String bankAccount;
@MaskData(MaskType.IP_ADDRESS)
private String serverIp;
@MaskData // defaults to TOTAL
private String secret;
}ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(payment);{
"cardNumber": "****-****-****-1234",
"email": "jo****@example.com",
"phone": "********5678",
"iban": "ES******************7891",
"ssn": "***-**-6789",
"fullName": "J*** D**",
"nationalId": "******3456",
"passport": "AB****567",
"bankAccount": "**********1234",
"serverIp": "***.***.***.100",
"secret": "********"
}@MaskData(value = MaskType.CUSTOM, maskChar = '#', visibleStart = 2, visibleEnd = 3)
private String accountId;
// "ABCDEFGHIJK" β "AB######IJK"| Parameter | Default | Description |
|---|---|---|
maskChar |
* |
Character used for masking |
visibleStart |
0 |
Characters visible at the beginning |
visibleEnd |
0 |
Characters visible at the end |
Use masking anywhere, not just during JSON serialization:
// In toString()
@Override
public String toString() {
return "User{card=" + MaskUtils.mask(cardNumber, MaskType.CREDIT_CARD) + "}";
// β User{card=****-****-****-1234}
}
// With custom parameters
String masked = MaskUtils.mask("ABCDEFGHIJK", '#', 2, 3);
// β "AB######IJK"
// In log statements
log.info("Processing payment for card {}", MaskUtils.mask(card, MaskType.CREDIT_CARD));Add the starter and configure via application.yml:
bankmasker:
enabled: true # globally enable/disable masking
default-mask-char: '*' # default mask character
audit:
enabled: true # enable SLF4J audit loggingThe starter auto-configures MaskingConfig and optionally enables SLF4J-based audit logging.
MaskingConfig.getInstance()
.setEnabled(true)
.setDefaultMaskChar('#')
.setAuditLogger((field, type) ->
log.info("Masked '{}' with {}", field, type));Track every masked field for compliance:
// Using built-in SLF4J logger
MaskingConfig.getInstance()
.setAuditLogger(new Slf4jMaskingAuditLogger());
// Or custom
MaskingConfig.getInstance()
.setAuditLogger((field, type) ->
auditService.record(field, type, Instant.now()));| Type | Input | Output |
|---|---|---|
CREDIT_CARD |
4111111111111111 |
****-****-****-1111 |
EMAIL |
john.doe@example.com |
jo****@example.com |
PHONE |
+525512345678 |
********5678 |
DNI |
ABCD123456 |
******3456 |
IBAN |
ES6621000418401234567891 |
ES******************7891 |
SSN |
123-45-6789 |
***-**-6789 |
NAME |
John Doe |
J*** D** |
PASSPORT |
AB1234567 |
AB****567 |
BANK_ACCOUNT |
12345678901234 |
**********1234 |
IP_ADDRESS |
192.168.1.100 |
***.***.***.100 |
TOTAL |
anything |
******** |
CUSTOM |
(configurable) | (configurable) |
For multi-tenant apps or parallel tests, use MaskingModule instead of the global singleton:
MaskingConfig tenantConfig = MaskingConfig.create()
.setEnabled(true)
.setDefaultMaskChar('#');
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new MaskingModule(tenantConfig));
// This mapper uses '#' while others keep using '*'@MaskData works on Java records out of the box:
public record PaymentRecord(
@MaskData(MaskType.CREDIT_CARD) String cardNumber,
@MaskData(MaskType.EMAIL) String email,
String plainField
) {}Implement MaskingStrategy for fully custom logic:
MaskingStrategy myStrategy = value -> value.charAt(0) + "***";Run JMH benchmarks to measure serialization overhead:
mvn -pl bankmasker-benchmark package -DskipTests
java -jar bankmasker-benchmark/target/bankmasker-benchmark.jarmvn clean verifyCoverage report: bankmasker-core/target/site/jacoco/index.html
bankmasker/
βββ pom.xml β Parent POM
βββ bankmasker-core/ β Core library
β βββ pom.xml
β βββ src/main/java/.../bankmasker/
β βββ MaskData.java β @MaskData annotation
β βββ MaskType.java β Built-in mask types (12)
β βββ MaskingSerializer.java β Jackson serializer
β βββ MaskingStrategy.java β Strategy interface
β βββ MaskUtils.java β Programmatic masking
β βββ MaskingConfig.java β Global + per-mapper config
β βββ MaskingModule.java β Per-ObjectMapper module
β βββ MaskingAuditLogger.java β Audit interface
β βββ Slf4jMaskingAuditLogger.java β SLF4J audit impl
βββ bankmasker-spring-boot-starter/ β Spring Boot auto-config
β βββ pom.xml
β βββ src/main/java/.../spring/
β βββ BankMaskerAutoConfiguration.java
β βββ BankMaskerProperties.java
βββ bankmasker-benchmark/ β JMH benchmarks
β βββ src/main/java/.../benchmark/
β βββ MaskingSerializerBenchmark.java
βββ .github/workflows/ci.yml β GitHub Actions CI
βββ .github/copilot-instructions.md β GitHub Copilot context
βββ docs/ β GitHub Pages site
β βββ index.html
βββ CHANGELOG.md
βββ CONTRIBUTING.md
βββ LICENSE
βββ README.md
βββ llms.txt β AI/LLM quick reference
βββ llms-full.txt β AI/LLM full API docs
This project includes llms.txt and llms-full.txt files following the llms.txt standard. These files help AI assistants (ChatGPT, Claude, Copilot, Gemini, etc.) understand how to use BankMasker correctly when generating code.
If you're building with an AI assistant, point it to llms.txt for quick reference or llms-full.txt for complete API documentation.
MIT Β© zeytx