Skip to content
Bluetape4k docs1.11

Converters and security boundaries

Latest stable Based on Bluetape4k release 1.11.0

An AttributeConverter makes a Kotlin type fit a column, but its JSON model, serializer, compression algorithm, or encryption key becomes a durable storage contract. Plan how old rows remain readable before changing it.

DurationAsTimestampConverter stores duration milliseconds as a Timestamp; document that the column contains a duration, not an instant.

AbstractObjectAsJsonConverter<T> logs Jackson serialization and parsing failures and returns null. Required data therefore needs validation before storage and an invariant check after loading. Write a domain converter that propagates failure when silent null is unacceptable.

Own encryption keysets outside the process

Section titled “Own encryption keysets outside the process”

AESStringConverter uses non-deterministic AES-GCM. DeterministicAESStringConverter uses AES-SIV for equality lookup but reveals equality patterns.

EncryptedStringConverterKeysets.configureAesKeyset(
secretManager.load("hibernate/aes-keyset")
)
  • Load keysets from a protected external store before conversion.
  • Missing key material fails fast.
  • A different keyset cannot decrypt existing ciphertext; design rotation before deployment.
  • Do not put cleartext keyset JSON in source, logs, or plain configuration.

Generic object converters are deprecated and trusted-storage-only. Prefer the typed ByteArray or Base64 converter base with a secure serializer. Benchmark compression against representative payloads before fixing the stored format.

Terminal window
./gradlew :bluetape4k-hibernate:test --tests '*EncryptedStringConverterTest'
./gradlew :bluetape4k-hibernate:test --tests '*JsonStringConverterTest'