feat(cognito): honor a custom ClientSecret on CreateUserPoolClient

ZE
5d ago
+179-7

Summary

Closes #2750.

  • CreateUserPoolClient takes a caller-chosen ClientSecret and makes it the app client's secret, so DescribeUserPoolClient, the /oauth2/token client authentication and SECRET_HASH checks all use it. Without ClientSecret nothing changes.
  • The value is checked against ClientSecretType (24-64 characters matching [\w+]+); a value outside it fails with InvalidParameterException and the standard 1 validation error detected message, which leaves the value out because the member is @sensitive. ClientSecret together with GenerateSecret: true fails with InvalidParameterException, as the API reference says.
  • Docs: the app clients line of docs/services/cognito.md.

Not changed here:

  • CloudFormation: AWS::Cognito::UserPoolClient has no ClientSecret property ("you can't specify a secret value"), so the provisioner stays as it is.
  • The secret-rotation operations (AddUserPoolClientSecret and friends) keep their current behaviour; they are a separate feature.
  • No SDK helpers: this is a standard API field, not a /_fakecloud endpoint.

Usage, together with the fixed ids from #2703:

aws cognito-idp create-user-pool --pool-name local --user-pool-tags _custom_id_=us-east-1_Local
aws cognito-idp create-user-pool-client --user-pool-id us-east-1_Local \
  --client-name _custom_id_:localclient --client-secret local_dev_client_secret_0123456789

Test plan

  • Unit (fakecloud-cognito, 430 pass): the custom secret is returned and stored as the client's secret; too short, too long, outside the pattern and with GenerateSecret: true are rejected with InvalidParameterException without the value in the message; the 24 and 64 character bounds are accepted.
  • E2E cognito_create_user_pool_client_with_custom_secret (aws-sdk-rust): create with client_secret, DescribeUserPoolClient returns it, a client_credentials grant at /oauth2/token authenticates with it, and GenerateSecret + ClientSecret and a short secret fail with InvalidParameterException.
  • cognito, cognito_persistence and cognito_authorize e2e pass; conformance run --services cognito-idp 4812/4812; cargo fmt --all --check and cargo clippy -p fakecloud-cognito -p fakecloud-e2e --all-targets -- -D warnings clean.

Summary by cubic

Lets CreateUserPoolClient take a caller-chosen ClientSecret and make it the app client's secret, so DescribeUserPoolClient, /oauth2/token client authentication, and SECRET_HASH checks all use it. Without ClientSecret, nothing changes. Closes #2750.

  • The value must be 24-64 characters matching [\w+]+; anything else fails with InvalidParameterException without echoing the value, since the member is sensitive.
  • ClientSecret together with GenerateSecret: true is rejected with InvalidParameterException, per the API reference.
  • CloudFormation and the secret-rotation operations are unchanged.