-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Aws kms #120
Aws kms #120
Changes from 16 commits
8d3f061
dcba545
89fbe8f
562ddc8
bb1da1e
6711acc
4d42597
43fb07e
24f3eb3
e36ccf6
82cd71f
a27e0be
f5510e9
9e153ef
70acd1d
caa6db2
973cf6e
d6bafa3
76cd470
55e3a79
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,9 +94,35 @@ keyManagement: | |
googleKms: | ||
location: <location> | ||
keyRing: <key ring name> | ||
protectionLevelP: HSM | ||
protectionLevel: HSM | ||
``` | ||
And use the following command to deploy kamus: | ||
``` | ||
helm upgrade --install kamus soluto/kamus -f values.yaml --set-string keyManagement.googleKms.credentials="$(cat credentials.json | base64)" | ||
``` | ||
|
||
### AWS KMS | ||
Using [AWS KMS](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html) as the key managment solution is the secure solution when running a cluster on AWS Cloud. | ||
There are 2 options to authentication with the KMS: | ||
1. Kamus by default will try to use the regular AWS SDK discovery mechinisem, if your cluster in AWS you need to map IAM role to kamus POD by using one of the community tools, for example [kiam](https://github.com/uswitch/kiam). | ||
2. Provide user access key and secret with KMS access. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a quick note on what is required when initializing KMS? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, maybe add a note on the required IAM permissions for Kamus? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you elaborate? I can't think of anything required other than permissions to KMS. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My bad, you're right. Just specify the IAM role? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added below that the required IAM role/user permissions for kamus to work properly is full KMS access. |
||
|
||
Typical values.yaml for AWS : | ||
```yaml | ||
keyManagement: | ||
provider: AwsKms | ||
``` | ||
If you want to pass user access key and secret to Kamus deploy use the following values.yaml command: | ||
```yaml | ||
keyManagement: | ||
provider: AwsKms | ||
awsKms: | ||
region: <> | ||
key: <> | ||
secret: <> | ||
``` | ||
And now deploy Kamus using the following helm command: | ||
``` | ||
helm upgrade --install kamus soluto/kamus -f <path/to/values.yaml> | ||
``` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
using System; | ||
using System.IO; | ||
using System.Net; | ||
using System.Threading.Tasks; | ||
using Amazon.KeyManagementService; | ||
using Amazon.KeyManagementService.Model; | ||
|
||
namespace Kamus.KeyManagement | ||
{ | ||
public class AwsKeyManagement : IKeyManagement | ||
{ | ||
private readonly IAmazonKeyManagementService mAmazonKeyManagementService; | ||
private readonly SymmetricKeyManagement mSymmetricKeyManagement; | ||
|
||
public AwsKeyManagement(IAmazonKeyManagementService amazonKeyManagementService, SymmetricKeyManagement symmetricKeyManagement) | ||
{ | ||
mAmazonKeyManagementService = amazonKeyManagementService; | ||
mSymmetricKeyManagement = symmetricKeyManagement; | ||
} | ||
|
||
public async Task<string> Encrypt(string data, string serviceAccountId, bool createKeyIfMissing = true) | ||
{ | ||
var masterKeyAlias = $"alias/kamus/{KeyIdCreator.Create(serviceAccountId)}"; | ||
shaikatz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
(var encryptionKey, var encryptedDataKey ) = await GenerateEncryptionKey(masterKeyAlias); | ||
shaikatz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
mSymmetricKeyManagement.SetEncryptionKey(Convert.ToBase64String(encryptionKey.ToArray())); | ||
var encryptedData = await mSymmetricKeyManagement.Encrypt(data, serviceAccountId); | ||
shaikatz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return "env" + "$" + encryptedDataKey + "$" + encryptedData; | ||
|
||
} | ||
|
||
public async Task<string> Decrypt(string encryptedData, string serviceAccountId) | ||
{ | ||
var encryptedEncryptionKey = encryptedData.Split('$')[1]; | ||
shaikatz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
var actualEncryptedData = encryptedData.Split('$')[2]; | ||
|
||
var decryptionResult = await mAmazonKeyManagementService.DecryptAsync(new DecryptRequest | ||
shaikatz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
CiphertextBlob = new MemoryStream(Convert.FromBase64String(encryptedEncryptionKey)), | ||
}); | ||
|
||
var encryptionKey = ConvertMemoryStreamToBase64String(decryptionResult.Plaintext); | ||
shaikatz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
mSymmetricKeyManagement.SetEncryptionKey(encryptionKey); | ||
return await mSymmetricKeyManagement.Decrypt(actualEncryptedData, serviceAccountId); | ||
} | ||
|
||
private static string ConvertMemoryStreamToBase64String(MemoryStream ms) | ||
{ | ||
return Convert.ToBase64String(ms.ToArray()); | ||
} | ||
|
||
private async Task<(MemoryStream encryptionKey, string encryptedEncryptionKey)> GenerateEncryptionKey(string keyAlias) | ||
{ | ||
GenerateDataKeyResponse generateKeyResponse = null; | ||
try | ||
{ | ||
generateKeyResponse = await mAmazonKeyManagementService.GenerateDataKeyAsync(new GenerateDataKeyRequest { KeyId = keyAlias, KeySpec = "AES_256"}); | ||
|
||
} | ||
catch (NotFoundException) | ||
{ | ||
await GenerateMasterKey(keyAlias); | ||
generateKeyResponse = await mAmazonKeyManagementService.GenerateDataKeyAsync(new GenerateDataKeyRequest { KeyId = keyAlias, KeySpec = "AES_256"}); | ||
} | ||
|
||
if (generateKeyResponse.HttpStatusCode != HttpStatusCode.OK) | ||
{ | ||
throw new Exception($"Couldn't generate encryption key for {keyAlias}"); | ||
} | ||
|
||
return (generateKeyResponse.Plaintext, ConvertMemoryStreamToBase64String(generateKeyResponse.CiphertextBlob)); | ||
} | ||
|
||
private async Task GenerateMasterKey(string keyAlias) | ||
{ | ||
var createKeyResponse = await mAmazonKeyManagementService.CreateKeyAsync(new CreateKeyRequest()); | ||
await mAmazonKeyManagementService.CreateAliasAsync(keyAlias, createKeyResponse.KeyMetadata.KeyId); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using System.Security.Cryptography; | ||
using System.Text; | ||
using Microsoft.AspNetCore.WebUtilities; | ||
|
||
namespace Kamus.KeyManagement | ||
{ | ||
public static class KeyIdCreator | ||
{ | ||
public static string Create(string s) | ||
{ | ||
return | ||
WebEncoders.Base64UrlEncode( | ||
SHA256.Create().ComputeHash( | ||
Encoding.UTF8.GetBytes(s))) | ||
.Replace("_", "-"); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe keep this section just say "add support for other solutions, like HSM"?