secretblob.SecretBlobModule.kt Maven / Gradle / Ivy
package se.wollan.crypto.secretblob
import java.nio.file.Path
/**
* This file tries to standardize secret blob handling, so it can work as a drop-on in other services.
* Using this, you can derive multiple secrets (and add new ones) from this data without having to
* add new docker secrets to backend servers for each one.
*
* What you need to do:
* - Generate secret blob data securely, generate offline by running function [generateNewSecretBlobData].
* - Place this secret on all servers in file `/docker/secrets//secretblob` with minimal permissions.
* - Create a docker-compose secret named `secretblob`.
* ```
* services:
* myservice:
* ...
* environment:
* SECRET_BLOB_FILE: "/run/secrets/secretblob"
* secrets:
* - secretblob
*
* secrets:
* secretblob:
* file: /docker/secrets//secretblob
* ```
* - Define a secret blob enum with your keys. This list is append only!
* ```
* enum class MySecretBlobKey(val length: Int) : SecretBlobKey {
* MySecretKey1(32, "222200000000000000000000000000BB"),
* MySecretKey2(16, "222200000000000000000000000000BB"),
* }
* ```
* - Bootstrap [SecretBlobModule].
* - Resolve [SecretBlob] and get secret blob data by `getSecretDataForKey(MySecretBlobKey.MySecretKey1)`.
*
* @param keys all enums value, i.e. `MySecretBlobKey.entries`
* @param secretBlobFilePath file path to the secret blob, e.g. "/run/secrets/secretblob"
* @param enableCache will keep secret data in memory if enabled, could be a security issue
*/
class SecretBlobModule(
private val keys: List,
private val secretBlobFilePath: Path,
private val enableCache: Boolean
) {
init {
require(keys.toSet().size == keys.size) { "secret blob keys contain duplicates!" }
for (key in keys) {
require(key.length * 2 == key.hexMask.length) {
"key-length (${key.length}) != mask-length (${key.hexMask.length / 2}) for key $key"
}
}
}
fun resolveSecretBlob(): SecretBlob = _secretBlob
private val _secretBlob by lazy {
val impl = SecretBlobImpl(keys, secretBlobFilePath)
if (enableCache) SecretBlobCacheDecorator(impl, keys) else impl
}
}