-
Notifications
You must be signed in to change notification settings - Fork 5
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
feat: Get promise token for CS autofix requests #830
base: main
Are you sure you want to change the base?
Conversation
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.
generally unsure why encryption is needed. please involve AEM security team for a spot review of encryption.
@@ -86,7 +71,7 @@ function BrandsController(dataAccess, log, env) { | |||
const imsOrgId = organization.getImsOrgId(); | |||
const imsUserToken = getImsUserToken(context); | |||
const brandClient = BrandClient.createFrom(context); | |||
const brands = await brandClient.getBrandsForOrganization(imsOrgId, imsUserToken); | |||
const brands = await brandClient.getBrandsForOrganization(imsOrgId, `Bearer ${imsUserToken}`); |
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.
the fact that an imsUserToken
is at some point used as a bearer token in an authorization header should not be a signature requirement, please remove.
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.
I don't understand what your ask is here. I refactored out the getImsUserToken function to utils to re-use and made it return only the token not the whole authorization header, because going by the function name that would be more expected. But the brands client actually expects the whole authorization header, so I need to add back the Bearer string to make the code functionally equivalent.
src/controllers/suggestions.js
Outdated
if (!context.env?.AUTOFIX_CRYPT_SECRET || !context.env?.AUTOFIX_CRYPT_SALT) { | ||
encryptedPromiseToken = promiseToken; | ||
} else { | ||
const algorithm = context.env?.AUTOFIX_CRYPT_ALG || 'aes-192-cbc'; |
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.
why this default algorithm? it is an uncommon choice, more standard would be AES-256-GCM
?
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.
No particular reason. I updated to use the algorithm you propose and made the key length also configurable. In the end the promise token is not considered a secret, so encrypting it is an additional, optional layer of safety which @alinarublea proposed to add. The tokens are also fairly short lived, so the algorithm used won't matter too much.
src/controllers/suggestions.js
Outdated
context.env.AUTOFIX_CRYPT_SALT, | ||
24, | ||
); | ||
const iv = crypto.randomBytes(16); |
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.
Even though a random IV is generated, it's not stored or sent with the ciphertext. Without the IV, decryption later becomes problematic. Typically, you’d prepend the IV to the ciphertext so that it can be used for decryption.
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.
True, added it, also refactored to have the encryption in the IMS client to have encryption/decryption closer together, see PR there adobe/spacecat-shared#667
src/controllers/suggestions.js
Outdated
const key = await promisify(crypto.scrypt)( | ||
context.env.AUTOFIX_CRYPT_SECRET, | ||
context.env.AUTOFIX_CRYPT_SALT, | ||
24, |
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.
AES-256 uses a 32-byte key, providing stronger encryption, in case you plan to switch
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.
I made the algorithm fixed, having it configurable isn't really feasible, nor needed, moved encryption code to adobe/spacecat-shared#667
* @returns {string} imsUserToken - The IMS User access token. | ||
* @throws {ErrorWithStatusCode} - If the Authorization header is missing. | ||
*/ | ||
export function getImsUserToken(context) { |
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.
similar code is to be found in spacecat-shared-ims-client - please re-use
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.
I did not find any similar code in spacecat-shared-ims-client. There is private method 'getBearerToken' somewhere in spacecat-shared-http-utils, I'd rather not refactor a completely unrelated module within this PR. Already refactored to re-use within this module, so I am not adding additional code.
Moved encryption related code to the IMS client for better re-use, see adobe/spacecat-shared#667 |
For sites of delivery type cloud service a promise token needs to be stored in the autofix job to be able to authenticate against the cloud service AEM instance.
This PR uses the IMS Promise client to exchange the user's token against a promise token which is stored in the sqs message payload to be used in the autofix worker later on. The promise token is not considered a secret, but may be optionally encrypted using a shared secret.