MongoDB Starter
Dependency
The following dependency is provided by default for flo-based projects (created using the Scaffolder)
<dependency>
<groupId>com.iconsolutions.ipf.core.platform</groupId>
<artifactId>ipf-common-starter-mongo</artifactId>
</dependency>
If you’re developing your own project using MongoDB as a data store and using Spring Reactive, you can include the above dependency to provide enhanced MongoDB integration.
Doing so adds:
-
Retries
-
SSL Configuration
-
Additional Converters
This page outlines the various different configuration options for the functionality provided by the above dependency.
Retries
When using the MongoDB Starter, the default retry configuration below helps handle transient failures (like network issues or rate limits) in Spring Data Reactive Repositories and can be customised as required.
| Config | Type | Comment | Default |
|---|---|---|---|
|
Integer |
Maximum number of retry attempts if error code is contained in the list of |
|
|
List of Integers |
Comma separated list of error codes for which retries should be attempted |
|
|
Duration |
Delay until the next retry attempt, specified as a duration. For more details on the supported format, see: github.com/lightbend/config/blob/main/HOCON.md#duration-format |
|
SSL Configuration
If securing a connection to MongoDB server, this can be done by setting the below configuration.
| Config | Type | Comment | Default | ||
|---|---|---|---|---|---|
|
Boolean |
Configure the SSL context based on the below configuration parameters |
|
||
|
String |
File path or resource location of the keystore file for MongoDB SSL/TLS connections |
|
||
|
String |
Password required to access the keystore defined by
|
|
||
|
String |
The type of the keystore defined by |
|
||
|
String |
Specifies the password required to access the private key within the keystore.
|
|
||
|
String |
File path or resource location of the trust store used to establish trust for SSL/TLS connections to MongoDB |
|
||
|
String |
The type of the truststore defined by |
|
||
|
String |
Password to access the trust store file.
|
|
Additional Converters
The following additional converters are registered as MongoCustomConversions with Spring Data when adding the ipf-common-starter-mongo dependency:
| Converter | Conversion |
|---|---|
Decimal128ToBigDecimalConverter |
|
BigDecimalToDecimal128Converter |
|
DateToOffsetDateTimeConverter |
|
OffsetDateTimeToDateConverter |
|
DateToIsoDateTimeConverter |
|
IsoDateTimeToStringConverter |
|
StringToIsoDateTimeConverter |
|
CommandIdToStringConverter |
|
StringToCommandIdConverter |
|
SupportingContextToStringConverter |
|
StringToSupportingContextConverter |
|
Client-Side Field Level Encryption (CSFLE)
IPF supports MongoDB’s Client-Side Field Level Encryption capability, which allows end-to-end encryption to protect sensitive or personally-identifying (PI) data.
⚠️ Important Considerations ⚠️
Please note that CSFLE encryption keys are not ephemeral. That is, they are not generated on a per-session basis, but are long-lived. In other words, losing encryption keys means losing access to your data.
Before starting to use CSFLE, please ensure that you have robust processes in place for managing keys and access to keys.
Here is an non-exhaustive list of changes to the application that need extra consideration when CSFLE is enabled:
| Event | Impact |
|---|---|
An encryption key is lost |
Data cannot be recovered. |
An encryption key is compromised |
You must decrypt all fields that were encrypted with the compromised key, atomically update them with a new encrypted value derived from a new non-compromised key, and then update IPF to use the new key ID. |
A field that was previously not considered sensitive is now sensitive |
You must encrypt all existing instances of the field using the new encryption key, and update IPF’s encryption schema to include the new field. |
Basic Configuration
The snippet below shows the minimal configuration required to configure CSFLE for IPF:
ipf.mongodb.csfle {
enabled = true (1)
key-vault-namespace = "encryption.__keyVault" (2)
key-id = "fITzChBUQFWiAjyWAvvdbg==" (3)
kms-providers {
//pick the right one for your environment from one of local/aws/gcp/azure/kmip:
local { (4)
key = "key-here"
}
aws { (5)
accessKeyId = "key-id-here"
secretAccessKey = "secret-access-key-here"
}
gcp { (6)
email = "my@gcp.email"
privateKey = "my-private-key"
}
azure { (7)
tenantId = "tenant-id-here"
clientId = "client-id-here"
clientSecret = "client-secret-here"
}
kmip { (8)
endpoint = "my.kmip.com" //uses default KMIP port 5696
}
}
extra-options {
cryptSharedLibPath = "/path/to/mongo_crypt_v1.so" (9)
cryptSharedLibRequired = true
}
}
| 1 | Enable CSFLE (disabled by default) |
| 2 | The namespace (database.collection) containing the key vault |
| 3 | The shared IPF key ID to use (see Specifying a Key ID for the format, and also What Is Encrypted and How to Override the Default Encryption Key) |
| 4 | Local KMS example |
| 5 | AWS KMS example |
| 6 | GCP KMS example |
| 7 | Azure KMS example |
| 8 | KMIP example |
| 9 | Path to the MongoDB encryption shared library used to encrypt the data. Download here (select crypt_shared under "Package") |
Specifying a Key ID
Key IDs are specified as the base64 encoded equivalent of the _id of the key. This is usually a UUID. For example, if
a key entry in the MongoDB vault is:
{
_id: UUID('634211da-561d-4e34-b958-554b5bef3565')
//...other fields here...
}
The equivalent Key ID would be the base64 encoded version of the bytes represented by the UUID string (not the UUID string itself). Here are some code snippets to convert a UUID’s bytes to its base64 equivalent.
| Language | Snippet |
|---|---|
Shell |
|
Java |
|
Python |
|
keyAltNames are not supported.
|
What Is Encrypted and How to Override the Default Encryption Key
By default, only one data key (defined in key-id above) is required to encrypt all fields. The table below shows all
the fields that IPF Engineering has identified as potentially containing PI data, and has decided to encrypt if CSFLE is
enabled.
The table also shows the configuration key you can set to use a different key ID to encrypt each field. The general format is
ipf.mongodb.csfle.mongodb.[collection].[field]:
| Collection | Field to encrypt | Config key to override default key ID |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Encrypting additional collections
To encrypt additional collections, add an encryption-schemas configuration block under ipf.mongodb.csfle and use
the normal Encryption Schemas syntax:
The only departure from the MongoDB reference above is that you should not prefix the collection name with the
database name. IPF will automatically determine this from the ipf.mongodb.url.
|
ipf.mongodb.csfle {
//other config here e.g. KMS, shared lib path
encryption-schemas {
myCollection {
bsonType = "object"
properties {
myProperty {
bsonType = "string" (1)
keyId = [
{
"$binary" {
base64 = ${my-special-key-id} (2)
subType = "04"
}
}
]
algorithm = "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" (3)
}
}
}
}
}
Troubleshooting
CSFLE can be difficult to set up. Here are some common error messages you may encounter in the log and potential resolutions:
| Error | Resolution |
|---|---|
or
|
The |
|
Ensure that |
|
The defined KMS provider key is different to the one that was initially used to write data to the database |