Skip to content
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

Support for custom Cognito User Pools #129

Closed
wants to merge 31 commits into from

Conversation

majdarbash
Copy link

@majdarbash majdarbash commented Aug 9, 2024

With this change, users will be able to select custom Cognito User Pool, rather than using the default Cognito User Pool created with Deployment dashboard. This will give users control on using support Cognito Identity Providers through being able to configure different user pools per use case deployed.

image

@knihit
Copy link
Member

knihit commented Aug 9, 2024

Thank you very much for your contribution @majdarbash . Once we review the code, we will include it in the next possible minor/ major release of the solution.

Copy link
Member

@jamesnixon-aws jamesnixon-aws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution to GAAB! I have left a couple of review comments on the infrastructure and lambda portions of your PR. I will leave the UI changes to be reviewed by my colleague, @OmarRad.

One additional general comment is that we require unit tests be provided for all new functionality, which I think is lacking from this PR. Feel free to reach out and we can work together to get those added.

@@ -58,6 +58,10 @@ export const deployUseCaseBodySchema: JsonSchema = {
description: 'Deploy the CloudFront based UI for the use case',
default: true
},
ExistingCognitoUserPoolId: {
type: [JsonSchemaType.STRING, JsonSchemaType.NULL],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the intention is to use the default user pool created by the deployment dashboard when this is not provided, I would simply leave the type as string, and expect a user of the API to not pass any value for ExistingCognitoUserPoolId if they want to use the default.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem occurs when we want to update the ExistingCognitoUserPoolId:
(image user set the cognitouserpool id, but then wants to update it to the default one?)

Passing / not passing string doesn't indicate whether we want to explicitly reset user pool to the default one. With giving ability to explicitly set it as null, we can use this value when "Use Existing User Pool = false" in the UI.

let me know if this makes sense.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. That is a workflow I had not considered, and I will need to think about it more. We block certain types of edits (e.g. if you use an existing kendra index for RAG, an edit can't then tell the use case to provision a new kendra index), and I think this would be a potentially good candidate for that approach.

As an alternative, perhaps if a user deploys with a custom user pool, perhaps they could return to the default one by editing and providing the id/client of the default pool in the wizard.

@@ -43,6 +43,10 @@ export const updateUseCaseBodySchema: JsonSchema = {
description: 'Email address of the user who will be created with permissions to use the deployed use-case',
format: 'email'
},
ExistingCognitoUserPoolId: {
type: [JsonSchemaType.STRING, JsonSchemaType.NULL],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same type comment as the deploy body

@@ -296,7 +296,7 @@ export class ChatUseCaseDeploymentAdapter extends UseCase {
);
cfnParameters.set(CfnParameterKeys.UseCaseConfigTableName, process.env[USE_CASE_CONFIG_TABLE_NAME_ENV_VAR]!);

cfnParameters.set(CfnParameterKeys.ExistingCognitoUserPoolId, process.env[USER_POOL_ID_ENV_VAR]!);
cfnParameters.set(CfnParameterKeys.ExistingCognitoUserPoolId, eventBody.ExistingCognitoUserPoolId || process.env[USER_POOL_ID_ENV_VAR]!);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a glance, I don't think that setting this CfnParameter alone will be sufficient for the functionality you are looking for. Below, we set parameters for ExistingCognitoUserPoolClient and CognitoDomainPrefix based on environment variables which are set on this lambda at deployment time, and refer to resources corresponding to the User Pool created at deployment, which would differ from those required when providing your own user pool.

Have you tested if this modification allowed deployment to succeed with the desired functionality?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct - this worked properly before CognitoDomainPrefix modification as of v2.0. We need to adjust this part as CognitoDomainPrefix seems to be set based on the default user pool id. I will coordinate directly with you on this change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. So I think that for this to be compatible, we need all 3 values to be provided in the UI (user pool id, client id, and domain prefix). Onus would be on the user to have a working client in the user pool the wish to use.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, otherwise we could also support obtaining domain prefix dynamically for the user pool id that's specified - something TBD

@@ -58,6 +58,10 @@ export const deployUseCaseBodySchema: JsonSchema = {
description: 'Deploy the CloudFront based UI for the use case',
default: true
},
ExistingCognitoUserPoolId: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than having this parameter at the top level of the payload, I would perhaps suggest we create a CognitoParams subschema here containing ExistingCognitoUserPoolId and any other potential future params related to cognito. Or perhaps even a generic AuthenticationParams which itself contains provider specific auth params, which for now would just be CognitoParams. This would follow a similar pattern to what we use for KnowledeBaseParams and LlmParams.

Open to suggestions from your end.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but I believe it would make sense to consider in the future releases, for the same of backward compatibility with the current used versions of GAAB. Introducing CognitoParams will mean that all currently deployed GAAB instances should have a way to migrate, i.e. set CognitoParams from ExistingCognitoUserPoolId (currently in use).

If you agree, we can work on it in the next iterations, as an enhancement to this, and we can possibly consider extending with more user management functionality as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well since existing versions do not have the ability to set a custom user pool, adding CognitoParams as a non-required param would not break compatibility as far as I can tell. To continue using the default (created for you) pool, the front end would just not send that object in the request. On the other hand, if we add this and then change the positioning of it later, that certainly will break API compatibility.

@@ -26,6 +26,44 @@ export const TOOLS_CONTENT = {
}
]
},
existingUserPool: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works but we most recently switched to having the relevant tools content for each component be in that components file so we are slowly moving away from having it all in tools-content.jsx. See here for an example:

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @OmarRad , noted.

Copy link
Member

@OmarRad OmarRad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, Majd, for your contribution. The UI side is thoroughly complete and looks good to me!

2 very minor comments:

  • For organization purposes, I would move the userpool-related UI files into a dedicated UserPool directory under the UseCase directory
  • I've left a small comment regarding the location of the tools content.

Otherwise, all that's required is the unit tests. Please let us know if you have any questions or require support on that.

@majdarbash
Copy link
Author

Thanks Omar, I will work and update the PR according to your feedback.

@bogdankatishev
Copy link

Any updates on this? This would be helpful for us

@tabdunabi
Copy link
Member

Thank you @bogdankatishev for reaching out!.

The team is working with @majdarbash to address few code reviews. This feature is a high priority and we are working on including it in a subsequent release ASAP.

@majdarbash
Copy link
Author

Hi team, the changes are done as we discussed.
Please feel free to continue reviewing the changes @jamesnixon-aws , @OmarRad.
Thanks!

Copy link
Member

@jamesnixon-aws jamesnixon-aws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple small comments, but looking good on my end. Let's connect to discuss steps on getting unit tests in here.

Copy link
Member

@jamesnixon-aws jamesnixon-aws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the late catch, but one of my colleagues mentioned this requirement to ensure all the values are validated for both the API and the UI fields.

@jamesnixon-aws
Copy link
Member

This feature has been integrated as of release v2.1.0 (#157)
Thanks for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants