-
Notifications
You must be signed in to change notification settings - Fork 246
CLDSRV-636: SSE with both internal & external KMS (HF 9.2.0.12) #5788
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
CLDSRV-636: SSE with both internal & external KMS (HF 9.2.0.12) #5788
Conversation
Hello bourgoismickael,My role is to assist you with the merge of this Available options
Available commands
Status report is not available. |
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
|
// this should trigger vault account key update as well | ||
return kms.createBucketKey(bucket, log, (err, { masterKeyArn }) => { | ||
if (err) { | ||
return cb(err, bucket); |
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.
should we log something?
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.
errors should already be logged by kms implementation. But we could append a message to the error to describe the error is due to the SSE migration
sse.masterKeyId = masterKeyArn; | ||
} | ||
if (updateConfigured) { | ||
sse.configuredMasterKeyId = masterKeyArn; |
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.
Are sse.masterKeyId
and sse.configuredMasterKeyId
not suppose to be different?
Does it break something if we have them both be the same value?
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.
Yes they should be different, I need to fix this
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.
Actually nothing should break, right now they are different because they are set at different times, but having the same key is fine
@@ -51,6 +52,7 @@ function objectGet(authInfo, request, returnTagCount, log, callback) { | |||
}; | |||
|
|||
return metadataValidateBucketAndObj(mdValParams, log, | |||
(err, bucket, objMD) => updateEncryption(err, bucket, objMD, objectKey, log, {}, |
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.
Should we fail the GET/HEAD object call if update encryption fails?
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.
Right now it will fail, the error is passed to the next callback.
But we could provide a flag through config to ignore migration failure and still return the object.
The only reason where the update could fail but not the get is if you can't write, because disk is full but still wants to read from it.
lib/kms/wrapper.js
Outdated
@@ -309,17 +377,21 @@ class KMS { | |||
cryptoScheme: serverSideEncryptionInfo.cryptoScheme, | |||
decipher: null, | |||
}; | |||
|
|||
// shadowing global client for key - implName already used can't be shadowed here | |||
const { client, implName: _impl, key } = getClientForKey(serverSideEncryptionInfo.masterKeyId); |
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.
We always need to check the client because there is no way to know that a migration never happened before? If we had a way to know that no migration happened before, we would be safe to use the default KMS, right? How is the impact of getClientForKey on the GET object latency?
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.
If we know the migration never happened before, we'd rather know we should use the previous
KMS instead of the new default external KMS.
But the way to know for now for outscale is if the scality kms arnPrefix is present or not.
I've also pre instantiated the previous KMS as file
is the only allowed for now in migration, to avoid latency of first GET after startup.
The impact on GET object latency is:
- extract key detail from arn:
split('/')
andsplit(':')
on the key: https://github.com/scality/Arsenal/pull/2349/files#diff-1c24d37a19bc08405b548ef9b5ac12a2ef83b7edb3a2ee62cc8426c7df8e5b95R122-R137 - if key is scality arnPrefix
- validate the key parts: https://github.com/scality/Arsenal/pull/2349/files#diff-1c24d37a19bc08405b548ef9b5ac12a2ef83b7edb3a2ee62cc8426c7df8e5b95R145-R167
- concatenate the
clientIdentifier
string: https://github.com/scality/cloudserver/pull/5788/files#diff-c506ce0254987c99cd5ff5a10cd1ecabc6e1bc59e643fe2401103b9feb7b27a6R131 - return the client and KeyId
- if key is not scality arnPrefix
- return the client (default or previous based on
sseMigration
configuration presence) and the KeyId
- return the client (default or previous based on
But as the GetObject migrate to new scality arn format, it should be expected the first Get on a bucket and object is slower for migration, and then we fall in the case where it's a scality arnPrefix
lib/kms/wrapper.js
Outdated
@@ -196,10 +261,13 @@ class KMS { | |||
log.debug('using user configured kms master key id'); | |||
masterKeyId = configuredMasterKeyId; | |||
} | |||
// shadowing global client for key | |||
// but should not happen to cipher for another client as Puts should use current KMS | |||
const { client, implName, key } = getClientForKey(masterKeyId); |
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.
Is getClientForKey needed for PUT object? We know that the client will always be the default one. What is the impact on our PUT object latency?
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.
It's needed if kms key is passed in scality arn format on a PUT request. Then the function will extract the KeyId from the arn and validate the arn scality format.
It also returns the client identifier so we can block usage of other client like if an arn for the file
KMS is used when there is a configured external KMS, it should be forbidden: https://github.com/scality/cloudserver/pull/5788/files#diff-c506ce0254987c99cd5ff5a10cd1ecabc6e1bc59e643fe2401103b9feb7b27a6R332-R339
And for any future case where multiple KMS providers can be used it will become useful
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.
As for PUT latency, it will be same as GET:
The impact on PUT object latency is:
- extract key detail from arn: split('/') and split(':') on the key: https://github.com/scality/Arsenal/pull/2349/files#diff-1c24d37a19bc08405b548ef9b5ac12a2ef83b7edb3a2ee62cc8426c7df8e5b95R122-R137
- if key is scality arnPrefix
- validate the key parts: https://github.com/scality/Arsenal/pull/2349/files#diff-1c24d37a19bc08405b548ef9b5ac12a2ef83b7edb3a2ee62cc8426c7df8e5b95R145-R167
- concatenate the clientIdentifier string: https://github.com/scality/cloudserver/pull/5788/files#diff-c506ce0254987c99cd5ff5a10cd1ecabc6e1bc59e643fe2401103b9feb7b27a6R131
- return the client and KeyId
- if key is not scality arnPrefix (should not happen as the PUT will prefix the key with a scality arn)
- return the client (default or previous based on sseMigration configuration presence) and the KeyId
a7f5219
to
b40068c
Compare
> This is a scheduled Ubuntu 20.04 brownout. Ubuntu 20.04 LTS runner will be removed on 2025-04-15. For more details, see actions/runner-images#11101 (cherry picked from commit 5c4a1b3)
Avoid print the warning if scality-kms is not configured: ```json {"name":"S3","time":1742220545805,"error":{"code":"MODULE_NOT_FOUND","requireStack":["/home/mickael/scality/cloudserver/lib/kms/wrapper.js","/home/mickael/scality/cloudserver/lib/data/wrapper.js","/home/mickael/scality/cloudserver/lib/utilities/healthcheckHandler.js","/home/mickael/scality/cloudserver/lib/utilities/internalHandlers.js","/home/mickael/scality/cloudserver/lib/server.js","/home/mickael/scality/cloudserver/index.js"]},"level":"warn","message":"scality kms unavailable. Using file kms backend unless mem specified.","hostname":"mickael-xps","pid":139701} ``` (cherry picked from commit 9e8c505)
642fb3f
to
9cd6ec0
Compare
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.
Thanks for the changes
To avoid breaking changes for clients
8ff7b58
to
cd4bca8
Compare
Issue: S3C-9996 MPU was not accepting configuredMasterKeyId (from object or bucket) for Create and Complete MPU. But used the configuredMasterKeyId (from object or bucket) for UploadPart making it possible to have parts encrypted with a different key than the key in object metadata after completion. Resulting in potential error on GetObject later: - If bucket had configuredMasterKeyId but no masterKeyId (no AES before or aws:kms without configuredKey) it would crash on decryption. - If bucket had configuredMasterKeyId and a masterKeyId it would be used to decrypt parts potentially encrypted with a configuredMasterKeyId, decrypting gibberish - On UploadPart object level encryption could be provided (outside sdk/cli) which is bad. ___ The expected behavior fixed here is to use the provided SSE on CreateMPU and then for UploadPart and CompleteMPU use the SSE provided at CreateMPU. The MPU calls also return the SSE headers now. The CopyObject returned SSE headers are fixed as well, the configuredMasterKeyId was ignored This fix allow seamless continuation of ongoing MPU during SSE migration. ___ There is no migration to fix already existing completed MPU.
cd4bca8
to
c2f045f
Compare
This is generic but simplified for file to aws use case and will be extended in latest version to handle any backend.
hideScalityArn
) to keep backward compatibilitysseMigration
configfile
key withaws
keyfile
) to decript and read files (or for ongoing MPU)Overall example of a new Key Format and migration