1

I am trying to give some custom attributes specific read/write access depending on the attribute. I am getting this error.

Resource handler returned message: "Invalid write attributes specified while creating a client (Service: CognitoIdentityProvider, Status Code: 400, Request ID: <request_id>)" (RequestToken: <request_token>, HandlerErrorCode: InvalidRequest)

Can anyone point me in the right direction or tell me why this is happening? Obviously, I understand what the error is telling me, but I don't know what (specifically) is causing it or how to fix it. Maybe something to do with the way I am creating the attribute to begin with...

Here is my code;

self.my_user_pool = cognito.UserPool(
    self,
    COGNITO_USER_POOL_ID,
    sign_in_aliases=cognito.SignInAliases(email=True),
    self_sign_up_enabled=True,
    auto_verify=cognito.AutoVerifiedAttrs(email=True),
    user_verification=cognito.UserVerificationConfig(
        email_style=cognito.VerificationEmailStyle.LINK
    ),
    custom_attributes={
        "custom_attribute_1": cognito.StringAttribute(mutable=True),
        "custom_attribute_2": cognito.StringAttribute(mutable=True),
    },
    password_policy=cognito.PasswordPolicy(
        min_length=8,
        require_lowercase=True,
        require_uppercase=True,
        require_digits=True,
        require_symbols=True,
    ),
    account_recovery=cognito.AccountRecovery.EMAIL_ONLY,
    removal_policy=RemovalPolicy.DESTROY,
)


client_read_attributes = (cognito.ClientAttributes()).with_custom_attributes(
    "custom:custom_attribute_1", "custom:custom_attribute_2"
)
client_write_attributes = (cognito.ClientAttributes()).with_custom_attributes(
    "custom:custom_attribute_1"
)

self.my_user_pool_client = self.user_pool.add_client(
    "<my_cognito_client_id>",
    access_token_validity=Duration.minutes(60),
    id_token_validity=Duration.minutes(60),
    refresh_token_validity=Duration.days(1),
    auth_flows=cognito.AuthFlow(admin_user_password=True, user_srp=True, custom=True),
    o_auth=cognito.OAuthSettings(flows=cognito.OAuthFlows(implicit_code_grant=True)),
    prevent_user_existence_errors=True,
    generate_secret=True,
    read_attributes=client_read_attributes,
    write_attributes=client_write_attributes,
    enable_token_revocation=True,
)
3
  • 1
    Does omitting the custom write attributes (i.e. only passing the custom read attributes) work? Commented Jul 23, 2024 at 17:47
  • 1
    Also, can you confirm that the code in the question is correct in that you are not passing the standard_attributes prop? Are you able to provide the names of your custom attributes and/or confirm that they don't conflict with the names of any standard attributes (e.g. name or email)? Commented Jul 23, 2024 at 17:53
  • @gshpychka - Thank you for the reply. I can omit the custom write attributes and it sets custom_attribute_1 and custom_attribute_2 to have both read and write access (both boxes checked). All the other attributes get set to write access only which is weird because why would you ever need only write access without read? The code above is a direct copy and paste and I am using "with_custom_attributes" and not "with_standard_attributes". My custom attributes are custom:pipeline and custom:destination. I don't think those names conflict with any of the standard attributes. Commented Jul 23, 2024 at 20:11

1 Answer 1

1

I finally figured this out, so I am answering my own question. The way you have to do it feels overly verbose and not particularly intuitive. It took me a while, so hopefully I can save someone else some time.

It is documented minimally but I assumed there would be more flexibility - ie the ability to set select attributes to read only without explicitly re-setting everything else to what is the default, on initial creation of the user pool client. I spent a lot of time playing with this, thinking it was possible and that I was just doing it wrong...

https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_cognito/ClientAttributes.html

  1. The read/write attributes are set to True by default when you add the user pool client.

  2. There is currently no way to just set some attributes as read only and ignore all the rest (i.e. - keep them as the default read/write settings)

  3. You need to explicitly specify all the attributes that need to have write access

  4. Then you need to pass the client_write_attributes into the client_read_attributes because otherwise it will set the above attribute to write only with no read access, which obviously makes no sense. Then add the attributes that you want to be read only.

  5. This will set all standard and custom attributes shown in the code below to read/write access, except for the standard attributes email_verified and phone_number_verified and the custom attributes customattribute2 and customattribute3. These will be set to read only access.

  6. To make things even a little more exciting... :-) A few of the standard attributes are named differently than they are in the console and will throw an error if you don't get them right. I have listed these below.

  • updated_at in the console is last_update_time
  • zoneinfo in the console is timezone
  • picture in the console is timezone
  • profile in console is profile_page

This is the code that worked for me

client_write_attributes = (
    cognito.ClientAttributes()
    .with_standard_attributes(
        family_name=True,
        email=True,
        address=True,
        birthdate=True,
        gender=True,
        given_name=True,
        locale=True,
        middle_name=True,
        nickname=True,
        phone_number=True,
    )
    .with_custom_attributes("customattribute1")
)

client_read_attributes = client_write_attributes.with_standard_attributes(
    email_verified=True, phone_number_verified=True
).with_custom_attributes("customattribute2", "customattribute3")

self.user_pool_client = self.user_pool.add_client(
    # ...
    # <all other settings>
    read_attributes=client_read_attributes,
    write_attributes=client_write_attributes,
)
Sign up to request clarification or add additional context in comments.

1 Comment

Consider using a code formatter for readability. I've edited the code block accordingly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.