All Downloads are FREE. Search and download functionalities are using the official Maven repository.

secretblob.SecretBlobModule.kt Maven / Gradle / Ivy

There is a newer version: 0.3.1
Show newest version
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
 */
open 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"
            }
            require(key.length % 16 == 0) { "key-length (${key.length}) must be a multiple of 16" }
        }
    }

    open fun resolveSecretBlob(): SecretBlob = _secretBlob
    private val _secretBlob by lazy {
        val impl = SecretBlobImpl(keys, secretBlobFilePath)
        if (enableCache) SecretBlobCacheDecorator(impl, keys) else impl
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy