Hello,
When deploying Karaf to production in the cloud, one often has to provide configuration to containers where some of the config properties are secrets (for example, database passwords, secret keys, API keys, etc.). Karaf has support for symmetric encryption of properties using jasypt, which is helpful, but still leaves the problem of securely distributing the encryption keys to the container. This distribution of encryption keys can be done in Amazon AWS using a variety of means including instance metadata, puppet, etc., but all of these methods have the disadvantage of propagating encryption key information throughout the environment, including the on-premise Continuous Integration servers. This is not that difficult to accomplish when systems are first deployed, but it you want to rotate encryption keys and use something like Karaf dynamic reconfiguration via Config Admin, you now have to find a secure way to distribute the newly rotated keys to the Karaf instances. Instance metadata can't be updated for systems already started, so you're now faced with the prospect of having to use Puppet to push encryption keys prior to pushing new container configuration. A better way would be to utilize a crypto service where keying information never leaves the boundaries of a trusted device or service. Amazon provides two built-in mechanisms for this purpose: CloudHSM and their newly-announced KSM (Key Management Service). The basic idea is that one or more dedicated, named keys would be created within the KSM, and secret properties would be encrypted by calling the Encrypt function of the KMS: "Encrypt this blob with the latest version of the key named by the alias ABC-XYZ". The encrypted blob would be stored in the config file using a namespace like ENC, so: <cm:property name="mydb.password" value="ENC(xxxxxx)"/> where xxxxxx is the ciphertext. And then ENC namespace would be defined using a declaration of: xmlns:enc="http://karaf.apache.org/xmlns/kms-enc/v1.0.0" And further expanded with a property placeholder definition referencing the alias of the key - using its ARN, or Amazon Resource Identifier which looks something like: "arn:aws:kms:us-east-1:168548364837:key/12345678-1234-1234-1234-123456789012". When the properties are resolved, it will cause multiple Decrypt calls to Amazon KMS saying "Decrypt this ciphertext using the key with this alias". There are several benefits to this approach: 1. Crypto keying material never leaves the trusted boundary of the KMS. Keys can never be stolen or saved anywhere. 2. Access to the Encrypt and Decrypt functions for each separate key are controlled using Grants to specific IAM Roles, which are assigned to each EC2 instance out-of-band. Access to keys can be revoked with a simple removal of a Grant 3. Key rotation is handled inherently by the KMS in a way that allows ciphertext from older key versions to still be decryptable [1] 4. All encrypt/decrypt calls are fully audited and handled in CloudTrail I would be happy to prototype this approach in the next couple weeks. Would like to know what people think, and maybe someone could be kind enough to point me in the direction of the repository containing the source code for the jasypt decryptor used in Karaf. Thoughts? -Chad
